This article mainly introduces another storage form of linear tables, the chain storage structure, and the code in this article.
Table of contents
Linked storage structure of linear table
Chain storage code description
Singly linked list element insertion
Singly linked list element deletion
Singly linked list element read
Advantages and disadvantages of single linked list and chain storage
Linked storage structure of linear table
When the elements are no longer stored in adjacent positions, we only let each element know the storage address of the next element, and there is a linear table with a linked storage structure.
definition
A field that stores element data information is called a data field
The field that stores the position information of the next element is called a pointer field
The node is composed of two parts, the data field and the pointer field.
N nodes are composed of pointer chains to form a linked list, which is the linked storage image of the linear list, called the linked storage structure of the linear list
head pointer & head node
We call the pointer to the first node of the linked list the head pointer
Set another node before the linked list called the head node
The difference between head pointer and head node:
head pointer | head node |
The head pointer refers to the pointer pointing to the first node of the linked list. If the linked list has a head node, it is a pointer to the head node | The head node is set up for the unity and convenience of operation. It is placed before the node of the first element, and its data field is generally meaningless (it can also store the length of the linked list) |
The head pointer has an identification function, so the head pointer is commonly used to be named with the name of the linked list | With the head node, the operation of inserting and deleting the first node before the first element node is unified with the operation of other nodes |
Regardless of whether the linked list is empty or not, the head pointer is not empty. The head pointer is a necessary element of the linked list | The head node is not necessarily a necessary element of the linked list |
Chain storage code description
Generally, we use structure pointers to describe:
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList; /* 定义LinkList */
Singly linked list operation
Singly linked list operation is relatively simple, direct code + comment
Singly linked list creation
The singly linked list is uniquely determined by the head pointer, so the singly linked list can be named by the name of the head pointer. If the name of the head pointer is L, the linked list is called list L. Initialize a linked list:
/* 初始化链式线性表 */
Status InitList(LinkList *L)
{
*L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
if(!(*L)) /* 存储分配失败 */
return ERROR;
(*L)->next=NULL; /* 指针域为空 */
return OK;
}
Two different creation ideas:
/* 头插法 */
void CreateListHead(LinkList *L, int n)
{
LinkList p;
int i;
srand(time(0)); /* 初始化随机数种子 */
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL; /* 先建立一个带头结点的单链表 */
for (i=0; i<n; i++)
{
p = (LinkList)malloc(sizeof(Node)); /* 生成新结点 */
p->data = rand()%100+1; /* 随机生成100以内的数字 */
p->next = (*L)->next;
(*L)->next = p; /* 插入到表头 */
}
}
/* 尾插法 */
void CreateListTail(LinkList *L, int n)
{
LinkList p,r;
int i;
srand(time(0)); /* 初始化随机数种子 */
*L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
r=*L; /* r为指向尾部的结点 */
for (i=0; i<n; i++)
{
p = (Node *)malloc(sizeof(Node)); /* 生成新结点 */
p->data = rand()%100+1; /* 随机生成100以内的数字 */
r->next=p; /* 将表尾终端结点的指针指向新结点 */
r = p; /* 将当前的新结点定义为表尾终端结点 */
}
r->next = NULL; /* 表示当前链表结束 */
}
Singly linked list element insertion
original linked list
Open the pointing of the original pointer and point to it again
connect back to previous node
/* 在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *L,int i,ElemType e)
{
int j;
LinkList p,s;
p = *L;
j = 1;
while (p && j < i) /* 寻找第i个结点 */
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR; /* 第i个元素不存在 */
s = (LinkList)malloc(sizeof(Node)); /* 生成新结点(C语言标准函数) */
s->data = e;
s->next = p->next; /* 将p的后继结点赋值给s的后继 */
p->next = s; /* 将s赋值给p的后继 */
return OK;
}
Singly linked list element deletion
The original linked list pointer is broken
reconnect
/* 删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(LinkList *L,int i,ElemType *e)
{
int j;
LinkList p,q;
p = *L;
j = 1;
while (p->next && j < i) /* 遍历寻找第i个元素 */
{
p = p->next;
++j;
}
if (!(p->next) || j > i)
return ERROR; /* 第i个元素不存在 */
q = p->next;
p->next = q->next; /* 将q的后继赋值给p的后继 */
*e = q->data; /* 将q结点中的数据给e */
free(q); /* 让系统回收此结点,释放内存 */
return OK;
}
Singly linked list deletion
/* 链式线性表L已存在,将L重置为空表 */
Status ClearList(LinkList *L)
{
LinkList p,q;
p=(*L)->next; /* p指向第一个结点 */
while(p) /* 没到表尾 */
{
q=p->next;
free(p);
p=q;
}
(*L)->next=NULL; /* 头结点指针域为空 */
return OK;
}
Singly linked list element read
/* 操作结果:用e返回L中第i个数据元素的值 */
Status GetElem(LinkList L,int i,ElemType *e)
{
int j;
LinkList p; /* 声明一结点p */
p = L->next; /* 让p指向链表L的第一个结点 */
j = 1; /* j为计数器 */
while (p && j<i) /* p不为空或者计数器j还没有等于i时,循环继续 */
{
p = p->next; /* 让p指向下一个结点 */
++j;
}
if ( !p || j>i )
return ERROR; /* 第i个元素不存在 */
*e = p->data; /* 取第i个元素的数据 */
return OK;
}
Advantages and disadvantages of single linked list and chain storage
We make some comparisons with the above, and we can draw some judgments:
- Sequential storage is more suitable if frequent searches are required and few insertion or deletion operations are performed, because continuous storage space is allocated at one time, which is convenient for searching;
- When the number of elements changes greatly (elements need to be added or deleted frequently), single-linked list storage is more suitable, because the storage address is recorded by pointer, and there is no need to consider the problem of space waste or insufficient space.
Welcome to like, collect, and comment in the comment area, and reprint to indicate the source.
-----------------------------
Above link:
Links below: