当前位置:   article > 正文

数据结构之双向链表,实现双向链表的增删改查_建立一个双向链表,并且写出删除节点,尾节点追加节点

建立一个双向链表,并且写出删除节点,尾节点追加节点

 


一、双向链表的定义

双向链表里有两个指针,一个指向前向节点,一个指向后续节点。

当链表为空的时候,phead->next = phead; phead->prev = phead;

1.双向链表节点的定义

  1. //双向链表节点的定义
  2. typedef int LTDataType;
  3. typedef struct ListNode
  4. {
  5. LTDataType data;
  6. struct ListNode * next;
  7. struct ListNode * prev;
  8. }LTNode;

2.双向链表的初始化

链表的初始化主要是构建节点,malloc出节点,将指针初始化为空;然后初始化一个头节点

  1. LTNode * BuyListNode(LTDataType x)
  2. {
  3. struct ListNode * newnode = (LTNode *)malloc(sizeof(struct ListNode));
  4. if(newnode ==NULL)
  5. {
  6. perror("malloc fail");
  7. exit(-1);
  8. }
  9. newnode->data = x;
  10. newnode->next = NULL;
  11. newnode->prev = NULL;
  12. return newnode;
  13. }
  14. LTNode * ListInit()
  15. {
  16. LTNode * phead = BuyListNode(1);
  17. phead->next = phead;
  18. phead->prev = phead;
  19. }

二、双向链表的函数接口实现

1.双链表的尾插

phead->prev就是最后一个节点,改变指针的指向,代码如下:

  1. void LTPushBack(LTNode * phead,LTDataType x)
  2. {
  3. assert(phead);
  4. LTNode * newnode = BuyListNode(x);
  5. LTNode * tail = phead->prev;
  6. //插入 前面
  7. tail->next = newnode;
  8. newnode->prev = tail;
  9. //后面
  10. newnode->next = phead;
  11. phead->prev = newnode;
  12. }

2.双向链表的尾删

删除尾节点,要保存前一个节点,tail即为phead->prev,tailPrev即为tail->prev。实现代码如下:

  1. void LTPopBack(LTNode * phead)
  2. {
  3. assert(phead);
  4. struct LTNode * tail = phead->prev;
  5. struct LTNode * tailPrev = phead->prev;
  6. tailPrev->next = phead;
  7. phead->prev = tailPrev;
  8. free(tail);
  9. }

3.双向链表的头插

插入前先创建节点newnode,实现代码如下:

  1. void LTPushFront(LTNode * phead,LTDataType x)
  2. {
  3. assert(phead);
  4. LTNode * newnode = BuyListNode(x);
  5. newnode->next = phead->next;
  6. phead->next->prev = newnode;
  7. phead->next = newnode;
  8. newnode->prev = phead;
  9. }

4.双向链表的头删

删除掉本节点,要保存本节点的下一个节点,然后修改指针的指向

  1. void LTPopFront(LTNode * phead)
  2. {
  3. assert(phead);
  4. //如果链表为空,则不能删除
  5. assert(phead->next !=phead);
  6. LTNode * first = phead->next;
  7. LTNode * second = first->next;
  8. free(first);
  9. phead->next = second;
  10. second->prev = phead;
  11. }

6.双向链表在pos前面插入

插入一个节点,首先先创建这个节点,pos指向当前位置,prev指向pos的前一个(prev),修改prev的指向,prev->next = newnode; newnode->prev = prev; newnode->next = pos; pos->prev = newnode;

  1. void LTInsert(LTNode * pos,LTDataType x)
  2. {
  3. assert(pos); //判断pos位置的有效性
  4. LTNode * prev = pos->prev;
  5. LTNode * newnode = BuyListNode(x);
  6. prev->next = newnode;
  7. newnode->prev = prev;
  8. newnode->next = pos;
  9. pos->prev = newnode;
  10. }

7.双向链表删除pos位置的节点

删除pos位置的节点,要保存Pos的前一个和后一个,链接起来

  1. void LTErase(LTNode * pos)
  2. {
  3. assert(pos);
  4. LTNode * pre = pos->prev;
  5. LTNode * next = pos->next;
  6. pre->next = next;
  7. next->prev = pre;
  8. }

8.双向链表的销毁

遍历销毁,最后销毁头节点

  1. void LTDestroy(LTNode * phead)
  2. {
  3. assert(phead);
  4. LTNode * cur = phead->next;
  5. while(cur !=phead)
  6. {
  7. LTNode * next = cur->next;
  8. free(cur); //释放掉找不到下一个,所以要保存下一个
  9. cur = next;
  10. }
  11. free(phead);
  12. }

总结

本文主要介绍了双向链表以及链表的一些接口函数,技术有限,如有错误请指正。

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

闽ICP备14008679号