Linear table implemented by pointer-linked list

Source: Internet
Author: User

The previous section describes how to use arrays to implement linear tables. This section uses pointers:

First look at the 12 functions:

# Include <stdio. h> # include <malloc. h> typedef int elemtype; typedef struct lnode {// the stored data elemtype data; // the pointer to the next node lnode * Next;} lnode, * linklist; // initialize the linked list bool initlist (linklist * lst) {* lst = (linklist) malloc (sizeof (lnode); If (null = lst) return false; (* lst) -> next = NULL; return true;} // Delete the linked table void deletelist (linklist * lst) {linklist P = (* lst)-> next; linklist Q; while (P) {q = p-> next; free (p); P = Q;} Free (* lst); * lst = NULL;} // clear the linked table void clearlist (linklist * lst) {linklist P = (* lst)-> next; linklist Q; while (P) {q = p-> next; free (p); P = Q ;}( * lst)-> next = NULL ;} // determine whether the linked list is empty. bool is_empty (linklist * lst) {If (null = (* lst)-> next) {printf ("the list is empty! \ N "); Return true;} else {printf (" the list is not empty! \ N "); Return false ;}/// the prepaid printlist (linklist * lst) {printf (" list elements are :"); linklist P = (* lst)-> next; while (p) {printf ("% d", p-> data); P = p-> next ;} printf ("\ n") ;}// calculate the number of elements in the linked list. Int listlength (linklist * lst) {int CNT = 0; linklist P = (* lst)-> next; while (p) {++ CNT; P = p-> next;} return CNT;} // Insert the bool insertelem (linklist * lst, int index, elemtype * E) {int CNT = 0; linklist P = (* lst); linklist q = (linklist) malloc (sizeof (lnode); While (P) {If (Index = CNT) {// The newly inserted node Pointer Points to the current node pointer to the element Q-> next = p-> next; // The pointer to the current node points to the newly inserted node p-> next = Q; // store data Q-> DATA = * E; return true ;}++ CNT; P = p-> next;} return false;} // Delete the bool deleteelem (linklist * lst, int index, elemtype * E) element in a certain position {int CNT = 0; linklist P = (* lst)-> next; // store the previous node of the current node linklist q = * lst; while (p) {If (Index = CNT) {// obtain the element * E = p-> data of the node to be deleted; // The previous node of the current node points to the next node of the current node Q-> next = p-> next; // release the current node free (p); break ;} P = p-> next; q = Q-> next; ++ CNT;} return false;} // get the position of an element int locateelem (linklist * lst, elemtype E) {int Index = 0; linklist P = (* lst)-> next; while (p) {If (E = p-> data) Return Index; ++ index; P = p-> next;} return-1;} // obtain the bool getelem (linklist * lst, int index, elemtype * E) element of a position {int CNT = 0; linklist P = (* lst)-> next; while (p) {If (Index = CNT) {* E = p-> data; return true ;}++ CNT; P = p-> next;} return false;} // obtain the next element bool nextelem (linklist * lst, elemtype curr, elemtype * NXT) {linklist P = (* lst) -> next; while (p) {If (curr = p-> data) {* NXT = p-> next-> data; return true ;} P = p-> next;} return false;} // obtain the previous element bool priorelem (linklist * lst, elemtype curr, elemtype * pre) {linklist P = (* lst) -> next; linklist q = (* lst); While (p) {If (curr = p-> data) {* pre = Q-> data; return true ;} Q = Q-> next; P = p-> next;} return false;} void inputlist (linklist * lst, int N, int * ARR) {for (INT I = n-1; I> = 0; -- I) {linklist pnew = (linklist) malloc (sizeof (lnode )); pnew-> DATA = arr [I]; pnew-> next = (* lst)-> next; (* lst)-> next = pnew ;}}

 

The last one is not required, just for the convenience of input.

A friend who is not familiar with pointers may not understand how the parameters are transmitted. Here is a specific example.

void reset(int *x){*x = 0;}

 

In the main function:

int a = 1;printf("before reset: %d\n",a);reset(&a);printf("after reset: %d\n",a);

I believe you have seen this program, but I still need to carefully explain how the compiler treats function calls: it will copy the real parameters to the form parameters, and then operate the form parameters. Therefore, changing the form parameter does not affect the real parameter. If you want to change the value of a real parameter in the main function, the address of the parameter must be passed to the called function. Although the real parameter is still copied to the form parameter, the address is copied, so it is dropped from the function, you only need to describe the address to operate the value in the main call function.
Let's look at our program:

typedef struct LNode{ElemType data;LNode *next;}LNode,*LinkList;

Defines the pointer to the struct. When we do not need to modify the pointer itself, we can pass the pointer itself:

// Determine whether the linked list is empty. bool is_empty (linklist lst) {If (null = (LST)-> next) {printf ("the list is empty! \ N "); Return true;} else {printf (" the list is not empty! \ N "); Return false ;}}

However, if our operation needs to modify this pointer, we can only pass the pointer address to the function, and then obtain the pointer itself through the lift operation "*" in the function, then, perform operations such as memory allocation, insertion, and deletion. Therefore, many of our function parameters have linklist * lst. In the main function, the pointer address is passed to the function, such as initlist (& mylist );
Comparing with passing a value, passing a pointer seems troublesome, but it has an obvious efficiency advantage: when passing a value directly, a value is copied, if we copy a complex struct, the cost is very high. But if we only copy a pointer, we only need four bytes (because our computer is 32-bit, so the address is also 32-bit, which is 4 bytes ).
In contrast, it is much more convenient to use the "Reference" concept in C ++: directly associating the real-participation parameters, and changing the real parameters can be used to change the real parameters, and no "replication" occurs.

Compared with linear tables implemented by arrays, linked lists have the advantage of easily inserting and deleting elements. However, random access to an element is very slow. You must traverse the entire linked list from the beginning, so the program always appears

Linklist P = L-> next; while (p) {// specific operation P = p-> next ;}

 

. In general, the two have their own advantages and disadvantages. If data needs to be inserted or deleted frequently, select the linked list. If frequent random examples are required, select the sequence table.

In fact, linked lists also have several complex structures, such as cyclic linked lists, two-way linked lists, and two-way linked lists. Since the basic principles are the same, we will only briefly introduce them here.

The circular linked list is very simple, that is, the pointer next of the last node points to the linked list header again. Its advantage is that no matter where you are currently in the linked list, you can always traverse all the elements in the linked list. The changes to the program part are also relatively small. during initialization, the next point is to the linked list header. During the traversal table process, the Stop Condition of the loop is changed to: While (P! = (* Lst )).

A two-way linked list adds a pointer prior to the previous node on the basis of the Basic linked list. During the insert or delete operation, the pointer must be pointed carefully:

 

# Include <stdio. h> # include <malloc. h> # define elemtype inttypedef struct dnode {elemtype data; dnode * Next; dnode * Prior;} dnode, * dlinklist; bool initdlist (dlinklist * dlst) {* dlst = (dlinklist) malloc (sizeof (dnode); If (* dlst = NULL) return false; (* dlst)-> next = NULL; (* dlst)-> prior = NULL; return true;} void deletedlist (dlinklist * dlst) {dlinklist P = (* dlst)-> next; dlinklist Q; while (p) {q = p-> next; free (p); P = Q;} Free (* dlst); * dlst = NULL;} bool insertelem (dlinklist * dlst, int index, elemtype e) {int CNT = 0; dlinklist P = * dlst; while (p) {If (Index = CNT) {dlinklist pnew = (dlinklist) malloc (sizeof (dnode); pnew-> DATA = E; pnew-> next = p-> next; pnew-> prior = P; P-> next = pnew; // note: when an element is inserted for the first time or at the last position, p-> next is empty and no node if (pnew-> next! = NULL) pnew-> next-> prior = pnew; return true;} p = p-> next; ++ CNT;} return false;} void deleteelem (dlinklist * dlst, int index, elemtype * E) {int CNT = 0; dlinklist P = (* dlst)-> next; while (p) {If (Index = CNT) {* E = p-> data; P-> prior-> next = p-> next; // if the elements at the end of the linked list are deleted, this step is not required if (p-> next! = NULL) P-> next-> prior = p-> prior; free (p); break;} + + CNT; P = p-> next ;}} void printlist (dlinklist * dlst) {printf ("elements are:"); dlinklist P = (* dlst)-> next; while (P) {printf ("% d \ t", p-> data); P = p-> next;} printf ("\ n ");}

The detailed code is provided here. In particular, when you insert an element to the linked list for the first time, or insert the element at the end of the linked list, or delete the last element of the linked list, in this case, P-> is null, so P-> next-> prior cannot be taken.

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.