C language list (Storage Structure)

List (linked storage structure) and create

List, an alias chain storage structure or a single linked list , for storing a logical relationship "one" data. The order different tables, linked lists do not limit the physical data storage state, in other words, using the list of data elements stored in the physical storage location is random.

For example, using a storage list {1,2,3}, the physical data storage state as shown below:
Here Insert Picture Description
We see FIG not reflect the logical relationships between data. In this regard, the list of solutions, each data element in the store is equipped with a pointer for pointing to his immediate successor elements. As shown below:
Here Insert Picture Description
image on this FIG., The data elements stored in a random, and indicates the relationship between the logical storage structure through the pointer data is linked storage structure.

List of nodes

As seen in Figure 2, each data is stored in the list consists of the following two parts:

  1. Data element itself, in its region is called a data field ;
  2. Direct pointer pointing to the subsequent element, where the area is called a pointer field ;

I.e., each data element stored in the list structure as shown below:
Here Insert Picture Description
the structure shown above is referred to the list in the node . That is, the actual list is stored in a node of a real data elements contained in these nodes, as shown below:
Here Insert Picture Description
Thus, each node in the linked list of the specific implementation, the structure requires the use of the C language, particularly implementation code as follows:

typedef struct Linklist{
	int  elem;//代表数据域
	struct Linklist *next;//代表指针域,指向直接后继元素
}Linklist; //link为节点名,每个节点都是一个 link 结构体

Note: Due to a node pointer is a pointer to point to the domain, and therefore declared as Link type (struct Link * Here we must be written in the form).

Head node, the node head pointer and the first element

In fact, the list structure shown in FIG. 4 is not complete. A complete list needs consists of the following components:

  1. Head pointer : a pointer general, it is characterized by a node always points to the location of the first list. Obviously, the head pointer is used to indicate the position of the list, find easy to post the list and uses the data in the table;
  2. Node : The node list is subdivided into the head node, the first node and other nodes yuan:
    the head node : in fact, a blank node does not exist any data, usually as the first node in the list. For the list, the head node is not required, it is the role for convenience only solve some practical problems;
    the first element nodes : because of the head node (that is, an empty node), the first node in the list says there data headed element nodes. The first element nodes just a title list contains data in the first node has no real meaning;
    the other nodes: the list of other nodes;

Thus, a storage {1,2,3}complete list structure is shown below:
Here Insert Picture Description

Note : When the list has a head node of the head node pointer to the head; the contrary, if the list is not the head node, then the head node pointer points to the first element.

Understand the basic structure of the list, let's learn how to create a linked list.

Create lists (initialization)

Create a list need to do the following:

  1. Declare a head pointer (if necessary, can declare a head node);
  2. Creating multiple nodes for storing data, during the creation process, to establish a logical relationship to its predecessor node at any time;

For example, to create a storage {1,2,3,4 }and headless node list, C language codes are as follows:

linklist * initlinklist(){
	linklist * p=NULL;//创建头指针
	linklist * temp = (linklist*)malloc(sizeof(linklist));//创建首元节点
	//首元节点先初始化
	temp->elem = 1;
	temp->next = NULL;
	p = temp;//头指针指向首元节点
	//从第二个节点开始创建
	for (int i=2; i<5; i++) {
	 //创建一个新节点并初始化
		linklist *a=(linklist*)malloc(sizeof(linklist));
		a->elem=i;
		a->next=NULL;
		//将temp节点与新建立的a节点建立逻辑关系
		temp->next=a;
		//指针temp每次都指向新链表的最后一个节点,其实就是 a节点,这里写temp=a也对
		temp=temp->next;
	}
	//返回建立的节点,只返回头指针 p即可,通过头指针即可找到整个链表
	return p;
}

If you want to create a memory {1,2,3,4}and contains the list head node, the C language code:

linklist * initlinklist(){
	linklist * p=(linklist*)malloc(sizeof(linklist));//创建一个头结点
	linklist * temp=p;//声明一个指针指向头结点,
	//生成链表
	for (int i=1; i<5; i++) {
		linklist *a=(linklist*)malloc(sizeof(linklist));
		a->elem=i;
		a->next=NULL;
		temp->next=a;
		temp=temp->next;
	}
	return p;
}

We simply call initLink function in the main function, you can easily create a list of stored {1,2,3,4}, C language complete code is as follows:

#include <stdio.h>
#include <stdlib.h>
//链表中节点的结构
typedef struct Linklist{
	int  elem;
	struct Linklist *next;
}linklist;
//初始化链表的函数
linklist * initlinklist();
//用于输出链表的函数
void display(linklist *p);
int main() {
	//初始化链表(1,2,3,4)
	printf("初始化链表为:\n");
	linklist *p=initlinklist();
	display(p);
	return 0;
}
linklist * initlinklist(){
	linklist * p=NULL;//创建头指针
	linklist * temp = (linklist*)malloc(sizeof(linklist));//创建首元节点
	//首元节点先初始化
	temp->elem = 1;
	temp->next = NULL;
	p = temp;//头指针指向首元节点
	for (int i=2; i<5; i++) {
		linklist *a=(linklist*)malloc(sizeof(linklist));
		a->elem=i;
		a->next=NULL;
		temp->next=a;
		temp=temp->next;
	}
	return p;
}
void display(linklist *p){
	linklist* temp=p;//将temp指针重新指向头结点
	//只要temp指针指向的结点的next不是Null,就执行输出语句。
	while (temp) {
		printf("%d ",temp->elem);
		temp=temp->next;
	}
	printf("\n");
}

As a result of the program:

Initializing the list is:
1 2 3 4
Note : If you use with the head node list created, then the output of the display list to make the appropriate function needs to be modified:

void display(linklist *p){
	linklist* temp=p;//将temp指针重新指向头结点
	//只要temp指针指向的结点的next不是Null,就执行输出语句。
	while (temp->next) {
		temp=temp->next;
		printf("%d",temp->elem);
	}
	printf("\n");
}

Insert elements list

With the order table as an element added to the list, depending on the added positions, can be divided into the following three cases:

  • (After the first node) is inserted into the head of the list, as the first element node;
  • Inserted somewhere in the middle of the list;
  • Inserted into the list of the very end, as the last data element in the list;

Although the insertion position of the new element is not fixed, but thought the list to insert elements are fixed, only you need to do the following two steps, you can insert a new element to the specified location:

  1. The new node pointer to the next node after the insertion position;
  2. The front insertion position of the node pointer to the next node is inserted;

For example, we list {1,2,3,4}are on a basis of the head, the middle portion, the tail inserting a new element 5, which process is implemented as follows:
Here Insert Picture Description
As can be seen from the figure, although a different insertion position of the new element, but the implementation insert the method is the same, the first step is 1, then the step 2.

Note : the element list operations must be inserted before step 1 and then step 2; otherwise, if the first step 2, the insertion position can cause subsequent loss of portions of the list, step 1 can no longer be achieved.

Through the above explanation, we can try to write C code to achieve operating chain insert elements:

//p为原链表,elem表示新数据元素,add表示新元素要插入的位置
linklist * insertElem(linklist * p,int elem,int add){
	linklist * temp=p;//创建临时结点temp
	//首先找到要插入位置的上一个结点
	for (int i=1; i<add; i++) {
		if (temp==NULL) {
			printf("插入位置无效\n");
			return p;
		}
		temp=temp->next;
	}   
	//创建插入结点c
	linklist * c=(linklist*)malloc(sizeof(linklist));
	c->elem=elem;
	//向链表中插入结点
	c->next=temp->next;
	temp->next=c;
	return  p;
}

Tip : insertElem if statement to add a function, a user input for determining the insertion position is valid. For example, {1,2,3} has been stored in the list, the position of the user in claim 100 where the data element inserting a new element in the list, a user operation obviously invalid, then triggered if statement.

Delete list elements

When you delete the specified data element from the list, but in reality there is a node of the data elements removed from the list, but as a qualified programmer, responsible for storage space, storage space is no longer in use should be promptly released. Thus, deletion of data elements from the list requires the following two-step operation:

  1. The node picked from the list;
  2. Manually relieved node, the node is recovering memory space occupied;

Among them, from the list of nodes removed to achieve a very simple, just locate the node's immediate predecessor node temp, perform one-liner:

temp->next=temp->next->next;

For example, from there {1,2,3,4}to delete the list of elements 3, the effect of this code is performed as shown below:
Here Insert Picture Description
Thus, to delete the list of elements of the C language as follows:

//p为原链表,add为要删除元素的值
linklist * delElem(linklist * p,int add){
	linklist * temp=p;
	//temp指向被删除结点的上一个结点
	for (int i=1; i<add; i++) {
		temp=temp->next;
	}
	linklist * del=temp->next;//单独设置一个指针指向被删除结点,以防丢失
	temp->next=temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
	free(del);//手动释放该结点,防止内存泄漏
	return p;
}

We can see from the list node off del finally been released by the free hand function.

Find a list of elements

Find the specified data element in the list, the most commonly used method is: Header, traversing from a node table, find the element with the data element stored in the data field of each node to compare, comparison is successful or until the list to traverse the most end NULL(mark ratio of failure).

Therefore, the list to find specific data elements C language code:

//p为原链表,elem表示被查找元素、
int selectElem(linklist * p,int elem){
//新建一个指针t,初始化为头指针 p
	linklist * t=p;
	int i=1;
	//由于头节点的存在,因此while中的判断为t->next
	while (t->next) {
		t=t->next;
		if (t->elem==elem) {
			return i;
		}
		i++;
	}
	//程序执行至此处,表示查找失败
	return -1;
}

Note : When the run through the head of the list of nodes, the need to avoid the influence of the head node on test data, so when traversing the linked list traversal methods used to establish the above code, directly over the head of the linked list node traversal effective.

Update the list of elements

Update the list of elements, simply by traversing to find this element storage node, a node in the data field can make changes to the operation.

Given directly update the data elements in the list C language code for:

//更新函数,其中,add 表示更改结点在链表中的位置,newElem 为新的数据域的值
linklist *amendElem(linklist * p,int add,int newElem){
	linklist * temp=p;
	temp=temp->next;//在遍历之前,temp指向首元结点
	//遍历到被删除结点
	for (int i=1; i<add; i++) {
		temp=temp->next;
	}
	temp->elem=newElem;
	return p;
}

Details of the above list of data elements to make "additions and deletions to change search," the realization of C language code and complete code has been associated push to GitHub, a small partner needs its own clone, if you feel good, welcome Star! Here is the portal chain storage structure , in addition, children's shoes want to learn more knowledge of C, C ++, Java, Python, etc., welcome to my blog ( reunion blog ), we discussed together! Next, I will continue to update other algorithms, so stay tuned!

Published 19 original articles · won praise 8 · views 612

Guess you like

Origin blog.csdn.net/qq_43336390/article/details/103979034