In-depth analysis of C + + circular chain list and bidirectional linked list design API implementation _c language

Source: Internet
Author: User
Tags exception handling

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;  }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.