preface
This article is only for learning notes. If there are errors and deficiencies, please correct them.
1. Sequence table
1.1 definition of sequence table
The sequence table can be seen as a structure that stores an array and the length of the array.
Sequence table definition:
typedef int ElemType; typedef struct { ElemType data[MaxSize]; //Storage order table element int length; //Length of storage sequence table } SqList;
1.2 basic usage of sequence table
The basic usage is as follows:
void CreateList(SqList *&L,ElemType a[],int n) //Create sequence table { L=(SqList *)malloc(sizeof(SqList)); for (int i=0;i<n;i++) L->data[i]=a[i]; L->length=n; } //Initialization sequence table void InitList(SqList *&L) { L=(SqList *)malloc(sizeof(SqList)); //Allocate space for linear tables L->length=0; } //Destruction sequence table void DestroyList(SqList *&L) { free(L); } //Empty sequence table bool ListEmpty(SqList *L) { return(L->length==0); } //Gets the length of the sequence table int ListLength(SqList *L) { return(L->length); } //Output sequence table void DispList(SqList *L) { for (int i=0;i<L->length;i++) printf("%d ",L->data[i]); printf("\n"); } //Gets the element of bit i of the sequence table bool GetElem(SqList *L,int i,ElemType &e) { if (i<1 || i>L->length) return false; e=L->data[i-1]; return true; } //Gets the position of the element in the sequence table int LocateElem(SqList *L, ElemType e) { int i=0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) return 0; else return i+1; } //Insert element bool ListInsert(SqList *&L,int i,ElemType e) { int j; if (i<1 || i>L->length+1) return false; i--; //Convert sequence table bit order to elem subscript for (j=L->length;j>i;j--) //Move data[i] and the following elements back one position L->data[j]=L->data[j-1]; L->data[i]=e; L->length++; //Increase the length of sequence table by 1 return true; } //Delete element bool ListDelete(SqList *&L,int i,ElemType &e) { int j; if (i<1 || i>L->length) return false; i--; //Convert sequence table bit order to elem subscript e=L->data[i]; for (j=i;j<L->length-1;j++) //Move the element after data[i] forward one position L->data[j]=L->data[j+1]; L->length--; //Sequence table length minus 1 return true; }
2. Single linked list
2.1 definition of single linked list
Define single linked list:
typedef int ElemType; typedef struct LNode { ElemType data; struct LNode *next; //Point to successor node } LinkNode;
Based on the structure of single linked list, single linked list has the following characteristics:
After accessing a node, you can only access its successor nodes, but not its predecessor nodes. (the pointer of the single linked list refers to the front, not the back)
The linked list is very much like a train. One node connects another node in one direction. The head node is like a locomotive. As the saying goes: "the train runs fast, all by the locomotive".
The benefits of using header nodes are:
Based on the above advantages, head nodes are used in single linked list, double linked list and partial circular linked list.
2.2 basic usage of single linked list
The basic usage of single linked list is as follows:
void CreateListF(LinkNode *&L,ElemType a[],int n) //Establishing single linked list by head interpolation { LinkNode *s; L=(LinkNode *)malloc(sizeof(LinkNode)); //Create header node L->next=NULL; for (int i=0;i<n;i++) { s=(LinkNode *)malloc(sizeof(LinkNode));//Create new node s s->data=a[i]; s->next=L->next; //Insert node s before the original start node and after the head node L->next=s; } } void CreateListR(LinkNode *&L,ElemType a[],int n) //Establishing single linked list by tail interpolation { LinkNode *s,*r; L=(LinkNode *)malloc(sizeof(LinkNode)); //Create header node L->next=NULL; r=L; //r always points to the terminal node and at the beginning to the head node for (int i=0;i<n;i++) { s=(LinkNode *)malloc(sizeof(LinkNode));//Create new node s s->data=a[i]; r->next=s; //Insert node s after node r r=s; } r->next=NULL; //Set the next field of the terminal node to NULL } void InitList(LinkNode *&L) { L=(LinkNode *)malloc(sizeof(LinkNode)); //Create header node L->next=NULL; } void DestroyList(LinkNode *&L) { LinkNode *pre=L,*p=pre->next; while (p!=NULL) { free(pre); pre=p; p=pre->next; } free(pre); //At this time, p is NULL,pre points to the tail node and releases it } bool ListEmpty(LinkNode *L) { return(L->next==NULL); } int ListLength(LinkNode *L) { LinkNode *p=L;int i=0; while (p->next!=NULL) { i++; p=p->next; } return(i); } void DispList(LinkNode *L) { LinkNode *p=L->next; while (p!=NULL) { printf("%d ",p->data); p=p->next; } printf("\n"); } bool GetElem(LinkNode *L,int i,ElemType &e) { int j=0; LinkNode *p=L; if (i<=0) return false; //i error return false while (j<i && p!=NULL) { j++; p=p->next; } if (p==NULL) //The ith data node does not exist return false; else //The ith data node exists { e=p->data; return true; } } int LocateElem(LinkNode *L,ElemType e) { LinkNode *p=L->next; int n=1; while (p!=NULL && p->data!=e) { p=p->next; n++; } if (p==NULL) return(0); else return(n); } bool ListInsert(LinkNode *&L,int i,ElemType e) { int j=0; LinkNode *p=L,*s; if (i<=0) return false; //i error return false while (j<i-1 && p!=NULL) //Find the i-1 node p { j++; p=p->next; } if (p==NULL) //No node with bit order i-1 was found return false; else //Find the node * p with bit order i-1 { s=(LinkNode *)malloc(sizeof(LinkNode));//Create new node * s s->data=e; s->next=p->next; //Insert node s after node p p->next=s; return true; } } bool ListDelete(LinkNode *&L,int i,ElemType &e) { int j=0; LinkNode *p=L,*q; if (i<=0) return false; //i error return false while (j<i-1 && p!=NULL) //Find the i-1 node { j++; p=p->next; } if (p==NULL) //No node with bit order i-1 was found return false; else //Find the node p with bit order i-1 { q=p->next; //q points to the node to be deleted if (q==NULL) return false; //If the ith node does not exist, false is returned e=q->data; p->next=q->next; //Delete q node from single linked list free(q); //Release q node return true; } }
3. Double linked list
3.1 definition of double linked list
typedef int ElemType; typedef struct DNode //Define double linked list node type { ElemType data; struct DNode *prior; //Point to precursor node struct DNode *next; //Point to successor node } DLinkNode;
Based on the definition of double linked list, double linked list has the following characteristics:
Starting from any node, we can quickly find its predecessor node and successor node. From any node, you can access other nodes.
(I think it's more convenient than a single linked list)
3.2 basic use of double linked list
void CreateListF(DLinkNode *&L,ElemType a[],int n) //Building double linked list by head inserting method { DLinkNode *s; L=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create header node L->prior=L->next=NULL; for (int i=0;i<n;i++) { s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node s->data=a[i]; s->next=L->next; //Insert node s before the original start node and after the head node if (L->next!=NULL) L->next->prior=s; L->next=s;s->prior=L; } } void CreateListR(DLinkNode *&L,ElemType a[],int n) //Constructing double linked list by tail interpolation { DLinkNode *s,*r; L=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create header node L->prior=L->next=NULL; r=L; //r always points to the terminal node and at the beginning to the head node for (int i=0;i<n;i++) { s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node s->data=a[i]; r->next=s;s->prior=r; //Insert node s after node r r=s; } r->next=NULL; //Set the next field of the tail node to NULL } void InitList(DLinkNode *&L) { L=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create header node L->prior=L->next=NULL; } void DestroyList(DLinkNode *&L) { DLinkNode *pre=L,*p=pre->next; while (p!=NULL) { free(pre); pre=p; p=pre->next; } free(pre); } bool ListEmpty(DLinkNode *L) { return(L->next==NULL); } int ListLength(DLinkNode *L) { DLinkNode *p=L; int i=0; while (p->next!=NULL) { i++; p=p->next; } return(i); } void DispList(DLinkNode *L) { DLinkNode *p=L->next; while (p!=NULL) { printf("%d ",p->data); p=p->next; } printf("\n"); } bool GetElem(DLinkNode *L,int i,ElemType &e) { int j=0; DLinkNode *p=L; if (i<=0) return false; //i error return false while (j<i && p!=NULL) { j++; p=p->next; } if (p==NULL) return false; else { e=p->data; return true; } } int LocateElem(DLinkNode *L,ElemType e) { int n=1; DLinkNode *p=L->next; while (p!=NULL && p->data!=e) { n++; p=p->next; } if (p==NULL) return(0); else return(n); } bool ListInsert(DLinkNode *&L,int i,ElemType e) { int j=0; DLinkNode *p=L,*s; if (i<=0) return false; //i error return false while (j<i-1 && p!=NULL) { j++; p=p->next; } if (p==NULL) //Node i-1 not found return false; else //Find the i-1 node p { s=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create new node s s->data=e; s->next=p->next; //Insert node s after node p if (p->next!=NULL) p->next->prior=s; s->prior=p; p->next=s; return true; } } bool ListDelete(DLinkNode *&L,int i,ElemType &e) { int j=0; DLinkNode *p=L,*q; if (i<=0) return false; //i error return false while (j<i-1 && p!=NULL) { j++; p=p->next; } if (p==NULL) //Node i-1 not found return false; else //Find the i-1 node p { q=p->next; //q points to the node to be deleted if (q==NULL) return false; //The ith node does not exist e=q->data; p->next=q->next; //Delete * q node from single linked list if (p->next!=NULL) p->next->prior=p; free(q); //Release q node return true; } }
4. Cycle table
4.1 introduction to cycle table
Because the circular list is based on single linked list and double linked list, there are two kinds of circular linked list: circular single linked list and circular double linked list.
Circular single chain indicates intention;
Circular double chain indicates the intention:
4.2 basic use of circular single linked list
void CreateListF(LinkNode *&L,ElemType a[],int n) //Establishment of circular single linked list by head interpolation { LinkNode *s;int i; L=(LinkNode *)malloc(sizeof(LinkNode)); //Create header node L->next=NULL; for (i=0;i<n;i++) { s=(LinkNode *)malloc(sizeof(LinkNode));//Create a new node s->data=a[i]; s->next=L->next; //Insert node s before the original start node and after the head node L->next=s; } s=L->next; while (s->next!=NULL) //Find the tail node and point to it by s s=s->next; s->next=L; //The tail node next field points to the head node } void CreateListR(LinkNode *&L,ElemType a[],int n) //Establishment of circular single chain table by tail interpolation { LinkNode *s,*r;int i; L=(LinkNode *)malloc(sizeof(LinkNode)); //Create header node L->next=NULL; r=L; //r always points to the terminal node and at the beginning to the head node for (i=0;i<n;i++) { s=(LinkNode *)malloc(sizeof(LinkNode));//Create a new node s->data=a[i]; r->next=s; //Insert node s after node r r=s; } r->next=L; //The tail node next field points to the head node } void InitList(LinkNode *&L) { L=(LinkNode *)malloc(sizeof(LinkNode)); //Create header node L->next=L; } void DestroyList(LinkNode *&L) { LinkNode *p=L,*q=p->next; while (q!=L) { free(p); p=q; q=p->next; } free(p); } bool ListEmpty(LinkNode *L) { return(L->next==L); } int ListLength(LinkNode *L) { LinkNode *p=L;int i=0; while (p->next!=L) { i++; p=p->next; } return(i); } void DispList(LinkNode *L) { LinkNode *p=L->next; while (p!=L) { printf("%d ",p->data); p=p->next; } printf("\n"); } bool GetElem(LinkNode *L,int i,ElemType &e) { int j=0; LinkNode *p; if (L->next!=L) //When the single linked table is not empty { if (i==1) { e=L->next->data; return true; } else //When i is not 1 { p=L->next; while (j<i-1 && p!=L) { j++; p=p->next; } if (p==L) return false; else { e=p->data; return true; } } } else //When the single linked table is empty return false; } int LocateElem(LinkNode *L,ElemType e) { LinkNode *p=L->next; int n=1; while (p!=L && p->data!=e) { p=p->next; n++; } if (p==L) return(0); else return(n); } bool ListInsert(LinkNode *&L,int i,ElemType e) { int j=0; LinkNode *p=L,*s; if (p->next==L || i==1) //When the original single linked list is empty or i==1 { s=(LinkNode *)malloc(sizeof(LinkNode)); //Create new node s s->data=e; s->next=p->next; //Insert node s after node p p->next=s; return true; } else { p=L->next; while (j<i-2 && p!=L) { j++; p=p->next; } if (p==L) //Node i-1 not found return false; else //Find the i-1 node p { s=(LinkNode *)malloc(sizeof(LinkNode)); //Create new node s s->data=e; s->next=p->next; //Insert node s after node p p->next=s; return true; } } } bool ListDelete(LinkNode *&L,int i,ElemType &e) { int j=0; LinkNode *p=L,*q; if (p->next!=L) //When the original single linked list is not empty { if (i==1) //When i==1 { q=L->next; //Delete the first node e=q->data; L->next=q->next; free(q); return true; } else //When i is not 1 { p=L->next; while (j<i-2 && p!=L) { j++; p=p->next; } if (p==L) //Node i-1 not found return false; else //Find the i-1 node p { q=p->next; //q points to the node to be deleted e=q->data; p->next=q->next; //Delete q node from single linked list free(q); //Release q node return true; } } } else return false; }
4.3 basic use of circular double linked list
void CreateListF(DLinkNode *&L,ElemType a[],int n) //Establishing circular double linked list by head interpolation { DLinkNode *s;int i; L=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create header node L->next=NULL; for (i=0;i<n;i++) { s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node s->data=a[i]; s->next=L->next; //Insert node s before the original start node and after the head node if (L->next!=NULL) L->next->prior=s; L->next=s;s->prior=L; } s=L->next; while (s->next!=NULL) //Find the tail node and point to it by s s=s->next; s->next=L; //The tail node next field points to the head node L->prior=s; //The head node's prior field points to the tail node } void CreateListR(DLinkNode *&L,ElemType a[],int n) //Establishment of circular double linked list by tail interpolation { DLinkNode *s,*r;int i; L=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create header node L->next=NULL; r=L; //r always points to the tail node and at the beginning to the head node for (i=0;i<n;i++) { s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node s->data=a[i]; r->next=s;s->prior=r; //Insert node s after node r r=s; } r->next=L; //The tail node next field points to the head node L->prior=r; //The head node's prior field points to the tail node } void InitList(DLinkNode *&L) { L=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create header node L->prior=L->next=L; } void DestroyList(DLinkNode *&L) { DLinkNode *p=L,*q=p->next; while (q!=L) { free(p); p=q; q=p->next; } free(p); } bool ListEmpty(DLinkNode *L) { return(L->next==L); } int ListLength(DLinkNode *L) { DLinkNode *p=L; int i=0; while (p->next!=L) { i++; p=p->next; } return(i); } void DispList(DLinkNode *L) { DLinkNode *p=L->next; while (p!=L) { printf("%d ",p->data); p=p->next; } printf("\n"); } bool GetElem(DLinkNode *L,int i,ElemType &e) { int j=0; DLinkNode *p; if (L->next!=L) //When the double linked list is not empty { if (i==1) { e=L->next->data; return true; } else //When i is not 1 { p=L->next; while (j<i-1 && p!=L) { j++; p=p->next; } if (p==L) return false; else { e=p->data; return true; } } } else //When the double linked list is empty return 0; } int LocateElem(DLinkNode *L,ElemType e) { int n=1; DLinkNode *p=L->next; while (p!=NULL && p->data!=e) { n++; p=p->next; } if (p==NULL) return(0); else return(n); } bool ListInsert(DLinkNode *&L,int i,ElemType e) { int j=0; DLinkNode *p=L,*s; if (p->next==L) //When the original double linked list is empty { s=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create new node s s->data=e; p->next=s;s->next=p; p->prior=s;s->prior=p; return true; } else if (i==1) //When the original double linked list is not empty but i=1 { s=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create new node s s->data=e; s->next=p->next;p->next=s; //Insert node s after node p s->next->prior=s;s->prior=p; return true; } else { p=L->next; while (j<i-2 && p!=L) { j++; p=p->next; } if (p==L) //Node i-1 not found return false; else //Find node i-1 * p { s=(DLinkNode *)malloc(sizeof(DLinkNode)); //Create new node s s->data=e; s->next=p->next; //Insert node s after node p if (p->next!=NULL) p->next->prior=s; s->prior=p; p->next=s; return true; } } } bool ListDelete(DLinkNode *&L,int i,ElemType &e) { int j=0; DLinkNode *p=L,*q; if (p->next!=L) //When the original double linked list is not empty { if (i==1) //When i==1 { q=L->next; //Delete the first node e=q->data; L->next=q->next; q->next->prior=L; free(q); return true; } else //When i is not 1 { p=L->next; while (j<i-2 && p!=NULL) { j++; p=p->next; } if (p==NULL) //Node i-1 not found return false; else //Find the i-1 node p { q=p->next; //q points to the node to be deleted if (q==NULL) return 0; //The ith node does not exist e=q->data; p->next=q->next; //Delete q node from single linked list if (p->next!=NULL) p->next->prior=p; free(q); //Release q node return true; } } } else return false; //When the original double linked list is empty }