Linear List-----Linked List

 Table of contents

Preface

Sequence table

linked list

concept

Difference from array 

Single list

1. Create nodes

2. Insert node

Insert the node at the end (form a linked list structure)

Insert a node into the specified position (the linked list already exists)

Edit

3. Traverse the linked list data

4. Get the length of the linked list

5. Delete node

Delete tail node

Delete specified node

6. Clear the linked list

7. Data search in linked list

8. Transposition of linked list

 test set

 circular linked list

Create a circular linked list 

Two-way circular linked list

Create a two-way circular linked list


Preface

        We have studied arrays before. Arrays are also a kind of sequence list, which stores structures continuously. However, arrays are essentially a static space, and what we are mainly talking about is the sequence list of dynamic space. As the name suggests, it is our common linked list. Linked lists are divided into singly linked lists , circular linked lists and bidirectional circular linked lists . Let’s take a look at them below! (I have uploaded the code, code resources can be downloaded)

Sequence table

definition:

Sequential table, the full name of sequential storage structure, is a type of linear table . Through the study of " What is a Linear Table ", we know that linear tables are used to store data with a "one-to-one" logical relationship, and sequential tables are no exception.
Not only that, the sequence table also has requirements for the physical storage structure of the data. When a sequential table stores data, it will apply for a physical space of sufficient size in advance, and then store the data in sequence without leaving any gaps between data elements. 

Our common sequence tables include arrays and linked lists. The former is a static space data storage structure, and the latter is a dynamic space data storage structure. Both can use indexes to implement table operations. Let’s look at the related operations of linked lists.

linked list

concept

A linked list is a non-continuous and non-sequential storage structure on a physical storage unit. The logical order of data elements is realized through the link order of pointers in the linked list. A linked list consists of a series of nodes (each element in the linked list is called a node), and nodes can be dynamically generated at runtime. Each node consists of two parts: one is the data field that stores data elements, and the other is the pointer field that stores the address of the next node. Compared to linear table sequential structures, operations. 

 The nodes of the linked list are divided into two parts: data field and pointer field.

Data domain : stores various data, such as int, char types, etc.

Pointer field : serves as a bridge to the next node 

typedef struct student{
    //数据域
    int index;//作为下标表示第几位
    long num;//学号
    char name[20];//名字
    int score;//分数
    //指针域
    struct student* next;//指向下一位的指针
}Student;

Illustration

 

Difference from array 

Single list

  The singly linked list is the simplest linear list data structure. The creation of a singly linked list can be achieved through dynamic space allocation. Below we will learn the methods of creating a singly linked list and adding, deleting, modifying, and searching.

1. Create nodes

Here we will not follow the previous method when learning linked lists. Before, we created nodes at once and connected the nodes at the same time. Here we will do these two steps separately to make the code more flexible. 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct date{
    long num;//学号
    char name[20];//名字
    int score;//分数
}Date;//存放数据
typedef struct student{
    //数据域
    Data x;
    //指针域
    struct student* next;//指向下一位的指针
}Student;


//创建节点
Student* create_node(Date x) {
    Student* node = (Student*)malloc(sizeof(Student));
    //数据赋值
    node->x = x;
    //指针域指向空
    node->next = NULL;
    //返回这个节点
    return node;
}

2. Insert node

Insert the node at the end (form a linked list structure)

//把节点连接起来
void create_studentlist(Student**head,Date x) {
    Student* new_node = create_node(x);
    //如果头指针指向空节点的话,那么将头指针指向这个新的节点
    if (*head == NULL) {
        *head = new_node;
    }
    //如果头指针指向一个不为空的节点的话,那么就要顺着这个链表找到最后的节点,把新节点放入
    else {
        Student* move=*head;//创建一个移动节点,找到最后一个节点的位置
        while (move->next != NULL) {
            move = move->next;  //一直往后移
        }
        move->next = new_node;//把新节点放入进去
    }
}

Insert a node into the specified position (the linked list already exists)

//指定位置插入节点
void insert_node(Student** head, Student *new_node,int n) //向链表第n个位置插入节点
{
    Student* move=*head;
    //通过循环找到这个节点
    for (int i = 0; i < n; i++)
    {
        move = move->next;
    }
    //下面这两步的顺序千万不能反过来!!!
    new_node->next = move->next;
    move->next = new_node;
}

3. Traverse the linked list data

//输出数据
void listprint(Student**head)
{
    Student* cur=*head;
    while (cur != NULL) {
        printf("%ld %s %d\n", cur->x.num, cur->x.name, cur->x.score);
        cur = cur->next;
    }
    printf("output over!");
}

4. Get the length of the linked list

//获取链表长度
int get_listlength(Student**head)
{
    int length=0;
    Student* cur = *head;
    while (cur != NULL)
    {
        length++;
        cur = cur->next;
    }
    return length;//返回长度的大小
}

5. Delete node

Deleting a node is one of the basic operations of a linked list. It is divided into deleting the tail node and deleting the specified node (not the tail node). These two situations need to be classified and discussed. Please see the code example below:

Delete tail node

//删除尾节点
void pop_lastnode(Student** head)
{
    //如果没有节点,就直接返回
    if (*head == NULL)
        return;
    //如果只有一个节点的话,就直接删除
    else if ((*head)->next == NULL)
    {
        free(*head);
        *head = NULL;//重新置空
    }
    /*如果有多个节点的话,要找到最后一个节点的上一个节点,删除掉最后一个节点
    然后再把这个节点的next指向空*/
    else{
        Student* move = *head;
        while (move->next->next!=NULL)
        {
            move = move->next;
        }
        free(move->next);
        move->next = NULL;
    }
}

Delete specified node

//删除指定节点
void pop_node(Student** head, int n)//删除第n个节点
{
    Student* move = *head;
    Student* p;
    //通过循环依次去找到要删除节点的上一个节点
    for (int i = 0; i < n-1; i++)
    {
        move = move->next;
    }
    p = move->next;//此时要删除的节点标记为p节点
    move->next = p->next;//让p节点的上一个节点指向p节点的下一个节点,此时p节点已经断链
    free(p);
}

6. Clear the linked list

//清空链表,释放全部的空间
void clear_list(Student**head){
    Student* cur=*head;
    Student* next;
    while (cur != NULL) {
        next = cur->next;
        free(cur);
        cur = next;
    }
    *head = NULL;//头指针置空
    printf("clear over!\n");
}

7. Data search in linked list

//数据查找

//按学号查找
Student* list_search_num(Student** head, int num) {
    Student* cur = *head;
    while (cur!=NULL) {
        if (cur->x.num == num) { 
            return cur; //找到了就返回这个节点
        }
        else
            cur = cur->next;
    }
    printf("No find");
    return NULL;
}

//按名字查找
Student* list_search_name(Student** head, char *name) {
    Student* cur = *head;
    while (cur != NULL) {
        if (strcmp(cur->x.name,name)==0) {
            return cur;   //找到了就返回这个节点
        }
        else
            cur = cur->next;
    }
    printf("No find");
    return NULL;
}

8. Transposition of linked list

The order of our existing linked list is: 1->2->3->4->5 Now I want to change the order of this linked list to 5->4->3->2->1 (as shown in the figure below) This The process is the transposition of the linked list, which we can achieve through head insertion.

The steps for plugging the head are as follows: 

//链表的转置(头插法)
void list_reverse(Student** head) {
    Student *L, *start,* p, * q;
    //开辟一个暂存节点L
    L = (Student*)malloc(sizeof(Student));
    //初始化
    start = *head;
    L->next = start;
    p = L->next;
    L->next = NULL;
    while (p!= NULL) {
        q = p->next;
        p->next = L->next;
        L->next = p;
        p = q;
    }
    *head = L->next;//将此时的头结点等于新的头结点
    free(L);//释放掉暂存节点
    printf("reverse over!\n");
}

 test set

//测试结果
int main()
{
    Date a[4] = { {1,"xiaoming",90} ,{ 2,"Jack",80 } ,{ 3,"Amy",98 } ,{ 4,"John",77 } };

    Student* head = NULL;//实例化一个头节点指针
    for (int i = 0; i < 4; i++) {
        //要把实例化的头指针的地址存入进去
        create_studentlist(&head, a[i]);//依次成链
    }
    listprint(&head);//输出数据
    printf("当前节点数量: %d\n", get_listlength(&head));
    list_reverse(&head);//逆转链表
    listprint(&head);//输出数据
    pop_lastnode(&head);//删除最后一个节点
    printf("当前节点数量: %d\n", get_listlength(&head));
    listprint(&head);//输出数据
    clear_list(&head);//清空链表
    printf("当前节点数量: %d\n", get_listlength(&head));

}
//输出如下:
/*1 xiaoming 90
2 Jack 80
3 Amy 98
4 John 77
output over!
当前节点数量: 4
reverse over!
4 John 77
3 Amy 98
2 Jack 80
1 xiaoming 90
output over!
当前节点数量: 3
4 John 77
3 Amy 98
2 Jack 80
output over!
clear over!
当前节点数量: 0
*/

 circular linked list

A linked list, from the name, is a data link. Generally, the end node of a linked list does not point to a point, but when the end node of the linked list is designated as pointing to the head node, a circular linked list is formed. So if you want to build a circular linked list, you only need to redirect the last node to the head node, or point to other nodes to form a partial circular linked list. Next, I will talk about creating a circular linked list through code. The relevant operation methods (add, delete, modify and check) are basically the same as mentioned above.

Create a circular linked list 

#include<stdio.h>
#include<stdlib.h>
typedef struct node {
	int date;
	struct node* next;
}Node;
//创建节点
Node *create_node(int date) {
	Node* node = (Node*)malloc(sizeof(Node));
	node->date = date;
	node->next = NULL;
	return node;
}
//把节点连起来
void create_annuallist(Node** head,int date) {
	Node* new_node = create_node(date);
	if (*head == NULL) {
		*head = new_node;
	}
	else
	{
		Node* cur = *head;
		while (cur->next) {
			cur = cur->next;
		}
		cur->next = new_node;
	}//成链
	//成环
	new_node->next = *head;
}

If you look carefully, there is basically no difference from the creation of a linked list. In fact, just add a tail node at the end to point to the head node!

Two-way circular linked list

The headed two-way circular linked list is the most complex chain structure among linked lists and is generally used to store data separately. The linked list data structures used in practice are all headed bidirectional circular linked lists. In addition, although the structure of this linked list is complex, you will find that it can bring many advantages after using code to implement it.

Create a two-way circular linked list

Implementation ideas:

To create a two-way circular linked list, it means adding a front pointer to the single-phase linked list to point to the previous node, and then in the process of forming the chain, the next node points to the previous node, and the previous node points to the next node. , and finally the head and tail nodes point to each other to form a two-way cycle.

Code:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//创建双向循环链表
typedef struct node {
	struct node* prev; //前指针
	char date[10];//数据域
	struct node* next; //后指针
}D_node;
D_node* create_D_node(char*date) {
	D_node* new_node = (D_node*)malloc(sizeof(D_node));
	strcpy(new_node->date, date);
	//前后指针都指向空,初始化
	new_node->prev = NULL;
	new_node->next = NULL;
	return new_node;
}
void create_D_list(D_node** head, char* date) {
	D_node* new_node = create_D_node(date);
	if (*head == NULL) {  //判断头结点是否为空
		*head = new_node;
	}
	else
	{
		D_node* cur = *head;
		while (cur->next) {
			cur = cur->next;
		}
		//双向指向(前指向后,后指向前)
		new_node->prev = cur;
		cur->next = new_node;
	}
	//头尾指针互相指向,成环
	new_node->next = *head;
	(*head)->prev = new_node;
}

 Okay, that’s all for this issue, see you in the next one!

Share a wallpaper:

Guess you like

Origin blog.csdn.net/m0_73633088/article/details/132776167