当前位置:   article > 正文

数据结构---单链表_单链表加什么头文件

单链表加什么头文件

目录

1、单链表

2、单链表的实现

头文件

函数的实现

(1)打印链表

(2)动态申请结点

(3)尾插

(4)头插

(5)尾删

(6)头删

(7)查找

(8)在pos之前插入

(9)删除pos

 (10)在pos之后插入

(11)在pos后删除

(12)最后用完记得销毁

3、各功能的测试


前言:单链表是后面要学的双链表以及循环链表的基础,要想继续深入了解数据结构以及C++,我们就要奠定好这块基石!接下来就和我一起学习吧!

这里我们来简单实现单链表的增删查找。

1、单链表

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

 (链表和我们生活中最接近的就是火车了。)

2、单链表的实现

接下来我们来实现单链表的增删查改

头文件

  1. #pragma once
  2. #include <stdio.h>
  3. #include <assert.h>
  4. #include <stdlib.h>
  5. typedef int SLDataType;
  6. //链表的创建
  7. typedef struct SListNode
  8. {
  9. SLDataType data;//val
  10. struct SListNode* next;//存储下一个结点的地址
  11. }SListNode,SLN;
  12. //打印链表
  13. void SListPrint(SListNode* phead);
  14. //尾插
  15. void SListPushBack(SListNode** pphead, SLDataType x);
  16. //头插
  17. void SListPushFront(SListNode** pphead, SLDataType x);
  18. //尾删
  19. void SListPopBack(SListNode** pphead);
  20. //头删
  21. void SListPopFront(SListNode** pphead);
  22. //查找
  23. SListNode* SListFind(SListNode* phead, SLDataType x);
  24. //在pos位置之前插入
  25. void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x);
  26. //删除pos位置
  27. void SListErase(SListNode** pphead, SListNode* pos);
  28. //在pos位置之后插入
  29. void SlistInserAfter(SListNode* pos, SLDataType x);
  30. //删除pos后的值
  31. void SlistEraseAfter(SListNode* pos);
  32. //用完销毁
  33. void SListDestroy(SListNode** pphead);

函数的实现

(1)打印链表

  1. void SListPrint(SListNode* phead)
  2. {
  3. assert(phead);
  4. SListNode* cur = phead;
  5. if (cur == NULL)
  6. {
  7. printf("SList is NULL\n");
  8. }
  9. while (cur != NULL)
  10. {
  11. printf("%d->", cur->data);
  12. cur = cur->next;
  13. }
  14. printf("NULL\n");
  15. }

(2)动态申请结点

将一个data x动态申请结点。

  1. SListNode* BuySList(SLDataType x)
  2. {
  3. SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
  4. if (newnode == NULL)
  5. {
  6. printf("malloc fail\n");
  7. exit(-1);
  8. }
  9. else
  10. {
  11. newnode->data = x;
  12. newnode->next = NULL;
  13. }
  14. return newnode;
  15. }

(3)尾插

  1. void SListPushBack(SListNode** pphead, SLDataType x)
  2. {
  3. assert(pphead);
  4. SListNode* newnode = BuySList(x);
  5. if (*pphead == NULL)
  6. {
  7. *pphead = newnode;
  8. }
  9. else
  10. {
  11. //找尾
  12. SListNode* tail = *pphead;
  13. while (tail->next != NULL)
  14. {
  15. tail = tail->next;
  16. }
  17. //走完循环找到尾
  18. tail->next = newnode;
  19. }
  20. }

(4)头插

  1. void SListPushFront(SListNode** pphead, SLDataType x)
  2. {
  3. assert(pphead);
  4. SListNode* newnode = BuySList(x);
  5. newnode->next = *pphead;
  6. *pphead = newnode;
  7. }

(5)尾删

  1. void SListPopBack(SListNode** pphead)
  2. {
  3. assert(pphead);
  4. //当链表只有一个结点时
  5. if (*pphead == NULL)
  6. {
  7. printf("SListNode is NULL\n");
  8. return;
  9. }
  10. //当链表只有一个结点时
  11. else if ((*pphead)->next == NULL)
  12. {
  13. free(*pphead);
  14. *pphead = NULL;
  15. }
  16. //当链表有多个结点时
  17. else
  18. {
  19. SListNode* tail = *pphead;
  20. while (tail->next->next != NULL)
  21. {
  22. tail = tail->next;
  23. }
  24. free(tail->next);
  25. tail->next = NULL;
  26. }
  27. }

(6)头删

  1. void SListPopFront(SListNode** pphead)
  2. {
  3. assert(pphead);
  4. if (*pphead == NULL)
  5. {
  6. printf("SList is NULL\n");
  7. return;
  8. }
  9. else
  10. {
  11. SListNode* next = (*pphead)->next;
  12. free(*pphead);
  13. *pphead = next;
  14. }
  15. }

(7)查找

  1. SListNode* SListFind(SListNode* phead, SLDataType x)
  2. {
  3. assert(phead);
  4. SListNode* cur = phead;
  5. while (cur != NULL)
  6. {
  7. if (cur->data == x)
  8. {
  9. return cur;
  10. }
  11. //如果没找到就往下走
  12. cur = cur->next;
  13. }
  14. //循环完成后还没找到就说明链表中没有该值
  15. return NULL;
  16. }

(8)在pos之前插入

  1. void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x)
  2. {
  3. assert(pphead);
  4. assert(pos);
  5. //pos是第一个位置
  6. if (pos == *pphead)
  7. {
  8. SListPushFront(pphead, x);
  9. }
  10. //pos不是第一个位置
  11. else
  12. {
  13. SListNode* prev = *pphead;
  14. while (prev->next != pos)
  15. {
  16. prev = prev->next;
  17. }
  18. SListNode* newnode = BuySList(x);
  19. prev->next = newnode;
  20. newnode->next = pos;
  21. }
  22. }

(9)删除pos

  1. void SListErase(SListNode** pphead, SListNode* pos)
  2. {
  3. assert(pphead);
  4. assert(pos);
  5. //1、头结点为空
  6. if (*pphead == NULL)
  7. {
  8. printf("SList is NULL\n");
  9. return;
  10. }
  11. //2、删除第一个结点
  12. else if (pos == *pphead)
  13. {
  14. SListPopFront(pphead);
  15. }
  16. //3、其他结点
  17. else
  18. {
  19. SListNode* prev = *pphead;
  20. while (prev->next != pos)
  21. {
  22. prev = prev->next;
  23. }
  24. prev->next = pos->next;
  25. free(pos);
  26. pos = NULL;
  27. }
  28. }

 (10)在pos之后插入

相对于在pos之前插入,在pos后插入可以不用传头结点,无论pos在哪个位置都适用。

  1. void SListInsertAfter(SListNode* pos, SLDataType x)
  2. {
  3. assert(pos);
  4. SListNode* newnode = BuySList(x);
  5. SListNode* next = pos->next;
  6. pos->next = newnode;
  7. newnode->next = next;
  8. //下面这种方式也可以
  9. /*SListNode* newnode = BuySList(x);
  10. newnode->next = pos->next;
  11. pos->next = newnode;*/
  12. }

(11)在pos后删除

  1. void SListEraseAfter(SListNode* pos)
  2. {
  3. assert(pos);
  4. SListNode* next = pos->next;
  5. if (next)
  6. {
  7. pos->next = next->next;
  8. free(next);
  9. next = NULL;
  10. }
  11. }

(12)最后用完记得销毁

  1. void SListDestroy(SListNode** pphead)
  2. {
  3. assert(pphead);
  4. SListNode* cur = *pphead;
  5. while (cur)
  6. {
  7. SListNode* next = cur->next;
  8. free(cur);
  9. cur = next;
  10. }
  11. *pphead = NULL;
  12. }

3、各功能的测试

  1. #include "SList.h"
  2. void test1()
  3. {
  4. SListNode* slist = NULL;
  5. //测试尾插
  6. SListPushBack(&slist, 1);
  7. SListPushBack(&slist, 2);
  8. SListPushBack(&slist, 3);
  9. SListPushFront(&slist, 5);
  10. SListPushFront(&slist, 4);
  11. SListPrint(slist);
  12. //测试头插
  13. SListPushFront(&slist, 5);
  14. SListPushFront(&slist, 4);
  15. SListPrint(slist);
  16. //测试尾删
  17. SListPopBack(&slist);
  18. SListPopBack(&slist);
  19. SListPrint(slist);
  20. //测试头删
  21. SListPopFront(&slist);
  22. SListPopFront(&slist);
  23. SListPopFront(&slist);
  24. SListPrint(slist);
  25. //测试查找
  26. SListNode* ret1 = SListFind(slist, 5);
  27. printf("%d\n", ret1->data);
  28. /*SListNode* ret2 = SListFind(slist, 2);
  29. printf("%d\n", ret2->data);*/
  30. //pos前插测试
  31. SListNode* pos = SListFind(slist, 1);
  32. if (pos)
  33. {
  34. SListInsert(&slist,pos,3);
  35. }
  36. SListPrint(slist);
  37. pos = SListFind(slist, 1);
  38. if (pos)
  39. {
  40. SListInsert(&slist, pos, 10);
  41. }
  42. SListPrint(slist);
  43. //删除pos测试
  44. pos = SListFind(slist, 10);
  45. if (pos)
  46. {
  47. SListErase(&slist, pos);
  48. }
  49. SListPrint(slist);
  50. //测试在pos后插入
  51. pos = SListFind(slist, 3);
  52. if (pos)
  53. {
  54. SListInsertAfter(pos, 6);
  55. }
  56. SListPrint(slist);
  57. pos = SListFind(slist, 1);
  58. if (pos)
  59. {
  60. SListInsertAfter(pos, 8);
  61. }
  62. SListPrint(slist);
  63. //测试删除pos后的值
  64. pos = SListFind(slist, 1);
  65. if (pos)
  66. {
  67. SListEraseAfter(pos);
  68. }
  69. SListPrint(slist);
  70. }
  71. int main()
  72. {
  73. test1();
  74. return 0;
  75. }

运行结果:

单链表的实现到此结束,如果你还想更进一步,请关注后续----单链表OJ,让你从此不再迷茫! 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号