当前位置:   article > 正文

【链表】双向链表的插入与删除_双向链表的插入和删除

双向链表的插入和删除

目录

插入

头插

尾插

在pos位置插入val

删除

删除第一个val值

删除pos位置的值


双向链表既有指向前驱的指针,又有指向后继的指针(也就是比单链表多一条从后往前的链)

定义结构如下:

  1. //双向链表
  2. typedef struct DNode
  3. {
  4. int data;//数据域
  5. struct DNode* prio;//前驱指针
  6. struct DNode* next;//后继指针
  7. }DNode, * DList;

其初始化,求链表长度,按值查找,输出与单链表大同小异。

插入

头插

头插要连接的链从单链表的两个变成了四个

第一步还是先连后面的链

1.连后继:p->next = plist->next;

2.连后继的前驱指针:plist->next->prio = p

在这里用到了两个指针,以防plist->next为空导致错误,我们需要在这句话前面判断:如果plist->next!=NULL,才执行这条语句。(后面的如果用到多个指针都需要像这样先判断是否为空)

第二步连前面的链

3.plist->next = p;

4.p->prio = plist;

这样,四条线就连完了。

  1. //头插
  2. bool Insert_head(DList plist, int val)
  3. {
  4. assert(plist != NULL);
  5. if (plist == NULL)
  6. {
  7. return false;
  8. }
  9. DNode* p = (DNode*)malloc(sizeof(struct DNode));//存
  10. assert(p != NULL);
  11. p->data = val;
  12. p->next = plist->next;
  13. if (plist->next != NULL)//判断很重要
  14. {
  15. plist->next->prio = p;
  16. }
  17. plist->next = p;
  18. p->prio = plist;
  19. return true;
  20. }

尾插

尾插同理连四条,下面可以对比一下双向链表与单链表的区别

(左为双向链表,右为单链表) 

在pos位置插入val

如果会了上面两种插入,按位置插也不难了

在pos位置插入和删除都要注意判断pos位置是否可以操作

  1. //位置插
  2. bool Insert(DList plist, int pos, int val)
  3. {
  4. assert(plist != NULL);
  5. if (plist == NULL)
  6. return false;
  7. if (pos<0 || pos>GetLength(plist))
  8. return false;
  9. DNode* p = (DNode*)malloc(sizeof(struct DNode));
  10. DNode* q = plist;
  11. assert(p != NULL || q != NULL);
  12. for (int i = 0; i < pos; i++)
  13. {
  14. q = q->next;
  15. }
  16. p->data = val;
  17. p->next = q->next;
  18. if (q->next != NULL)
  19. q->next->prio = p;
  20. p->prio = q;
  21. q->next = p;
  22. return true;
  23. }

删除

删除第一个val值

定义两个节点指针p,q

找到val的前驱

p指向前驱,q指向要删除的那个

最后free掉它

(其实定义一个也可以,不过本人习惯定义两个)

  1. //删除,第一个val值
  2. bool DelVal(DList plist, int val)
  3. {
  4. assert(plist != NULL);
  5. if (plist == NULL)
  6. return false;
  7. DNode* p;
  8. DNode* q;
  9. p = GetPrio(plist, val);//val的前驱
  10. if (p == NULL)
  11. return false;
  12. q = p->next;
  13. p->next = q->next;
  14. if(q->next!=NULL)
  15. q->next->prio = p;
  16. free(q);
  17. return true;
  18. }

删除pos位置的值

  1. //删除,pos位置的值
  2. bool DelPos(DList plist, int pos)
  3. {
  4. assert(plist != NULL);
  5. if (plist == NULL)
  6. return false;
  7. if (pos < 0 || pos >= GetLength(plist))
  8. return false;
  9. DNode* p = plist;
  10. for (int i = 0; i < pos; i++)
  11. {
  12. p = p->next;
  13. }
  14. DNode* q;
  15. q = p->next;
  16. p->next = q->next;
  17. if(q->next!=NULL)
  18. q->next->prio = p;
  19. free(q);
  20. return true;
  21. }

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

闽ICP备14008679号