Here, we implement the basic operation of circular list. We use single chain list to convert it into circular list:
1. Convert single chain table to circular chain table
ChangeLinkListToCkList(LinkList head) //Here, just point the last tail pointer to the head node { LinkList p,p2=head,p1=head; while(p2){ //The last p is the pointer of the link list to the end node p=p2; p2=p2->next; } while(p!=head) //The last head is the pointer to the penultimate tail node { head=head->next; } head->next=p1; //Point tail node to head node }
2. Add data to the circular list
void AddElemIntoCKList(LinkList head,int index,User user) { LinkList p=(LinkList)malloc(sizeof(LNode)); p->user=user; int i=0; for(;i<index-1;i++) //Here, the previous node of the target location is returned { head=head->next; } p->next=head->next; //Point the target node to the node at the current target location head->next=p; //Point the previous node of the target location to the target node, and then the target node completes the insertion operation }
3. Delete a node in a position of the circular list
void DeletElemFromCKList(LinkList head,int index) { int i=0; for(;i<index-1;i++) //Here, the previous node of the target location is returned { head=head->next; } LinkList p=head->next; head->next=head->next->next; free(p); }
4. Merge two circular lists into one
void ContactCKList(LinkList tails_0,LinkList tails_1) //Here, tails 0 and tails 1 are tail pointers of two linked lists respectively { LinkList p=tails_1->next->next; //1. Find the first element node of the second circular list tails_1->next=tails_0->next; //2. The tail node of the second list points to the head node of the first list tails_0->next=p; //3. The tail node of the first linked list points to the first element node of the second linked list }
Difficulty: merge two circular lists into one
Initial state:
Step one:
The second step:
The third step:
Then beautify it:
At this point, the combination of two circular lists into a circular list is completed.
Finally, a complete source code is attached:
#include<bits/stdc++.h> using namespace std; typedef struct { char username[20]; int id; }User; typedef struct LNode { User user; struct LNode *next; }LNode,*LinkList; //Create a single chain table LinkList CreateLinkList(LinkList L) { L=(LinkList)malloc(sizeof(LNode)); L->next=NULL; return L; } //Insert 5 data by back interpolation void InsertElem_Back(LinkList head) { int i=0; LinkList r=head; //Every time data is added, r points to the tail node for(;i<5;i++) { User user; user.id=i; strcpy(user.username,"gjw"); LinkList p=(LinkList)malloc(sizeof(LNode)); p->user=user; p->next=NULL; r->next=p; r=p; } } //Test output list void TestList(LinkList head) { while(head->next) { User user=head->next->user; cout<<user.username<<endl; head=head->next; } } //Convert single linked list to circular linked list ChangeLinkListToCkList(LinkList head) //Here, just point the last tail pointer to the head node { LinkList p,p2=head,p1=head; while(p2){ //The last p is the pointer of the link list to the end node p=p2; p2=p2->next; } while(p!=head) //The last head is the pointer to the penultimate tail node { head=head->next; } head->next=p1; } //Test cycle list void TestCKList(LinkList head) //Note here that the header node has no data, so it will output its address value { int num=0; while(head&&num<10) { head=head->next; num++; cout<<head->user.username<<endl; } } //Add data to circular linked list void AddElemIntoCKList(LinkList head,int index,User user) { LinkList p=(LinkList)malloc(sizeof(LNode)); p->user=user; int i=0; for(;i<index-1;i++) //Here, the previous node of the target location is returned { head=head->next; } p->next=head->next; //Point the target node to the node at the current target location head->next=p; //Point the previous node of the target location to the target node, and then the target node completes the insertion operation } //Delete node at position i void DeletElemFromCKList(LinkList head,int index) { int i=0; for(;i<index-1;i++) //Here, the previous node of the target location is returned { head=head->next; } LinkList p=head->next; head->next=head->next->next; free(p); } //Get tail pointer of linked list LinkList GetTails(LinkList head,int i) { LinkList p; int index=0; while(head && index<i) { p=head==0?p:head; head=head->next; index++; } return p; } //Merge two circular lists into one void ContactCKList(LinkList tails_0,LinkList tails_1) { LinkList p=tails_1->next->next; //Find the first element node of the second circular list tails_1->next=tails_0->next; //The tail node of the second linked list points to the head node of the first linked list tails_0->next=p; //The tail node of the first linked list points to the first element node of the second linked list } int main() { LinkList L; User user; //Create a single chain table LinkList head=CreateLinkList(L); //Insert a piece of data by back interpolation InsertElem_Back(head); //Test output list //TestList(head); //Change single chain list to circular chain list ChangeLinkListToCkList(head); //Test cycle list //TestCKList(head); //Loop list add data to position i //int i=3; //user.id=0; //strcpy(user.username,"px"); //AddElemIntoCKList(head,i,user); //Delete node at position i //DeletElemFromCKList(head,i); //Merge two circular lists into one LinkList head1=CreateLinkList(L); //Create a new single chain table InsertElem_Back(head1); //Add 5 data to linked list ChangeLinkListToCkList(head1); //Convert the list to a circular list LinkList tails_0=GetTails(head,5); //Get the tail pointer of the first linked list LinkList tails_1=GetTails(head1,5); //Get the tail pointer of the second linked list ContactCKList(tails_0,tails_1); //Merge two circular lists into one return 0; }