400 likes | 509 Views
Chapter 5 – Linked Lists. 1. Main Index. Contents. Abstract Model of a List Obj. Node Composition Inserting at the Front of a LL Deleting from the Front of a LL Removing a Target Node. Circular Doubly LL’s (2 slides) Updating a Doubly LL. Abstract Model of a List Object. 3.
E N D
Chapter 5 – Linked Lists 1 Main Index Contents • Abstract Model of a List Obj. • Node Composition • Inserting at the Front of a LL • Deleting from the Front of a LL • Removing a Target Node • Circular Doubly LL’s (2 slides) • Updating a Doubly LL
3 Main Index Contents Linked List Nodes • Removal is like Insertion in reverse.
4 Main Index Contents Node Composition • An individual Node is composed of two parts, a Data field containing the data stored by the node, and a Pointer field that marks the address of the next Node in the list.
5 Main Index Contents 节点声明模板类 Template <typename T> class node { public: T data_field; // data held by the node node<T> *link_field; // next node in the list node() : link_field(NULL) {} node(const T& item, node<T> *nextNode = NULL) : data_field(item),link_field(nextNode) {} …… };
6 Main Index Contents 节点声明模板类 Template <typename T> class node { public: node( const T& init_data = T( ), node<T>* init_link = NULL) { data_field = init_data; link_field = init_link; } void set_data(const T& new_data) { data_field = new_data; } void set_link(node* new_link) { link_field = new_link; } T data( ) const { return data_field; } const node* link( ) const { return link_field; } node* link( ) { return link_field; } private: T data_field; node<T>* link_field; };
7 Main Index Contents Inserting at the Front of a Linked List
8 Main Index Contents 创建链表方法1(Inserting a node at back with a back pointer) Node<T> *head_ptr, *tail_ptr, *newNode; newNode=new node<T>(item); if(head_ptr!=Null) tail_ptr -> link_field=newNode; else head_ptr=newNode; tail_ptr=newNode;
9 Main Index Contents 创建链表方法2(Inserting a node at front with a back pointer) node<T> head_ptr*, *tail_ptr, *newNode; newNode=new node<T>(item, head_ptr); if(head_ptr==Null) tail_ptr=newNode; head_ptr=newNode;
10 Main Index Contents Creating a Linked List(创建链表1) Node<T> *head_ptr, *tail_ptr, *newNode; //创建第一个节点 newNode=new node<T>(item); if(head_ptr!=Null) tail_ptr -> link_field=newNode; else head_ptr=newNode; tail_ptr=newNode; //创建其余节点 for(i=2;i<=5;i++) { cin>>itme; newNode=new node<int>(item,head_ptr); head_ptr=newNode; } Inserting a new node at the back of list. (通过在表尾追加节点->建立链表)
11 Main Index Contents Creating a Linked List(创建链表2) node<int> *head_ptr=Null, *newNode; int i; for(i=1;i<=5;i++) { cin>>item; newNode=new node<int>(itme,head_ptr); head_ptr=newNode; } Inserting a new node at the front of list. (通过在表头插入节点->建立链表)
12 Main Index Contents 遍历链表 node<T> *p; p=head_ptr; while(p!=Null) { cout<<p->data_field; p=p->link_field; //private data } 或者: For(p=head_ptr;p!=Null;p=p->link_ptr) { cout<<p->data_field; }
13 Main Index Contents 计算链表长度 node<T> *p; p=head_ptr; int k=0; while(p!=Null) { cout<<p->data_field; p=p->link_field; //private data i++; } cout<<i;
14 Main Index Contents 基本插入和删除节点方法 Insert: newNode->link_field = curr; Prev->link_field=newNode; Delete: node<T> *curr, *prev; prev->link_field=curr->field; delete curr;
15 Main Index Contents 插入节点方法 在链表头插入: head_ptr = new node(entry, head_ptr); 在非表头插入: void list_insert(node<T>* previous_ptr, const T& entry) { node<T> *insert_ptr; insert_ptr = new node(entry, previous_ptr->link_field);//private data previous_ptr->link_field(insert_ptr);//private } 思考:在表尾插入
16 Main Index Contents 查找节点方法 node *cursor; for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( )) { if (target == cursor->data( )) return cursor; }
front // front = NULL Deleting front of a 1-node list front // front = front->next Deleting front of a multi-node list 17 Main Index Contents Deleting From the Front of a Linked List
18 Main Index Contents Deleting a Linked List node<T> *p; while(head_ptr!=Null) { p=head_ptr; head_ptr=head_ptr->next; delete p; }
19 Main Index Contents Removing a Target Node(删除指定节点)
20 Main Index Contents Removing a Target Node Template<Typename T> Void eraseValue(node<T> *front, const T& target) { node<T> *curr=front, *prev=Null; bool foundItem=false; while(curr!=Null && !foundItem){ if(curr->nodeValue==target) { if(prev=Null) front=front->next; else prev->next=curr->next; delete curr; foundItem=true; } else{ prev=curr; curr=curr->next; } } }
21 Main Index Contents 用链表实现包 1.模板包 2.构造函数 3.erase_one 4.count
22 Main Index Contents 节点统计count 两种实现方法: 1.逐个搜索,边遍历边统计; 2.用list_search方法实现,每找到一个目标节点,就从这里开始重新search,直到结束; erase_one 两种实现方法: 1.边搜索,边删除,用链表表头元素替代被删除元素; 2.用list_remove方法实现,但需先找到前驱节点指针;
23 Main Index Contents Prg 9-1: Erasing nodes in descending order #include <iostream> #include "d_node.h" #include "d_nodel.h" #include "d_random.h" using namespace std; template <typename T> node<T> *getMax(node<T> *front); template <typename T> void eraseValue(node<T> * & front, const T& target);
24 Main Index Contents Prg 9-1: Erasing nodes in descending order int main() { node<int> *front = NULL, *p; randomNumber rnd; int listCount, i; cout << "Enter the size of the list: "; cin >> listCount; for (i = 0; i < listCount; i++) front = new node<int> (rnd.random(100), front); cout << "Original List of Values: "; writeLinkedList(front, " "); cout << endl;
25 Main Index Contents Prg 9-1: Erasing nodes in descending order cout << "Output in Descending Order: "; while (front != NULL) { p = getMax(front); cout << p->nodeValue << " "; eraseValue(front, p->nodeValue); } cout << endl; return 0; }
26 Main Index Contents Prg 9-1: Erasing nodes in descending order template <typename T> node<T> *getMax(node<T> *front) { node<T> *curr = front, *maxPtr = front; while (curr != NULL) { if (maxPtr->nodeValue < curr->nodeValue) maxPtr = curr; curr = curr->next; } return maxPtr; }
27 Main Index Contents 6. Doubly Linked List Value
28 Main Index Contents d_dnode.h Template<Typename T> Class dnode { public: T nodeValue; dnode<T> *prev; dnode<T> *next; dnode(); dnode(const T& value): nodeValue(value); };
29 Main Index Contents Inserting a Node at a Position Inserting a Node before curr Position
30 Main Index Contents Inserting a Node at a Position Dnode<T> *newNode, *prevNode;newNode=new dnode<T>(item);prevNode=curr->prev;newNode->prev=prevNode;newNode->next=curr;prevNode->next=newNode;Curr->prev=newNode;
31 Main Index Contents Deleting a Node at a Position
32 Main Index Contents Deleting a Node at a Position Dnode<T>*prevNode=curr->prev, *succNode=curr->next; prevNode->next=succNode; succNode->prev=prevNode; Delete curr;
33 Main Index Contents 7. Circular Doubly Linked Lists • A Watch Band provides a good Real Life analogue for this Data Structure
34 Main Index Contents Circular Doubly Linked Lists • Implemented on a Computer it might look something like this.
Updating a Doubly Linked List Dnode<T> *header=new dnode<T>; Header->prev=header; header->next=header; //default constructor template <typename T> class dnode { public: Dnode() { next=this; prev=this; } …}
writeDLinkedList Template<Typename T> Void writeDLinkedList(dnode<T> *header, const string &separator=“ “) { Dnode<T> *p=header->next; While(P!=header) { cout<<p->nodeValue<<separator; p=p->next; } }
Inserting a node to DLinkedList Template<Typename T> Dnode<T> *insert(dnode<T> *curr, const T& item) { dnode<T> *newNode, *prevNode; newNode=new dnode<T>(item); prevNode=curr->prev; newNode->prev=prevNode; newNode->next=curr; prevNode->next=newNode; curr->prev=newNode; return newNode; }
Deleting a node to DLinkedList Template<Typename T> void *erase(dnode<T> *curr) { if(curr->next==curr)return; dnode<T> *prevNode=curr->prev, *succNode=curr->next; prevNode->next=succNode; succNode->prev=prevNode; delete curr; }
Inserting and Deleting a node at the front and back of DLinkedList API implementation ----------------------------------------------------------------- Push_front(item) insert(header->next, item) //insert in inverse way Pop_front() erase(header->next) Front() header->next->nodeValue Push_back(item) insert(header,item) //attach at the end in order Pop_back() erase(header->prev) Back() header->prev->nodeValue