Implementation + operation of a single-chain table with algorithm data structure and comparison with a sequence table
Advantages and disadvantages of ordered tables and single-chain tables:
An ordered table does not require additional storage space to represent the logical relationship between elements in a table;
You can quickly access any element in a table.
Disadvantages of an ordered table: a large number of elements need to be moved after the deletion operation is performed;
When the length of a linear table is unstable, it is difficult to determine the storage space, which may easily cause storage space fragmentation.
For a single-chain table
Chained storage means that the memory units of element storage can be discontinuous and scattered. How to maintain the relationship between elements (logical structure, the precursor and successor of each element .)
That is, a pointer field is used to store the direct relationship between the pointer and the frontend or the successor.
The above is a single-chain table pointer structure, that is, each element stores the memory space address of its successor element.
Application Scenario Selection
You can simply know the common operations of data, such as adding, deleting, modifying, and querying.
The sequential storage speed is very fast when data operations are biased towards query and modification, while the linked list must be traversed from the first node.
However, when an element is inserted or deleted, each operation of sequential storage must move the element to maintain the sequence. For a linked list, after a new storage unit is added, just change the pointer pointing to several pointer domains.
Tips1. However, we should note that the insert and delete operations of a table are actually composed of two parts: traverse to find the I-th element and then delete or insert it. In fact, the time complexity of this step is O (1 ),
The time complexity of a single-chain table is O (n). Although the sequence table needs to move the elements after I one by one, the call time is O (n ), A single-chain table does not need to move elements,
The time is O (1 ). In fact, it looks like even. In this way, a single-chain table has no major advantage over the sequential storage structure of a linear table. However, if k elements are inserted at point I,
Then, as long as the first traversal finds the I-th element, the subsequent operation is basically O (1), and the sequential operation, is to move n-I elements every time, O (n ),
The effect is displayed.
Tips2. for sequence tables, if we do not consider the dead corner of the storage space allocation during the insert or delete operations (that is, the storage space can be dynamically applied without Overflow ),
All operations are performed on the last element. That is, deletion and insertion are performed at the end of the table, so there is no need to move a large number of elements.
Code implementation:
# Ifndef _ LIST_H # define _ LIST_H # include
# Include // asserted # include
# Include
# Include
# Include
Using namespace std; # define ElemType inttypedef struct Node {ElemType data; struct Node * next;} Node, * PNode; typedef PNode List; /* ------------------------- function declaration ---------------------- */void menu (); // menu void InitList (List * list); // initialize the function bool CreateList (List * list, int count ); // create the function bool isEmpty (List * list); // judge empty bool push_front (List * list, ElemType x); // insert int push_back (List * list, elemType x); // insert bool pop_front (List * list); // Delete bool pop_back (List * list) in the header; // delete Node * find (List * list, elemType x); // query the intLocatePos (List * list, ElemType x) pointer returned by the input sequence number; // query and obtain the void Length (List * list) of the input sequence number ); // length bool delete_pos (List * list, ElemType pos); // Delete bool delete_val (List * list, ElemType x); // Delete bool modify (List * list, int pos, ElemType x); // modify the value range bool DestroyList (List * list) in a certain position; // destroy void ShowList (List list ); // display bool insert_pos (List * list, int pos, ElemType x); // insert bool insert_val (List * list, ElemType x) in the position; // Insert the value (ordered prerequisite) bool sort (List * list); // sort Node * resver (List * list); // reverse void reverse_2 (List * list ); // reverse Node * next (List * list, ElemType key); // return the successor Node * prio (List * list, ElemType key) of the input position ); // return the Node * Pfind (List * list, size_t pos) at the input position. // return the pointer at the corresponding position # endif
# Include "List. h "/* ----------------- function implementation section -------------------- */void menu () {cout <" <endl; cout <"*********************************" <<endl; cout <"* [100] CreateList *" <endl; cout <"* [0] quit_system [1] push_back *" <endl; cout <"* [2] push_front [3] show_list *" <endl; cout <"* [4] pop_back [5] pop_front *" <endl; cout <"* [6] insert_pos *" <endl; cout <"* [8] delete_p OS [9] delete_val * "<endl; cout <" * [10] find [11] LocatePos * "<endl; cout <"* [12] modify [13] destroy *" <endl; cout <"* [14] sort [15] resver *" <endl; cout <"* [16] length [17] next *" <endl; cout <"* [18] prio *" <endl; cout <"*********************************" <<endl; cout <"plese chose:>";}/* ----------- initialize a single-chain table ------------- */void InitList (List * list) {* list = (Node *) Malloc (sizeof (Node); (* list)-> next = NULL; (* list)-> data = 0 ;} /* --------- create a single-chain table by using the header node ---------------------*///??????? Bool CreateList (List * list, int count) // Node ** list {Node * p = * list; ElemType x = 0; for (int I = 1; I <= count; ++ I) {cin> x; p = p-> next = (Node *) malloc (sizeof (Node )); p-> data = x; p-> next = NULL; (* list)-> data ++;} return false ;} /* ---- judge empty -------- */bool isEmpty (List * list) {return (NULL = (* list)-> next );} /* --------------- End Plug ------------ */int push_back (List * list, ElemType x) {if (isEmpty (list) return 0; Node * cur = (* list)-> next; while (cur-> next! = NULL) {cur = cur-> next;} Node * p = (Node *) malloc (sizeof (Node); if (p = NULL) return 0; p-> data = x; cur-> next = p; p-> next = NULL; (* list)-> data ++ ;} /* --------------- header plug ------------ */bool push_front (List * list, ElemType x) {Node * p = (Node *) malloc (sizeof (Node )); if (p = NULL) return false; p-> data = x; p-> next = (* list)-> next; (* list)-> next = p; (* list)-> data ++;}/* ------ display -------------- */void ShowList (List List) {Node * p = list-> next; while (p! = NULL) {cout <p-> data <"-->"; p = p-> next;} cout <"Nul" <endl ;} /* --------------- tail deletion ------------ */bool pop_back (List * list) {if (isEmpty (list) return false; Node * cur = (* list ); while (cur-> next! = NULL & cur-> next! = NULL) {cur = cur-> next;} free (cur-> next); cur-> next = NULL; (* list)-> data --; return true ;} /* --------------- header deletion ------------ */bool pop_front (List * list) {if (isEmpty (list) return false; Node * p = (* list)-> next; (* list)-> next = p-> next; free (p); p = NULL; (* list)-> data --;} /* ----------------- insert -------------- */bool insert_pos (List * list, int pos, ElemType x) {Node * p = Pfind (list, pos-1 ); // find the I-1 node if (p = NULL) // when I <1 or I> n + 1, the insertion position I is incorrect {cout <"ERROR POS" <endl ;} node * s = (Node *) malloc (sizeof (Node); s-> data = x; s-> next = p-> next; p-> next = s; return false;}/* -------- location Delete --------------- */bool delete_pos (List * list, ElemType pos) {int count = 1; Node * cur = NULL; node * pre = * list; while (pre-> next! = NULL & pre-> next! = NULL & count <pos) // find the precursor {pre = pre-> next; count ++;} if (count! = Pos) {cout <"ERROE pos" <endl; return false;} cur = pre-> next; pre-> next = cur-> next; free (cur); cur = NULL; (* list)-> data --; return true;}/* ---------- Delete ------------- */bool delete_val (List * list, elemType x) {Node * pre = * list; Node * cur = NULL; while (pre-> next! = NULL & pre-> next! = NULL) // find the precursor {if (x = pre-> next-> data) {cur = pre-> next; pre-> next = cur-> next; free (cur); cur = NULL; return true;} pre = pre-> next;} (* list)-> data --; return true ;} /* ---------------- query returns pointer ------------ */Node * find (List * list, ElemType x) {Node * p = (* list)-> next; while (p) {if (p-> data! = X) p = p-> next; elsebreak;} return p;}/* ---------- input sequence number returned pointer ------ */Node * Pfind (List * list, size_t pos) {size_t count = 1; Node * p = (* list)-> next; while (count <pos) {p = p-> next; count ++ ;} if (count! = Pos) return NULL; return p;}/* ----------------- query return serial number ------------ */intLocatePos (List * list, ElemType x) {Node * cur = (* list) -> next; int count = 0; while (cur) {count ++; if (x = cur-> data) return count; // The returned element cur = cur-> next;} return 0;}/* ---------------- modify --------------- */bool modify (List * list, int pos, ElemType x) {int count = 1; if (pos <0 | pos> (* list)-> data) return false; Node * cur = (* list)-> next; While (cur! = NULL & cur-> next! = NULL) {if (count = pos) {cur-> data = x; return true;} cur = cur-> next; count ++;} return false ;} /* ------- destroy ------------- */bool DestroyList (List * list) {Node * p = (* list); Node * q = NULL; while (p) {q = p-> next; free (p); p = q;} (* list)-> next = NULL; cout <"the List was destroyed! "<Endl; cout <" After destroy, any operation is invalid! "<Endl; cout <" Please quit_system! "<Endl; return true;}/* ---------- sort -------------- */bool sort (List * list) {if (isEmpty (list) return false; Node * p = NULL; node * q = NULL; for (p = (* list)-> next; p! = NULL; p = p-> next) {for (q = p-> next; q! = NULL; q = q-> next) {if (p-> data> q-> data) {p-> data = p-> data ^ q-> data; q-> data = p-> data ^ q-> data; p-> data = p-> data ^ q-> data ;}} return true ;} /* ------- reverse ----------- */Node * resver (List * list) {Node * p = (* list)-> next; Node * q = NULL; Node * r = NULL; while (p) {q = p-> next; p-> next = r; r = p; p = q;} return r;} void reverse_2 (List * list) {Node * p, * q; p = (* list)-> next; // P points to the first element of the linked list (* list)-> next = NULL; // disconnected Head node and linked list while (p! = NULL) {q = p; p = p-> next; q-> next = (* list)-> next; // It is equivalent to creating a new linked list using the forward insertion method, opposite to the original (* list)-> next = q ;}/ * ---------------- return Length ---------- */void Length (List * list) {cout <"the length of list is:>" <(* list)-> data <endl ;} /* --------------- return the successor ------------ */Node * next (List * list, ElemType key) // enter the Node serial number to return the successor Node {Node * cur = (* list) -> next; int count = 1; if (isEmpty (list) | key <0 | key> (* list)-> data) return false; while (count <key) {cur = cur-> next; count ++;} if (count = key) {cur = cur-> next; return cur ;} else {cout <"ERROE" <endl; return false ;}/ * ----------------- return the precursor ------------ */Node * prio (List * list, ElemType key) {Node * pre = (* list); Node * cur = (* list)-> next; int count = 1; if (isEmpty (list) | key <1 | key> (* list)-> data) return false; while (count <key) {pre = pre-> next; cur = cur-> next; count ++;} if (count = key) {return pre;} else {cout <"ERROE" <endl; return false ;}}
# Include "List. h "int main (void) {List mylist; InitList (& mylist); ElemType item; int pos = 0; int select = 1; int length = 0; while (select) {menu (); cin> select; switch (select) {case 100: cout <"please input the length:>"; cin> length; cout <"please input the data:>"; CreateList (& mylist, length); break; case 1: cout <"please enter data:> "; cin> item; push_back (& mylist, item); break; case 2: cout <"please Enter data:> "; cin> item; push_front (& mylist, item); break; case 3: ShowList (mylist); break; case 4: pop_back (& mylist ); break; case 5: pop_front (& mylist); break; case 6: cout <"please enter position:>"; cin> pos; cout <"please enter insert data:>"; cin> item; insert_pos (& mylist, pos, item); break; case 8: cout <"please enter position:>"; cin> pos; delete_pos (& mylist, pos); break; case 9: cout <"please ente R delete data:> "; cin> item; delete_val (& mylist, item); break; case 10: cout <" please enter data:> "; cin> item; cout <"the piont of pos is:>" <find (& mylist, item) <endl; break; case 11: cout <"please enter data:>"; cin> item; cout <"the number of pos is>" <LocatePos (& mylist, item) <endl; break; case 12: cout <"please enter position:>"; cin> pos; cout <"please enter the modify data:>"; cin> Item; modify (& mylist, pos, item); break; case 13: DestroyList (& mylist); break; case 14: sort (& mylist ); cout <"the changes of SeqList will be incremental! "<Endl; ShowList (mylist); break; case 15 :( mylist)-> next = resver (& mylist); cout <" the changes of List will be resver! "<Endl; ShowList (mylist); reverse_2 (& mylist); cout <" the changes of List will be resver! "<Endl; ShowList (mylist); break; case 16: Length (& mylist); break; case 17: cout <" please enter position:> "; cin> pos; if (pos <= 0 | pos> = (mylist)-> data) // ensure that the input location is correct {cout <"error pos" <endl; break;} cout <"the NextPosData is:>" <next (& mylist, pos) -> data; break; case 18: cout <"please enter position:>"; cin> pos; if (pos <= 1 | pos> (mylist) -> data) // ensure that the input location is correct {cout <"error pos" <endl; break;} cout <"the PrePosData is:> "<prio (& mylist, pos)-> data; break ;}} return 0 ;}