C-Language Data Structure-linked list

Source: Internet
Author: User

I wrote a csdn article yesterday. Due to the poor speed of the training area, I wrote a csdn blog with nothing left. It can only be said that luck is not good. Let's put down the blog of the static table yesterday and write the linked list first today.

The data structure mentioned by Lao Tang is still quite difficult.

I. Basic Concepts

1. The linked list and single-chain table link n nodes into a linear structure called the table chain table. When each node contains only one pointer field, it is called a single-chain table.

2. Several key concepts of linked list

(1) the header node, the first node in the linked list, contains the pointer pointing to the first data element and some information about the linked list itself.

(2) Data Node. The node in the linked list that represents the data element contains the pointer to the next data element and the information of the data element.

(3) The next element pointer of the end node, the last data node in the linked list, is null, that is, this node has no successor, so it is called the end node.

In the Basic chain table insert operations, there are headers and tails. The operation method is shown in the following figure:

Header insertion method:

Table creation by means of End Plug:

In the linked list, you must pay attention to the header information and the data node pointed to by the header. At the same time, I don't know whether to establish a linked list without a head.

The storage structure of a single-chain table has been mentioned above. The figure below shows:

 

 

II. Specific implementation of header nodes, node pointer fields and data elements (laotang's big trick)

A data node in the linked list contains the data part of the data node and the pointer part pointing to the next data node. As shown in:

Obviously, a data element in a linked list must be a struct. Only in this way can two parts of a data node be saved. Sum can be any type of data, and P is the pointer to the next data node, where p is of the unsigned int type. Because it is an address, it takes exactly four bytes.

At this time, Lao Tang raised a question: why is the address of this data element in the specific pointer type, because in the specific pointer type, we also operate the data in the data node through the next operation, and set the address to the unsigned int type, which is also the four-byte address, so it is the same and a little concise.

The second question of Lao Tang is why the implementation of the sequence table stores the specific pointer address instead of the data element. I would like to ask, what if the data node you insert contains multiple data elements? How much memory will it occupy? Therefore, the most direct reason for saving the address is to save memory space.

What should we do if we want to insert elements of different data types into the linked list? You may say, insert it, but it is not that simple.

Assume that the structure of the first data node you insert is as follows:

Struct Value
{
Linklistnode header;
Int V;
};

The structure of the second data node is as follows:

Struct Value
{
Linklistnode header;
Char C;
};

Every time you insert data, the data node pointer changes. In this way, we always need to think about this node pointer. At this time, Tang has made a big move.

For linklistnode * Current = (linklistnode *) slist;
In lmain. C, struct Value
{
Linklistnode header;
Int V;
};
The data type we want to put into the linked list is the above struct, but if we want to change the data type in the connected struct, we need to take the next type as the intermediate variable, in this way, no matter what variables we want to put in are converted into such a type, We can insert them at will.
Struct Value
{
Linklistnode header;
Int V;
};
This struct is located in main. in C, this is the struct to be inserted into the linked list. This struct executes the linklist_insert (list, (linklistnode *) & V1, linklist_length (list) statement during insertion. In this way (linklistnode *) & V1 converts the address of this struct to the linklistnode * type.
Typedef struct _ tag_linklistnode linklistnode;
Struct _ tag_linklistnode
{
Linklistnode * next;
};
At this time, the node we want to insert has been converted to the above struct type. And because of linklistnode * next, when we want to insert a data node, we can directly perform next. At the same time, we can change the member type in the struct as we need to convert its address to the linklistnode * type, and then use the next pointer to operate the original struct address. This should be the data encapsulation mentioned by Lao Tang.
This involves one thing, that is, when a large struct is forcibly converted to a small struct
The nested struct must be placed in front of the large struct.
At this time, the address of the first four bytes of the structure that the operation is stuck in is to operate the original structure, that is, the data node we want to insert.

I think the above things are really around. However, you just need to remember a principle. The reason why Old Tang is doing this is to use this method to turn next into an intermediate variable. In this way, no matter what value the program on the upper layer wants to operate the linked list transmits, we can operate the data node in the linked list by operating the intermediate variable next, that is to say, you can operate data nodes in the linked list.

Iii. Code

1. Linked List Operation. c file

# Include <stdio. h> # include <malloc. h> # include "linklist. H "// because the table is reused, the address should be changed, and an address is 4 bits, so an unsigned int // just happens, that is, the address is inserted into the sequence table. Typedef unsigned int tseqlistnode; typedef struct _ tag_linklist {linklistnode header; int length;} tlinklist; linklist * linklist_create () // o (1) {// here is the space tlinklist * ret = (tlinklist *) malloc (sizeof (tlinklist) for the tlinklist struct )); // determine whether the tlinklist struct is allocated space if (Ret! = NULL) {ret-> length = 0; // RET is the pointer of the tlinklist struct member. // The Pointer Points to the header, which is a content of the struct. // The content is a struct, the next value of a content struct is null. // Here, the pointer to the next node is assigned null. Ret-> header. next = NULL;} return ret;} void linklist_destroy (linklist * List) // o (1) {// In malloc. declare free (list) in H;} void linklist_clear (linklist * List) // o (1) {// force type conversion tlinklist * slist = (tlinklist *) List; // determine whether the input value is valid if (slist! = NULL) {slist-> length = 0; slist-> header. next = NULL ;}}/* Get the length of the linked list */INT linklist_length (linklist * List)/O (1) {tlinklist * slist = (tlinklist *) List; /* is defined as-1. If the passed pointer is null,-1 */int ret =-1 is returned. If (slist! = NULL) {ret = slist-> length;} return ret;} int linklist_insert (linklist * List, linklistnode * node, int POS) // O (N) {tlinklist * slist = (tlinklist *) list; int ret = (slist! = NULL) & (Pos> = 0) & (node! = NULL); int I = 0; If (RET) {// this step is actually converting the pointer to the linklistnode * type, and assigning the address of the linked list header to current. // The current pointer can also be defined here to point current to our header node. Linklistnode * Current = (linklistnode *) slist; // determines whether the node at the end of a single-chain table is reached. For (I = 0; (I <POS) & (current-> next! = NULL); I ++) {current = Current-> next;}/* here, the address of the next node at the node location to be inserted is assigned to the same node to be inserted, point the large type pointer of node to the position that the current-> next should point. * /// Hand over the pointer to node-> next = Current-> next; // then assign the value of the new content to the pointer current-> next = node which should point to this position; // Through the above two steps, a linked list is continuously completed, at the same time, you have completed the step of inserting a new node. Slist-> length ++;} return ret;} linklistnode * linklist_get (linklist * List, int POS) // O (N) {// perform Step-by-Step forced type conversion tlinklist * slist = (tlinklist *) list; linklistnode * ret = NULL; int I = 0; If (slist! = NULL) & (0 <= POS) & (Pos <slist-> length) {linklistnode * Current = (linklistnode *) slist; // start traversing the target position. When I = POs, The traversal ends. For (I = 0; I <Pos; I ++) {current = Current-> next;} ret = Current-> next;} return ret ;} linklistnode * linklist_delete (linklist * List, int POS) // O (n) {tlinklist * slist = (tlinklist *) list; linklistnode * ret = NULL; int I = 0; if (slist! = NULL) & (0 <= POS) & (Pos <slist-> length) {linklistnode * Current = (linklistnode *) slist; for (I = 0; I <Pos; I ++) {current = Current-> next;} ret = Current-> next; Current-> next = ret-> next; slist-> length --;}/* indicates the space of a data node malloc in the main function, when deleting this node, the pointer of this node must be returned to the main function for free. */return ret ;}

2. linked list. h file

#ifndef _LINKLIST_H_#define _LINKLIST_H_typedef void LinkList;typedef struct _tag_LinkListNode LinkListNode;struct _tag_LinkListNode{    LinkListNode* next;};LinkList* LinkList_Create();void LinkList_Destroy(LinkList* list);void LinkList_Clear(LinkList* list);int LinkList_Length(LinkList* list);int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);LinkListNode* LinkList_Get(LinkList* list, int pos);LinkListNode* LinkList_Delete(LinkList* list, int pos);#endif

3. Test code:

# Include <stdio. h> # include <stdlib. h> # include "linklist. H "/* run this program using the console pauser or add your own getch, system (" pause ") or input loop */struct value {linklistnode header; int V ;}; int main (INT argc, char * argv []) {int I = 0; linklist * List = linklist_create ();/* member to be inserted into the linked list */struct value V1; struct value V2; struct value V3; struct value V4; struct value V5; v1.v = 1; v2.v = 2; v3.v = 3; v4.v = 4; v5.v = 5; /* Create a linked list by using the header insertion method. The inserted elements are moved backward in the Hui sequence */linklist_insert (list, (linklistnode *) & V1, linklist_length (list )); linklist_insert (list, (linklistnode *) & V2, linklist_length (list); linklist_insert (list, (linklistnode *) & V3, linklist_length (list); linklist_insert (list, (linklistnode *) & V4, linklist_length (list); linklist_insert (list, (linklistnode *) & V5, linklist_length (list); for (I = 0; I <linklist_length (list); I ++) {struct value * Pv = (struct value *) linklist_get (list, I); printf ("% d \ n ", PV-> V);} while (linklist_length (list)> 0) {struct value * Pv = (struct value *) linklist_delete (list, 0 ); printf ("% d \ n", PV-> V);} linklist_destroy (list); 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.