双向链表,添加,删除一个节点

简介: 链表有几种,大致分为:单链表, 双向链表,循环链表,静态链表。这里为大家简单介绍双向链表节点的添加,删除。

前言


链表有几种,大致分为:单链表, 双向链表,循环链表,静态链表。这里为大家简单介绍双向链表节点的添加,删除。


提示:以下是本篇文章正文内容,下面案例可供参考


一、创建双向链表(重命名)


双向链表,即有两个指针,pre 和 next。 其中 pre 可指向当前节点的前一个节点, next 指向当前节点的下一个节点。

将该结构体重命名为 T_Name, PT_Name 便于定义结果体变量。


typedef struct NAME{
  char *name;
  struct NAME *pre;
  struct NAME *next;
}T_Name, *PT_Name;



二、添加一个节点


1.添加头指针:

static PT_Name g_ptNameHead;

1

2.若 头指针为空

ptNew 的 next 要赋值为NULL, 避免其成为野指针。


PT_Name ptNew
  if(!g_ptNameHead)
  {
  g_ptNameHead = ptNew;
  ptNew->next = NULL;
  }


3.若头指针非空

定义一个临时指针 ptTemp 。通过判断 ptTemp->next 来确定是否为结尾的指针,若确定 ptTemp 为结尾节点,就可以在其后添加新节点 ptNew。


ptTemp->next = ptNew; 其中 ptTemp 下一个节点为 ptNew, 且 ptNew 的pre指针,指向 ptTemp 。
  PT_Name ptTemp;
  ptTemp = g_ptNameHead;
  while(ptTemp->next)
  {
    ptTemp = ptTemp->next;
  }
  ptTemp->next = ptNew;
  ptNew->pre   = ptTemp;


具体代码如下:


void add_name(PT_Name ptNew)
{
  PT_Name ptTemp;
  if(!g_ptNameHead)
  {
  g_ptNameHead = ptNew;
  ptNew->next = NULL;
  }
  else
  {
  ptTemp = g_ptNameHead;
  while(ptTemp->next)
  {
    ptTemp = ptTemp->next;
  }
  ptTemp->next = ptNew;
  ptNew->pre   = ptTemp;
  }
}
void add_one_name(void)
{
  PT_Name ptNew;
  char *str;
  char name[128];
  printf("enter the name:");
  scanf("%s", name);
  str = malloc(strlen(name) + 1);
  strcpy(str, name);
  ptNew = malloc(sizeof(T_Name));
  ptNew->name = str;
  ptNew->next = NULL;
  ptNew->pre  = NULL;
  add_name(ptNew);
}


三、删除一个节点


要删除某个节点,首先我们要通过名字找到这个节点,再将其删除。


1.找到某节点

若头指针为空,说明不存在节点,就直接返回。

否则 通过 strcmp 函数比较节点的名字,逐个寻找。若名字匹配,则将其节点返回。否则 ptTemp = ptTemp->next; 直到节点为空。


PT_Name get_name(char *name)
{
  PT_Name ptTemp;
  if(!g_ptNameHead)
  {
  return NULL;
  }
  else
  {
  ptTemp = g_ptNameHead;
  while(ptTemp)
  {
    if(0 == strcmp(name, ptTemp->name))
    {
    return ptTemp;
    }
    else
    {
    ptTemp = ptTemp->next;
    }
  }
  }
  return NULL;
}


2.将节点从链表中删除

要将一个中间节点删除。例如: 要删除的节点为 ptDel , 前一个节点为 ptPre, 后一个节点为 ptNext.

(1). ptPre 的 next 指针要指向 ptDel 的 next 。
(2). ptNext 的 pre 指针要指向 ptPre 。
(3),free(ptDel->name); free(ptDel);
void del_name(PT_Name ptDel)
{
  PT_Name ptCur;  
  PT_Name ptPre;  
  PT_Name ptNext; 
  if (g_ptNameHead == ptDel)
  {
  g_ptNameHead = ptDel->next;
  /* 释放 */
  return;
  }
  else
  {
  ptCur = g_ptNameHead->next;
  while (ptCur)
  {
    if (ptCur == ptDel)
    {
    /* 从链表中删除 */
    ptPre  = ptCur->pre;
    ptNext = ptCur->next;
    ptPre->next = ptNext;
    if (ptNext)
    {
      ptNext->pre = ptPre;
    }
    break;
    }
    else
    {
    ptCur = ptCur->next;
    }
  }
  }
  free(ptDel->name);
  free(ptDel);
}

ab85022a73595de666298edfe013d47.png

四. 展示所有的节点


当 ptTemp 为空时,就以结束。


void list_all_name(void)
{
  PT_Name ptTemp = g_ptNameHead;
  int i=0;
  while(ptTemp)
  {
  printf("%02d : %s\n", i++, ptTemp->name);
  ptTemp = ptTemp->next;
  }
}


五. 实验效果


dc81d3ebd70c0df94ba94ad9668d816.png


总结

双向指针并不难,大家要多加理解。


相关文章
|
6月前
|
存储 Python
链表中插入节点
链表中插入节点
|
1月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
18 0
LeetCode第二十四题(两两交换链表中的节点)
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
44 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
49 0
|
3月前
|
算法
LeetCode第24题两两交换链表中的节点
这篇文章介绍了LeetCode第24题"两两交换链表中的节点"的解题方法,通过使用虚拟节点和前驱节点技巧,实现了链表中相邻节点的交换。
LeetCode第24题两两交换链表中的节点
05_删除链表的倒数第N个节点
05_删除链表的倒数第N个节点
04_两两交换链表中的节点
04_两两交换链表中的节点
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
54 5
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
41 4
|
4月前
|
安全 云计算
云计算自旋锁问题之在线程安全地删除链表节点时,需要频繁加锁会影响性能如何解决
云计算自旋锁问题之在线程安全地删除链表节点时,需要频繁加锁会影响性能如何解决
50 2