一、概念
- 线性表:多个数据元素组成的有限序列。
- 链表:线性表的链式存储结构
二、分类
1.单链表
- 概念: 链表的结点包含数据域和指针域,指针域只有一个,并指向下一个结点。
- 特点:插入删除数据的时间复杂度仅为O(1),不需要预分配存储空间。
2. 循环链表
- 概念:单链表中,终端结点的指针由空指针改为指向头结点的指针,形成一个环。
- 特点:相对于单链表,循环链表可以在任意位置开始访问到整个链表,尾指针的存在方便了链表的合并。
3. 双向链表
- 概念:结点中除数据域以外包含两个指针域,一个指向前驱结点,一个指向后继结点。
- 特点:相对于单项链表可以实现双向的查找。
三、单链表
注:C语言实现,包括单链表的创建、增加数据、查询某一个数据、删除某个结点、获取链表长度等。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155/**
* singly_linked_list.c
*
* Created on: 2020年1月27日
* Author: Beyonderwei
*/
/*----------单链表----------*/
// 定义链表元素所存储的数据类型
typedef int ElemType;
// 定义节点的存储结构
typedef struct Node
{
/* data */
ElemType data;
struct Node *next;
}Node;
// 定义链表指针
typedef struct Node *LinkList;
/**
* Function 创建带有头节点的单链表,即创建一个头节点
* @param:
* list: 链表
* @return 指向链表的指针
*/
LinkList createList(void)
{
LinkList list;
list = (LinkList)malloc(sizeof(Node));
list->next = NULL;
return list;
}
/**
* Function 向链表追加数据
* @param:
* list: 链表
* elem: 要追加的数据
* @return 指向链表的指针
*/
LinkList listAppend(LinkList list, ElemType elem)
{
LinkList tmp, node;
tmp = list;
while(tmp->next)
{
tmp = tmp->next;
}
node = (LinkList)malloc(sizeof(Node)); //生成一个新的节点,来存储数据
node->data = elem;
node->next = NULL;
tmp->next = node;
return list;
}
/**
* Function 按照条件查找链表中的某个元素
* @param:
* list: 链表
* elem: 要查找的数据
* @return 指向该结点的指针
*/
LinkList getElem(LinkList list, ElemType elem)
{
LinkList tmp = list;
while(tmp)
{
if(tmp->data == elem) // 可以改为按照data中的某个条件来查找
{
return tmp;
}
else
{
tmp = tmp->next;
}
}
return NULL;
}
/**
* Function 获取链表的长度
* @param:
* list: 链表
* @return 链表的长度(不包括头节点)
*/
unsigned int getLength(LinkList list)
{
unsigned int length = 0;
LinkList tmp;
tmp = list;
while(tmp->next)
{
length++;
tmp = tmp->next;
}
return length;
}
/**
* Function 按照条件删除链表的某一个结点
* @param:
* list: 链表
* elem: 要删除的元素
* @return list: 删除成功
* NULL: 删除失败
*/
LinkList deleteElem(LinkList list, ElemType elem)
{
LinkList last_node;
LinkList tmp = list;
while(tmp->next)
{
last_node = tmp;
tmp = tmp->next; //因为头结点没有存储数据,直接略过
if(tmp->data == elem)
{
last_node->next = tmp->next;
free(tmp);
return list;
}
}
return NULL;
}
/*---------测试代码----------*/
void main(void)
{
LinkList list;
unsigned int length;
list = createList();
LinkList e;
listAppend(list, 1);
listAppend(list, 2);
listAppend(list, 3);
listAppend(list, 4);
listAppend(list, 5);
listAppend(list, 6);
deleteElem(list, 7);
deleteElem(list, 5);
length = getLength(list);
printf("链表长度为:%d\n",length);
e = getElem(list, 6);
if(e != NULL)
{
printf("查询的值为:%d\n",e->data);
}
printf("链表第一个元素:%d",list->next->data);
}
四、循环链表与双向链表
对于以上功能的实现仅仅是在单项链表上做了一些改变。
...
...
00:00
00:00
本文为作者原创文章,未经作者允许不得转载。