当前位置:   article > 正文

数据结构(链表)

数据结构(链表)

1.链表的概念

概念:链表是一种物理上不连续,非顺序的存储结构,数据元素的逻辑顺序上是通过指针来连接的线性表。

2.链表的分类

链表的分类有很多,主要有以下部分组成不同的链表:

3.链表和顺序表的区别

不同点                                        顺序表                                        链表
存储空间上                                物理上一定连续                          逻辑上连续,但物理上不一定连续
随机访问                                   支持O(1)                                       不支持:O(N)
任意位置插入或者删除元素    可能需要搬移元素,效率低O(N)     只需修改指针指向
插入                                        动态顺序表,空间不够时需要扩容     没有容量的概念
应用场景                         元素高效存储+频繁访问                             任意位置插入和删除频繁
缓存利用率                                        高                                                        低

3.单链表的增删查改

链表结构如下:

头文件(函数声明):

  1. typedef int SLTDataType;
  2. typedef struct SListNode
  3. {
  4. SLTDataType a;
  5. struct SListNode* next;
  6. }SLTNode;
  7. void SLTPrint(SLTNode* phead);
  8. //头部插入删除/尾部插入删除
  9. void SLTPushBack(SLTNode** pphead, SLTDataType x);
  10. void SLTPushFront(SLTNode** pphead, SLTDataType x);
  11. void SLTPopBack(SLTNode** pphead);
  12. void SLTPopFront(SLTNode** pphead);
  13. //查找
  14. SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
  15. //在指定位置之前插入数据
  16. void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
  17. //删除pos节点
  18. void SLTErase(SLTNode** pphead, SLTNode* pos);
  19. //在指定位置之后插入数据
  20. void SLTInsertAfter(SLTNode* pos, SLTDataType x);
  21. //销毁链表
  22. void SListDesTroy(SLTNode** pphead);

代码实现

打印链表:

  1. //打印
  2. void SLTPrint(SLTNode* phead)
  3. {
  4. SLTNode* node = phead;
  5. while (node)
  6. {
  7. printf("%d ", node->a);
  8. node = node->next;
  9. }
  10. }

头部插入删除:

  1. //头插
  2. void SLTPushFront(SLTNode** pphead, SLTDataType x)
  3. {
  4. assert(pphead);
  5. SLTNode* node = c_jian(x);
  6. if (*pphead==NULL)
  7. {
  8. *pphead = node;
  9. }
  10. node->next = *pphead;
  11. *pphead = node;
  12. }
  13. //头删
  14. void SLTPopFront(SLTNode** pphead)
  15. {
  16. assert(*pphead && pphead);
  17. SLTNode* node = (*pphead)->next;
  18. free(*pphead);
  19. *pphead = NULL;
  20. *pphead = node;
  21. }

尾部插入删除:

  1. //尾插
  2. void SLTPushBack(SLTNode** pphead, SLTDataType x)
  3. {
  4. SLTNode* node = c_jian(x);
  5. if (*pphead == NULL)
  6. {
  7. *pphead = node;
  8. }
  9. else
  10. {
  11. SLTNode* tail = *pphead;
  12. while (tail->next)
  13. {
  14. tail = tail->next;
  15. }
  16. tail->next = node;
  17. }
  18. }
  19. //尾删
  20. void SLTPopBack(SLTNode** pphead)
  21. {
  22. assert(*pphead && pphead);
  23. if ((*pphead)->next == NULL)
  24. {
  25. free(*pphead);
  26. *pphead = NULL;
  27. }
  28. SLTNode* tail= *pphead;
  29. SLTNode* tail_1 = *pphead;
  30. while (tail->next)
  31. {
  32. tail_1 = tail;
  33. tail = tail->next;
  34. }
  35. free(tail);
  36. tail_1->next = NULL;
  37. tail = NULL;
  38. }

查找数据:

  1. //查找结点
  2. SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
  3. {
  4. assert(phead);
  5. while (phead)
  6. {
  7. if (phead->a == x)
  8. return phead;
  9. phead = phead->next;
  10. }
  11. return NULL;
  12. }

在指定位置之前插入数据:

  1. void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
  2. {
  3. assert(pphead);
  4. assert(pos);
  5. SLTNode* node = c_jian(x);
  6. SLTNode* prev = *pphead;
  7. if (*pphead == pos)
  8. {
  9. SLTPushFront(pphead, x);
  10. }
  11. else
  12. {
  13. while (prev->next != pos)
  14. {
  15. if (prev->next == NULL)
  16. exit(1);
  17. prev = prev->next;
  18. }
  19. node->next = pos;
  20. prev->next = node;
  21. }
  22. }

删除pos节点:

  1. void SLTErase(SLTNode** pphead, SLTNode* pos)
  2. {
  3. assert(pphead);
  4. assert(pos);
  5. SLTNode* node = *pphead;
  6. if (*pphead == pos)
  7. {
  8. SLTPopFront(pphead);
  9. }
  10. else
  11. {
  12. while (node->next != pos)
  13. {
  14. if (node == NULL)
  15. exit(1);
  16. node = node->next;
  17. }
  18. SLTNode* node1 = node->next;
  19. node->next = node1->next;
  20. free(node1);
  21. node1 = NULL;
  22. }
  23. }

在指定位置之后插入数据:

  1. void SLTInsertAfter(SLTNode* pos, SLTDataType x)
  2. {
  3. assert(pos);
  4. SLTNode* node = c_jian(x);
  5. node->next = pos->next;
  6. pos->next = node;
  7. }

销毁链表:

  1. void SListDesTroy(SLTNode** pphead)
  2. {
  3. SLTNode* node = NULL;
  4. while ((*pphead)->next)
  5. {
  6. node = *pphead;
  7. *pphead = (*pphead)->next;
  8. free(node);
  9. }
  10. free(*pphead);
  11. }

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

闽ICP备14008679号