我是靠谱客的博主 繁荣微笑,这篇文章主要介绍基础数据结构与算法之链表-C语言实现,现在分享给大家,希望可以做个参考。

结构定义:

将一个链表类型定义为一个指向一个链表节点LNode的指针,LNode分为数据域指针域,代码实现如下:

复制代码
1
2
3
4
5
6
7
typedef int ElementType; typedef struct LNode* List; struct LNode { ElementType Data; List Next; };

求表长:

只要当前指针非空,就不断指向下一个节点,并将计数器++即可,最后返回计数器的值。易知该操作时间复杂度为O(n),代码实现如下:

复制代码
1
2
3
4
5
6
7
8
9
10
int Length(List PtrL) { int j = 0; List p = PtrL; while (p) { p = p->Next; j++; } return j; }

按序号查找:

跟求表长操作类似,只要当前指针非空并计数器值<序号值,就不断指向下一个节点。检查跳出循环时计数器的值,如果等于序号,说明找到了,返回节点的指针;否则说明没找到,返回NULL。查找的时间复杂度为O(n),代码实现如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
List FindKth(List PtrL, int k) { List p = PtrL; int i = 1; while (p != NULL && i < k) { p = p->Next; i++; } if (i == k) return p; else return NULL; }

按值查找:

循环过程中检查p指向的节点的数据是否等于被查找元素的值即可,时间复杂度为O(n),代码实现如下:

复制代码
1
2
3
4
5
6
7
List Find(ElementType x, List PtrL) { List p = PtrL; while (p != NULL && p->Data != x) p = p->Next; return p; }

插入操作:

如果插入位置为1,说明插入位置在第一个:
首先申请节点空间,然后将数据x装填进去,最后令Next指向原来的链表,返回新申请的节点地址即可;

否则:
则需要用FindKth函数找到插入位置的前驱节点p,然后新申请一块空间s并装填数据,接着令s的Next指向p的Next,p的Next指向s,注意操作顺序,最后返回原链表指针即可。

插入操作的时间复杂度为O(n),时间主要花在了FindKth查找插入位置上,代码实现如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
List Insert(ElementType x, int i, List PtrL) { List s, p; if (i == 1) { List s = (List)malloc(sizeof(struct LNode)); s->Data = x; s->Next = PtrL; return s; } p = FindKth(PtrL, i - 1); if (!p) { printf("参数i错n"); return NULL; } else { List s = (List)malloc(sizeof(struct LNode)); s->Data = x; s->Next = p->Next; p->Next = s; return PtrL; } }

删除指定元素:

如果要删除第一个元素:
如果指针为空,则说明是空表,返回NULL即可;
否则,用s指向第一个节点,然后PtrL指向PtrL->Next,这样就跳过了第一个节点,最后释放掉第一个节点的内存,返回新的表头节点指针。

否则,找到第i个节点的前驱p:
如果p为空,说明前驱不存在,报错返回;
如果p的Next为空,说明前驱是最后一个节点,也就是要删除的节点不存在,报错返回。
否则,令s指向待删除的节点,p的Next指向s的Next,然后释放掉s的内存,返回原链表指针即可。

删除操作的时间复杂度也为O(n),同样的,其时间也是花在了查找元素上。代码实现如下:

复制代码
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
List Delete(int i, List PtrL) { List s, p; if (i == 1) { if (!PtrL) { return NULL; } else { s = PtrL; PtrL = PtrL->Next; free(s); return PtrL; } } p = FindKth(PtrL, i - 1); if (p == NULL) { printf("第%d节点不存在n", i - 1); return NULL; } else if (p->Next == NULL) { printf("第%d节点不存在n", i); return NULL; } else { s = p->Next; p->Next = s->Next; free(s); return PtrL; } }

销毁链表:

为避免产生内存泄露,线性表不用了的话归还申请的空间,代码实现如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
void Destory(List PtrL) { List p = PtrL; List s; while (p) { s = p; p = p->Next; free(s); } return; }

最后

以上就是繁荣微笑最近收集整理的关于基础数据结构与算法之链表-C语言实现的全部内容,更多相关基础数据结构与算法之链表-C语言实现内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(110)

评论列表共有 0 条评论

立即
投稿
返回
顶部