Design of circular chain table and implementation of API
Basic Concepts
Circular List Definition: Point next pointer to the first element of the last data element in a single linked list
A circular list has all the operations of a single linked list
- Create a linked list
- Destroy a linked list
- Get the length of a linked list
- Clear the linked list
- Get POS element operations
- Insert element to position POS
- Delete the element at the POS at the location
What's NEW: cursor definition
In a circular list you can define a "current" pointer, which is often called a cursor, through which you can traverse all the elements in a linked list.
New operation of Cyclic link list
To reset a cursor to the first data element in a linked list
circlelistnode* circlelist_reset (circlelist* list);
Gets the data element that the current cursor points to
circlelistnode* circlelist_current (circlelist* list);
Move a cursor to the next data element in a linked list
circlelistnode* circlelist_next (circlelist* list);
Specify to delete a data element in a linked list directly
circlelistnode* Circlelist_deletenode (circlelist* list, circlelistnode* node);
Delete element pk based on the value of an element delete an element based on its location
Finally, the application of a cyclic chain list is added: solving Joseph problem
Joseph problem-typical application of cyclic chain list
n a person in a circle, first of all, the 1th person from the beginning of 1 a person a person by the clock, report the first m individual, make it out. And then from the next person starting from 1 clockwise, report the first m individual, and then make it out, ..., and so on, to find the order of the column.
Code:
Circlelist.h//Cyclic list API declaration #ifndef _circlelist_h_ #define _CIRCLELIST_H_ typedef void Circlelist;
typedef struct _TAG_CIRCLELISTNODE {struct _tag_circlelistnode *next;
}circlelistnode;
Create a linked list circlelist* circlelist_create ();
Destroy chain list void Circlelist_destroy (circlelist* list);
Empty list void Circlelist_clear (circlelist* list);
Gets the length of the list int circlelist_length (circlelist* list);
Insert node node int circlelist_insert (circlelist* list,circlelistnode* node, int pos) at POS position;
Get POS location of Node circlelistnode* circlelist_get (circlelist* list, int pos);
Delete POS location node circlelistnode* circlelist_delete (circlelist* list, int pos);
Data deletion based on the value of the node circlelistnode* circlelist_deletenode (circlelist* list, circlelistnode* node);
Reset cursor circlelistnode* circlelist_reset (circlelist* list);
Gets the node circlelistnode* circlelist_current (circlelist* list) of the current cursor;
Returns the node of the original cursor to the upper layer, and then lets the cursor move to the next node circlelistnode* circlelist_next (circlelist* list);
#endif
Circlelist.cpp//Cycle list API implementation #include <iostream> #include <cstdio> #include "circlelist.h" typedef
struct _tag_circlelist {Circlelistnode header;
Circlelistnode *silder;
int length;
}tcirclelist;
Create a list circlelist* circlelist_create () {tcirclelist *ret = (tcirclelist *) malloc (sizeof (tcirclelist));
if (ret = null) {return null;
}//Initialize ret->header.next = NULL;
Ret->silder = NULL;
ret->length = 0;
return ret;
}//Destroy list void Circlelist_destroy (circlelist* list) {if (list = = NULL) {return;
Free (list);
Return
}//Empty list void Circlelist_clear (circlelist* list) {if (list = = NULL) {return;
} tcirclelist *tlist = (tcirclelist *) list;
Tlist->header.next = NULL;
Tlist->silder = NULL;
tlist->length = 0;
Return
//Get the length of the list int circlelist_length (circlelist* list) {if (list = = NULL) {return-1; } tcirclelist *tlist = (TCirclelist *) List;
Return tlist->length; Insert node node int circlelist_insert (circlelist* list, circlelistnode* node, int pos) in POS location {if (list = = NULL | | n Ode = = NULL | |
POS < 0) {return-1;
} tcirclelist *tlist = (tcirclelist *) list;
Circlelistnode *cur = (Circlelistnode *) tlist;
for (int i = 0; i < POS; ++i) {cur = cur->next;
} Node->next = cur->next;
Cur->next = node;
If it is the first time to insert if (Tlist->length = = 0) {tlist->silder = node; } ++tlist->length; Remember the length plus 1//If it is the header interpolation if (cur = = (Circlelistnode *) tlist) {//Get the last element circlelistnode *last = Circlelist_
Get (Tlist, tlist->length-1);
Last->next = cur->next;
return 0;
//Get POS location node circlelistnode* circlelist_get (circlelist* list, int pos) {//because it is a circular list, so there is no need to exclude pos>length.
if (list = = NULL | | POS < 0) {return null;
} tcirclelist *tlist = (tcirclelist *) list;Circlelistnode *cur = (Circlelistnode *) tlist;
for (int i = 0; i < POS; ++i) {cur = cur->next;
Return cur->next; //Delete POS location node circlelistnode* circlelist_delete (circlelist* list, int pos) {tcirclelist *tlist = (Tcirclelist *
) List;
Circlelistnode *ret = NULL; if (tlist!= NULL && pos >= 0 && tlist->length > 0) {circlelistnode *cur = (circlelistnode
*) Tlist;
for (int i = 0; i < POS; ++i) {cur = cur->next;
//If the header node is deleted, the end node Circlelistnode *last = NULL is required;
if (cur = = (Circlelistnode *) tlist) {last = Circlelist_get (tlist, tlist->length-1);
RET = cur->next;
Cur->next = ret->next;
--tlist->length;
If you delete the header node if (last!= NULL) {tlist->header.next = ret->next;
Last->next = ret->next; ///If the element being deleted is the element that the cursor refers to if (Tlist->silder = ret) {Tlist->silder = Ret->next;
///If delete element after the chain table length is 0 if (tlist->length = = 0) {tlist->header.next = NULL;
Tlist->silder = NULL;
} return ret; ///Data deletion based on node value circlelistnode* circlelist_deletenode (circlelist* list, circlelistnode* node) {tcirclelist *tli
St = (tcirclelist *) list;
Circlelistnode *ret = NULL;
if (list!= null && node!= null) {Circlelistnode *cur = (Circlelistnode *) tlist;
int i = 0;
for (i = 0; i < tlist->length; ++i) {if (Cur->next = node) {ret = cur->next;
Break
} cur = cur->next;
//If Find if (ret!= NULL) {circlelist_delete (tlist, i);
} return ret;
}//Reset cursor circlelistnode* circlelist_reset (circlelist* list) {tcirclelist *tlist = (tcirclelist *) list;
circlelistnode* ret = NULL;
if (list!= NULL) {Tlist->silder = tlist->header.next;
RET = tlist->silder; } return NULL;
//Get the current cursor's point circlelistnode* circlelist_current (circlelist* list) {tcirclelist *tlist = (tcirclelist *) list;
circlelistnode* ret = NULL;
if (list!= NULL) {ret = tlist->silder;
return ret; ///Return the node of the original cursor to the upper level, and then let the cursor move to the next node circlelistnode* circlelist_next (circlelist* list) {tcirclelist *tlist = (tcircle
list *) List;
circlelistnode* ret = NULL;
if (list!= null && tlist->silder!= null) {ret = tlist->silder;
Tlist->silder = ret->next;
return ret;
}
joseph.h
Solving Joseph problem with the Circulation List API #include <cstdio> #include "circlelist.h" Const int MAXP = 8;
struct person {Circlelistnode circlenode;
int id;
};
void Joseph () {person S[MAXP];
for (int i = 0; i < Maxp ++i) {s[i].id = i + 1;
} circlelist *list = NULL;
List = Circlelist_create (); Insert element for (int i = 0; i < Maxp ++i) {//tail interpolation int ret = Circlelist_insert (list, (Circlelistnode *) &s
[i], circlelist_length (list));
if (Ret < 0) {printf ("function Circlelist_insert err:%d\n", ret); }///traverse the list for (int i = 0; i < circlelist_length (list), ++i) {person *tmp = (person *) Circlelist_get (
list, i);
if (tmp = = NULL) {printf ("function Circlelist_get err.\n");
printf ("Age:%d\n", tmp->id);
//Solve Joseph problem while (Circlelist_length (list) > 0) {person* PV = NULL;
for (int i = 1; i < 3; i++) {circlelist_next (list); } pv = (person*) circlelist_current (list);
printf ("%d", pv->id); Circlelist_deletenode (list, (Circlelistnode *) PV);
Delete the node element ("\ n") based on the value of the node.
Circlelist_destroy (list);
}
main.cpp
Cyclic list test program #include <iostream> #include <cstdio> #include "circlelist.h" #include "joseph.h" const
int MAXN = 5;
struct Student {Circlelistnode circlenode;
Char name[32];
int age;
};
void Play01 () {Student S[MAXN];
for (int i = 0; i < MAXN ++i) {s[i].age = i + 1;
} circlelist *list = NULL; List = Circlelist_create (); Create a linked list/insert element for (int i = 0; i < MAXN ++i) {//tail interpolation int ret = Circlelist_insert (list, circlelist
Node *) &s[i], circlelist_length (list);
if (Ret < 0) {printf ("function Circlelist_insert err:%d\n", ret); }///Traverse list//Here traversal prints on both sides, which can prove that this is a circular linked list for (int i = 0; i < 2 * Circlelist_length (list); ++i) {Student
*tmp = (Student *) circlelist_get (list, i);
if (tmp = = NULL) {printf ("function Circlelist_get err.\n");
printf ("Age:%d\n", tmp->age); }//delete node, through node location while (Circlelist_length (list) {StuDent *tmp = (Student *) circlelist_delete (list, circlelist_length (list)-1);
if (tmp = = NULL) {printf ("function Circlelist_delete err.\n");
printf ("Age:%d\n", tmp->age);
}//Destroy Chain list Circlelist_destroy (list);
int main () {play01 ();//To test the lifecycle of the data, write another function call to run Joseph ();
return 0;
}
design of bidirectional linked list and implementation of API
Why do I need a two-way list?
- The node of a single linked list has only one pointer to the next node.
- A single linked list of data elements cannot directly access its precursor elements
- It is extremely time-consuming to access the elements in a single linked list in reverse order!
Definition of bidirectional linked list
Add a pre pointer to the node of a single linked list to point to its predecessor
Two-way linked lists have all the operations of a single linked list
- Create a linked list
- Destroy a linked list
- Get the length of a linked list
- Clear the linked list
- Get POS element operations
- Insert element to position POS
- Delete the element at the POS at the location
Insert operation
Insert Operation exception Handling
Inserts the first element exception handling
Insert element at number No. 0;
Delete operation
New operation of bidirectional linked list
- Gets the data element that the current cursor points to
- To reset a cursor to the first data element in a linked list
- Move a cursor to the next data element in a linked list
- Move a cursor to the previous data element in a linked list
- Specify to delete a data element in a linked list directly
Two-way linked list important technical scene
The technique scene of inserting the circular link table into the node
Cyclic linked list Delete node technology scene
Advantages: Two-way linked lists add a pointer to the precursor on the basis of a single linked list
Functionally bidirectional linked lists can completely replace the use of single linked lists
Next,pre and current operations of two-way linked lists can efficiently traverse all elements in a linked list
Disadvantages: Complex Code
code example:
Dlinklist.h
Bidirectional List API declaration #ifndef _dlinklist_h_ #define _DLINKLIST_H_ typedef void Dlinklist;
typedef struct _TAG_DLINKLISTNODE {_tag_dlinklistnode *next;
_tag_dlinklistnode *pre;
}dlinklistnode;
Create a linked list dlinklist* dlinklist_create ();
Destroy the chain table void Dlinklist_destroy (Dlinklist *list);
Empty the list void Dlinklist_clear (Dlinklist *list);
Gets the chain list length int dlinklist_length (dlinklist *list);
In POS position, insert node node int dlinklist_insert (dlinklist *list, Dlinklistnode *node, int pos);
Get the node of POS position, return to Upper dlinklistnode* Dlinklist_get (dlinklist *list, int pos);
Delete POS location node dlinklistnode* dlinklist_delete (dlinklist *list, int pos);
Deletes a node node dlinklistnode* dlinklist_deletenode (dlinklist* list, dlinklistnode* node);
Reset cursor dlinklistnode* dlinklist_reset (dlinklist* list);
Gets the node that the current cursor refers to dlinklistnode* dlinklist_current (dlinklist* list);
Gets the current point of the cursor, and then lets the cursor point to the next node dlinklistnode* dlinklist_next (dlinklist* list); Gets the current point of the cursor, and then lets the cursor refer to a node forward Dlinklistnode* DLINKLIST_PRE (dlinklist* list);
#endif
dlinklist.cpp
Loop List API implementation #include <cstdio> #include <malloc.h> #include "dlinklist.h" typedef struct _TAG_DLINKLI
St {Dlinklistnode header;
Dlinklistnode *slider;
int length;
}tdlinklist;
Create a list dlinklist* dlinklist_create () {tdlinklist *ret = (tdlinklist *) malloc (sizeof (tdlinklist));
if (ret!= null) {ret->header.next = null;
Ret->header.pre = NULL;
Ret->slider = NULL;
ret->length = 0;
return ret;
}//Destroy list void Dlinklist_destroy (Dlinklist *list) {if (list!= NULL) {free (list);
} return;
//Empty list void Dlinklist_clear (Dlinklist *list) {tdlinklist *tlist = (tdlinklist *) list;
if (tlist!= null) {tlist->header.next = null;
Tlist->header.pre = NULL;
Tlist->slider = NULL;
tlist->length = 0;
} return;
}//Get list length int dlinklist_length (dlinklist *list) {tdlinklist *tlist = (tdlinklist *) lists;
int ret =-1; if (TlisT!= NULL) {ret = tlist->length;
return ret; ///At POS location, insert node node int dlinklist_insert (dlinklist *list, Dlinklistnode *node, int pos) {tdlinklist *tlist = (TD
linklist *) List;
int ret =-1, i = 0;
if (list!= null && node!= null && pos >= 0) {ret = 0;
Dlinklistnode *cur = (Dlinklistnode *) tlist;
Dlinklistnode *next = NULL;
for (i = 0; i < pos && cur->next!= NULL; ++i) {cur = cur->next;
} next = cur->next;
Cur->next = node;
Node->next = Next;
Special handling is required when the list is inserted into the first node if (next!= NULL) {next->pre = node;
} node->pre = cur; if (Tlist->length = = 0) {tlist->slider = node;//When the list inserts the first element processing cursor}//If inserted in 0 position, requires special handling, new node next before
The pre points to null if (cur = = (Dlinklistnode *) tlist) {node->pre = null;
} ++tlist->length;
return ret; //Get the node of POS position, return to upper Dlinklistnode* Dlinklist_get (dlinklist *list, int pos) {tdlinklist *tlist = (tdlinklist *) list;
dlinklistnode* ret = NULL;
int i = 0; if (List!= NULL && pos >= 0 && Pos < tlist->length) {Dlinklistnode *cur = (Dlinklistnode *
) Tlist;
for (i = 0; i < POS; ++i) {cur = cur->next;
RET = cur->next;
return ret; //Delete POS location node dlinklistnode* dlinklist_delete (dlinklist *list, int pos) {tdlinklist *tlist = (tdlinklist *) List
;
dlinklistnode* ret = NULL;
int i = 0;
if (tlist!= NULL && pos >= 0) {Dlinklistnode *cur = (Dlinklistnode *) tlist;
Dlinklistnode *next = NULL;
for (i = 0; i < pos && cur->next!= NULL; ++i) {cur = cur->next;
RET = cur->next;
Next = ret->next;
Cur->next = Next;
if (next!= NULL) {next->pre = cur;
if (cur = = (Dlinklistnode *) tlist) {//No. 0 position, requires special handling Next->pre = NULL;
} if (Tlist->slider = = ret) {Tlist->slider = next;
}--tlist->length;
return ret; //Delete node nodes dlinklistnode* dlinklist_deletenode (dlinklist* list, dlinklistnode* node) {tdlinklist *tlist = (
Tdlinklist *) List;
dlinklistnode* ret = NULL;
int i = 0;
if (tlist!= NULL) {Dlinklistnode *cur = (Dlinklistnode *) tlist;
for (i = 0; i < dlinklist_length (tlist); ++i) {if (Cur->next = = node) {ret = cur->next;
Break
} cur = cur->next;
} if (!ret) {dlinklist_delete (tlist, i);
} return ret;
}//Reset cursor dlinklistnode* dlinklist_reset (dlinklist* list) {tdlinklist *tlist = (tdlinklist *) list;
dlinklistnode* ret = NULL;
if (tlist!= NULL) {Tlist->slider = tlist->header.next;
RET = tlist->slider;
return ret; //Gets the node that the current cursor refers to dlinklistnode* Dlinklist_current (dlinklist* list) {tdlinklist *tlist = (tdlinklist *) list;
dlinklistnode* ret = NULL;
if (tlist!= NULL) {ret = tlist->slider;
return ret; //Get the current point of the cursor and then have the cursor point to the next node dlinklistnode* dlinklist_next (dlinklist* list) {tdlinklist *tlist = (tdlinklist *) Li
St
dlinklistnode* ret = NULL;
if (tlist!= null && tlist->slider!= null) {ret = tlist->slider;
Tlist->slider = ret->next;
return ret; //Get the current point of the cursor and then let the cursor refer to the Forward node dlinklistnode* dlinklist_pre (dlinklist* list) {tdlinklist *tlist = (tdlinklist *) Lis
T
dlinklistnode* ret = NULL;
if (tlist!= null && tlist->slider!= null) {ret = tlist->slider;
Tlist->slider = ret->pre;
return ret;
}
main.cpp
Loop Line table test program #include <cstdio> #include "dlinklist.h" const int MAXN = 5;
struct Student {dlinklistnode node;
int age;
};
void Play () {Student S[MAXN];
for (int i = 0; i < MAXN ++i) {s[i].age = i + 21;
} dlinklist *list = NULL; List = Dlinklist_create (); Create a linked list/insert node for (int i = 0; i < MAXN ++i) {int ret = Dlinklist_insert (list, (Dlinklistnode *) &s[
I], dlinklist_length (list);
if (Ret < 0) {return;
printf ("function Dlinklist_insert err.\n"); }///traversal list for (int i = 0; i < dlinklist_length (list); ++i) {Student *tmp = (Student *) Dlinklist_get (
list, i);
if (tmp = = NULL) {printf ("function Dlinklist_get err.\n");
Return
printf ("Age:%d\n", tmp->age); } dlinklist_delete (list, dlinklist_length (list)-1); Delete Tail node Dlinklist_delete (list, 0); Delete Header node//CURSOR traversal list for (int i = 0; i < dlinklist_length (list); + +i) {Student *tmp = (Student *) Dlinklist_next (list);
if (tmp = = NULL) {printf ("function Dlinklist_next err.\n");
Return
printf ("Age:%d\n", tmp->age);
printf ("\ n");
Dlinklist_reset (list);
Dlinklist_next (list);
Student *tmp = (Student *) dlinklist_current (list);
if (tmp = = NULL) {printf ("function dlinklist_current err.\n");
Return
printf ("Age:%d\n", tmp->age);
Dlinklist_deletenode (list, (dlinklistnode*) TMP);
TMP = (Student *) dlinklist_current (list);
if (tmp = = NULL) {printf ("function dlinklist_current err.\n");
Return
printf ("Age:%d\n", tmp->age);
printf ("Length:%d\n", Dlinklist_length (list));
Dlinklist_pre (list);
TMP = (Student *) dlinklist_current (list);
if (tmp = = NULL) {printf ("function dlinklist_current err.\n");
Return
printf ("Age:%d\n", tmp->age);
printf ("Length:%d\n", Dlinklist_length (list)); Dlinklist_destroy(list);
Return
int main () {play ();
return 0; }