1.09k likes | 1.1k Views
Discover the concept of linked lists, their implementation, common errors, and benefits over arrays in this software college guide. Learn examples, cursor implementation, and types of linked lists like doubly and circularly linked lists. Find out how linked lists overcome limitations of variable-length arrays in memory storage and insertion/removal operations. Explore the structure of linked lists, memory storage, and practical techniques to insert new nodes efficiently.
E N D
Chapter 3 Linked Lists Software College Northeastern University
Overview • Linked Lists • Programming details • Common Error • Doubly Linked Lists • Circularly Linked Lists • examples • Cursors Implementation of Linked Lists Software College Northeastern University
Variable-length arrays? • Direct access to element (By indexing) • Array size is fixed-length -To expand them, you create a new, longer array, and copy the contents of the old array into the new array • This is used by function realloc() in C • This is slow! • Linear time Insertion/Removal due to shift elements • due to contiguous storage in memory • Half of the list needs to be moved for either operations Software College Northeastern University
Variable-length arrays? • Solution: -The list is not need to store contiguously. -Attach a pointer to each item in the array, which points to the next item. -provides the ability to add or remove the items anywhere in the list in constant time • This is a linked list • Linked lists are unbounded (maximum number of items limited only by memory) Software College Northeastern University
[0] [1] [2] array Array A B C node Linked list Head A B C The Linked List data structure • An data item plus its pointer is called a node • A node contains data item and one or more links. - The link is a reference to a node. • - The link of last node is set to NULL • a “head” which is a pointer to the first node in the linked list Software College Northeastern University
H Address Data Item Links LI ZHAO SUN QIAN 1 LI 7 QIAN 13 WANG ZHOU ZHENG WU ^ SUN 19 H WANG 25 31 WU 31 ZHAO 37 ZHENG 43 ZHOU A simple single Linked List 43 Header 13 1 NULL 37 7 19 25 Software College Northeastern University
Memory Storage of linked list Heap We can access all nodes through pointer “head” Software College Northeastern University
Linked lists • Each node contains the address of the next one in the list. • We can access the first node through pointer “head” • two important pointer: - head: the reference to the first node - tail: the reference to the last node Software College Northeastern University
How to implementate? ? Software College Northeastern University
Definition of the class • Using multi class • Class of Node(ListNode) • Class of List • Class of Iterator • Type of Definition • compound • inside Software College Northeastern University
List is a Friend class class List; classListNode { friend class List; private: intdata; ListNode *link; }; class List{ public: ……… private: ListNode *first, *last; }; Software College Northeastern University
class List{ public: ……… private: classListNode{ public: int data; ListNode *link; }; ListNode *first, *last; }; ListNode is a class inside List Software College Northeastern University
Linked List:Inserting a new node(1) • int List::Insert ( constintx, const int i ) • Insert a node with data equal to x after the i-1’th element. (i.e., when i = 1, insert the node as the first element; when index = 2, insert the node after the first element, and so on) • If the insertion is successful, return 1. Otherwise, return 0. (If index is < 1 or > length+1 of the list, the insertion will fail.) • Steps • Locate i-1’th element • Allocate memory for the new node • Point the new node to its successor • Point the new node’s predecessor to the new node i’th element newNode Software College Northeastern University
Linked List:Inserting a new node(2) • Insert position • Case 1:insert in front of the first node newnode→link = first ; first = newnode; newnode newnode first first (Before) (After) Software College Northeastern University
Linked List:Inserting a new node(3) • Case 2:insert in the middle of the list newnode→link = p→link; p→link = newnode; newnode newnode p p (Before) (After) Software College Northeastern University
Linked List:Inserting a new node(4) • Case 3:Insert in the rear newnode→link = p→link; p→link = last = newnode; newnode newnode p p last last (Before) (After) Software College Northeastern University
Linked List:Inserting a new node(5) From 0 int List::Insert ( constintx, const int i ) { // Insert a node with data equal to x after the i-1’th ListNode*p = first; int k = 0; while ( p != NULL && k <i -1 ) { p = p→link; k++;}// Locate i-1’th element if ( i<0 || p == NULL&&first != NULL ) { cout << “无效的插入位置!\n”; return 0; } ListNode *newnode=newListNode(x, NULL); // Allocate memory for the new node Software College Northeastern University
Linked List:Inserting a new node(6) if ( first == NULL || i == 0 ) { //Insert in the front of list newnode→link = first; if ( first == NULL ) last = newnode; first = newnode; } else { //else newnode→link = p→link; if ( p→link == NULL ) last = newnode; p→link = newnode; } return 1; } Software College Northeastern University
Linked List:Inserting a new node when we insert a new node: (1)insert before the i’th element, which pointer should we get first? (2)illegal inserting position is ? How can we judge inserting position is illegal? (3)We should change two links when inserting , Is there an order? ? Software College Northeastern University
Linked List:Deleting a new node(1) Case 1: delete the first Case 2: delete the other node According the pointer to i’th element ,Can we accomplish the operation? Delete the i’th element Software College Northeastern University
Linked List:Deleting a new node(2) intList::Remove ( inti ) { //Delete the i’th element Node*p = first, *q; int k = 0; while ( p != NULL && k<i-1 ) { p = p→link; k++; }//locate the i-1’th element if (i<0 || p == NULL||p→link == NULL ) { cout << “无效的删除位置!\n”; return 0; } if ( i == 0 ) {//delete the first q = first;//q point the deleted node p = first = first→link;//Update first } Software College Northeastern University
Linked List:Deleting a new node(3) else { q = p→link; p→link = q→link; } if ( q == last ) last = p;//if necessary update last k = q→data; delete q;//free the node pointed by q return k; } Software College Northeastern University
Linked List with header • A node linking to the first node is called Header, the header cell only contains references to the first. a1 an first first 0 0 last last Non-empty list empty list Software College Northeastern University
Inserting in a linked list with header newnode→link = p→link; if ( p→link == NULL ) last = newnode; p→link = newnode; Software College Northeastern University
Deleting in a linked list with header q = p→link; p→link = q→link; delete q; if ( p→link == NULL ) last = p; Software College Northeastern University
Template of linked list(1) template <class Type> classList; template <class Type> classListNode{ friend class List<Type>; Type data; //结点数据 ListNode<Type>*link; //结点链接指针 public: ListNode ( ); //链表结点构造函数 ListNode ( const Type& item ); ListNode<Type>*NextNode ( ) { return link;} //给出当前结点的下一结点地址 Software College Northeastern University
Template of linked list(2) void InsertAfter ( ListNode<Type> *p ); //在当前结点后插入结点p ListNode<Type> *RemoveAfter ( ); //摘下当前结点的下一结点 }; template <class Type> class List { ListNode<Type> *first, *last; public: ListNode<Type> *GetNode ( const Type& item, ListNode<Type> *next ); //创建数据为item,指针为next的新结点 Software College Northeastern University
Template of linked list(3) List ( const Type & value ) { last =first = new ListNode<Type>( value ); } //构造函数 ~List ( );//析构函数 void MakeEmpty ( ); //链表置空 int Length ( ) const; //求链表长度 ListNode<Type> *Find ( Type value ); ListNode<Type> *Find ( int i ); int Insert ( Type value,int i ); Type *Remove ( int i ); Type *Get ( int i ); }; Software College Northeastern University
Implementation of linked list(1) template <class Type> ListNode<Type> :: ListNode ( ):link (NULL){ } template <class Type> ListNode<Type>:: ListNode( const Type& item ): data (item), link (NULL){ } template <class Type> void ListNode<Type>:: InsertAfter ( ListNode<Type>*p ) { p→link = link; link = p; } Software College Northeastern University
Implementation of linked list(2) template <class Type> ListNode<Type> *ListNode<Type>::RemoveAfter ( ) { //摘下当前结点的下一结点 ListNode<Type> *tempptr = link; if ( link == NULL ) return NULL; //没有下一结点则返回空指针 link = tempptr→link; //重新链接 return tempptr; //返回下一结点地址 } Software College Northeastern University
Implementation of linked list(3) template <class Type> ListNode<Type>*List<Type>::GetNode ( const Type & item, ListNode<Type> *next = NULL ) { ListNode<Type> *newnode = new ListNode<Type> ( item ); newnode →link = next; return newnode; } template <class Type> List<Type> :: ~List ( ){ //析构函数 (链表的公共操作) MakeEmpty ( ); delete first; //链表置空,再删去表头结点 } Software College Northeastern University
Implementation of linked list(4) template <class Type> void List<Type> :: MakeEmpty ( ) { //删去链表中除表头结点外的所有其他结点 ListNode<Type>*q; while ( first→link != NULL ) { q = first→link;first→link = q→link; //将表头结点后第一个结点从链中摘下 delete q; //释放它 } last = first; //修改表尾指针 } Software College Northeastern University
Implementation of linked list(5) template <class Type> int List<Type>::Length ( ) const { //求单链表的长度 ListNode<Type> *p = first→link; //检测指针p指示第一个结点 int count = 0; while ( p != NULL ) { //逐个结点检测 p = p→link; count++; } return count; } Software College Northeastern University
Implementation of linked list(6) template <class Type> ListNode<Type>*List <Type>:: Find ( Type value ) { //在链表中从头搜索其数据值为value的结点 ListNode<Type> *p = first→link; //检测指针 p 指示第一个结点 while ( p != NULL && p→data != value ) p = p→link; return p; // p 在搜索成功时返回找到的结点地址 // p 在搜索不成功时返回空值 } Software College Northeastern University
Implementation of linked list(7) template <class Type> ListNode<Type>*List<Type> :: Find ( inti ) { //在链表中从头搜索第 i 个结点,不计头结点 if ( i < -1)returnNULL; if ( i == -1 ) returnfirst; // i 应 0 ListNode<Type>*p = first→link; intj = 0; while ( p != NULL && j < i ) // j = i停 { p = p→link; j++; } return p; } Software College Northeastern University
Implementation of linked list(7) template <class Type> int List<Type> :: Insert ( Typevalue,int i ) { //将含value的新元素插入到链表第 i 个位置 ListNode<Type>*p = Find ( i-1 ); // p指向链表第 i-1个结点 if ( p == NULL )return 0; ListNode<Type>*newnode = //创建结点 GetNode ( value, p→link ); if ( p→link == NULL ) last = newnode; p→link = newnode; //重新链接 return 1; } Software College Northeastern University
Implementation of linked list(8) template <class Type> Type *List<Type>::Remove ( inti ) { //从链表中删去第 i个结点 ListNode<Type> *p = Find (i-1), *q; if ( p == NULL || p→link== NULL ) returnNULL; q = p→link; p→link = q→link; //重新链接 Typevalue = new Type ( q→data ); if ( q == last ) last = p; delete q; return&value; } Software College Northeastern University
Implementation of linked list(8) template <class Type> Type*List<Type>::Get ( inti ) { //提取第 i个结点的数据 ListNode<Type>*p = Find ( i ); // p指向链表第 i个结点 if ( p == NULL||p == first ) return NULL; else return&p→data; } Software College Northeastern University
Array versus Linked Lists • Linked lists are more complex to code and management than arrays, but they have some distinct advantages. • Dynamic: a linked list can easily grow and shrink in size. -We don’t need to know how many nodes will be in the list. They are created in memory as needed. -In contrast, the size of a C array is fixed at compilation time. • Easy and fast insertions and deletions -To insert or delete an element in an array, we need to copy to temporary variables to make room for new elements or close the gap caused by deleted elements. -With a linked list, no need to move other nodes. Only need to reset some pointers. Software College Northeastern University
Arrays versus linked lists • Space (storage) considerations • A linked list requires pointers to nodes • An array requires the maximum number of elements to be known in advance. If that maximum is not required, space is wasted at the end of the array. Software College Northeastern University
Arrays versus linked lists • Time considerations • Most methods in a linked list require more statements than those in an array, which may indicate more time required • Arrays are quicker at finding and altering ‘in the middle’ • Linked lists are quicker at additions and removals ‘in the middle’ Software College Northeastern University
Iterator class of list • Iterator class of list is used to traverse nodes of list. • priciple: • Iteratorclass is friend of List and ListNode • Iterator refer to the nodes of list。 • Data member current point to the node currently used • Iterator privides some test and find operation Software College Northeastern University
Template definition(1) enum Boolean{ False, True }; template <class Type> classList; template <class Type> class ListIterator; template <class Type> classListNode{ //表结点 friend classList <Type>; friend classListIterator <Type>; public: ……… private: Type data; ListNode<Type>*link; }; Software College Northeastern University
Template definition(2) template <class Type> class List{ //链表类 public: ……… private: ListNode<Type>*first, *last; }; template <class Type> classListIterator { public: ListIterator ( constList<Type>& l ) :list ( l ), current ( l.first->link ){ } //构造函数: 引用链表 l, 表头为当前结点 private: list<Type> list; ListNode<Type> * current; } Software College Northeastern University
Template definition(3) template <class Type> Boolean ListIterator<Type> :: NotNull ( ) { //检查链表中当前元素是否非空 if ( current != NULL ) returnTrue; else returnFalse; } current current case 1 return Truecase 2 return False Software College Northeastern University
Template definition(4) template <class Type> Boolean ListIterator<Type>::NextNotNull ( ) { //检查链表中下一元素是否非空 if ( current != NULL && current→link != NULL )returnTrue; else return False; } current current case 1 return Truecase 2 return False Software College Northeastern University
Template definition(5) template <class Type> ListNode<Type>* ListIterator<Type> :: Firster ( ) { //返回链表中头结点的地址 current = list.first; return current; } list.first list with header current Software College Northeastern University
Template definition(5) template <class Type> Type * ListIterator<Type> :: First ( ) { //返回链表中第一个元素的地址 if ( list.first→link != NULL ){ current = list.first->link; return ¤t→data; } else { current = NULL; returnNULL; } } list.first list with header current Software College Northeastern University
Template definition(6) template <class Type> Type* ListIterator<Type> :: Next ( ) { //返回链表中当前结点的下一个结点的地址 if ( current != NULL && current→link != NULL ) { current = current→link; return & current→data; } else { current = NULL; return NULL; } } current current Software College Northeastern University
Calculating using iterator intsum ( constList<int>&l ) { ListIterator<int>li ( l ); //链表为空时返回0 int*p= li.First( ); retval = 0//指向第一个结点 while ( p != null ){ //链表未扫描完 retval += *p; //累加 p= li.Next( ); } returnretval; } Software College Northeastern University