当前位置:   article > 正文

【数据结构】 单向链表的实现

【数据结构】 单向链表的实现

单向链表是数据结构中的一种,它由节点组成,每个节点包含两个部分:数据域和指针域。数据域用于存储节点的值,指针域则用于指向下一个节点。单向链表的特点是只能从头节点开始遍历到尾节点,不能反向遍历。

1 单向链表的节点定义

  1. typedef struct node
  2. {
  3. int data; //数据域 用来存放数据 整型
  4. struct node * next; //指针域 用来存放下一个节点的首地址
  5. }link_node_t;
单向链表的操作 ( 有头的单向链表 )
//1. 创建一个空的链表 createEmpty()
//2. 遍历链表的有效元素 showLinknode()
//3. 求链表的长度 getLen()
//4. 向链表的指定位置插入数据 insertInto
//5. 判断链表是否为空 , 空返回 1 ,未空返回 0 isEmpty()
//6. 删除链表指定位置的数据 deleteFrom()
//7. 查找指定数据,出现在链表中的位置 findData()
//8. 清空链表 clear()

2.创建一个空的链表 

  1. //1.创建一个空的链表(本质上只有一个头节点链表,将头节点的首地址返回)
  2. link_node_t* createEmptyLinklist()
  3. {
  4. //创建一个空的头节点
  5. link_node_t* p = malloc(sizeof(link_node_t));
  6. if(p == NULL)
  7. {
  8. printf("createEmptyLinklist malloc failed!!\n");
  9. return NULL;//表达申请失败
  10. }
  11. //申请空间,就是为了装东西
  12. p->next = NULL;//指针域初始化为NULL,数据域不用初始化,因为头节点数据域无效
  13. //将头节点的首地址返回
  14. return p;
  15. }

3.遍历有头链表的有效元素

  1. void showLinklist(link_node_t* p)
  2. {
  3. while(p->next != NULL)
  4. {
  5. p = p->next;
  6. printf("%d ",p->data);
  7. }
  8. printf("\n");
  9. }

4.求链表的长度  

  1. int getLengthLinklist(link_node_t* p)
  2. {
  3. int len = 0;//统计长度
  4. while(p->next != NULL)
  5. {
  6. p = p->next;
  7. len++;//打印一次,就计数一次
  8. }
  9. return len;
  10. }

5.判断链表是否为空,空返回1,未空返回0

  1. //6. 判断链表是否为空 空返回1,未空返回0
  2. int isEmptyLinklist(link_node_t* p)
  3. {
  4. //p指向头节点
  5. //p->next代表头节点的指针域,头节点的指针域为空,说明后面什么没有了
  6. return p->next == NULL ? 1 : 0;
  7. }

6.向链表的指定位置插入数据

编程思想 :
0. 容错判断( post <= 0 || post > getLinkLen ( p ) + 1
1. 创建新的节点,保存插入的数据 x 也就是 100
2. 将头指针移动到插入位置的前一个位置
3. 将新的节点插入 ( 先连后面,再连前面 )
  1. int insertIntoLinklist(link_node_t* p, int post, int x)
  2. {
  3. int i;
  4. //0.容错判断
  5. if(post < 1 || post > getLengthLinklist(p)+1)
  6. {
  7. printf("insertIntoLinklist failed!!\n");
  8. return -1;
  9. }
  10. //1.创建一个新的节点,保存插入的数据x
  11. link_node_t* pnew = malloc(sizeof(link_node_t));
  12. if(pnew == NULL)
  13. {
  14. printf("pnew malloc failed!!\n");
  15. return -1;
  16. }
  17. //申请空间,就是为了装东西,立刻装东西
  18. pnew->data = x;
  19. pnew->next = NULL;
  20. //准备开始插入
  21. //2.将头指针指向(移动)插入位置的前一个位置
  22. for(i = 0; i < post-1; i++)
  23. p = p->next;
  24. //3.将新节点插入链表(先连后面,再连前面)
  25. pnew->next = p->next;//连后面
  26. p->next = pnew;//连前面
  27. return 0;
  28. }

7.删除链表指定位置的数据

编程思想 :
1. 将头指针移动到删除位置的前一个位置
2. 定义一个指针,指向被删除节点
3. 跨过被删除节点
4. 释放被删除节点
  1. int deleteFromLinklist(link_node_t* p, int post)
  2. {
  3. //0.容错判断
  4. if(post < 1 || post > getLengthLinklist(p) || isEmptyLinklist(p))
  5. {
  6. printf("deleteFromLinklist failed!!\n");
  7. return -1;
  8. }
  9. //1. 将头指针移动到删除位置的前一个位置
  10. int i;
  11. for(i = 0; i < post-1; i++)
  12. p = p->next;
  13. //2.定义了指针变量4个字节,指向被删除节点
  14. link_node_t* pdel = p->next;
  15. //3.跨过被删除节点
  16. p->next = pdel->next;
  17. //4. 释放被删除节点
  18. free(pdel)
  19. pdel = NULL;
  20. return 0;
  21. }

8.清空链表

编程思想:
1. 将头指针移动到删除位置的前一个位置 可以不写
2. 定义了指针变量 4 个字节 , 指向被删除节点
3. 跨过被删除节点
4. 释放被删除节点
  1. void clearLinklist(link_node_t* p)
  2. {
  3. //砍头思想:每次删除的是头节点的下一个节点
  4. while(p->next != NULL)
  5. //只要链表不为空,就执行删除操作 p->next == NULL循环结束,此时是空的表
  6. {
  7. //1. 将头指针移动到删除位置的前一个位置
  8. //第一步可以省略不写,因为每次删除的是头节点的下一个节点,
  9. //那么头节点就是每次被删除节点的前一个位置
  10. //2.定义了指针变量4个字节,指向被删除节点
  11. link_node_t* pdel = p->next;
  12. //3.跨过被删除节点
  13. p->next = pdel->next;
  14. //4. 释放被删除节点
  15. free(pdel);
  16. pdel = NULL;
  17. }
  18. }

9.查找指定数据x出现的位置

  1. int searchDataLinklist(link_node_t* p, int x)
  2. {
  3. int post = 0;
  4. while(p->next != NULL)
  5. {
  6. p = p->next;
  7. post++;//用来记录第几个
  8. if(p->data == x)
  9. return post;//返回值是第几个
  10. }
  11. return -1;//不存在
  12. }

结语

以上就是单向链表的基本使用,本次代码分享到此结束,后续还会分享单向链表的尾插法以及头插法。最后的最后,还请大家点点赞,点点关注,谢谢大家!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/445950
推荐阅读
相关标签
  

闽ICP备14008679号