双向链表的增,删,改,查

由于单向链表只能从头遍历,那么在做增删改查操作时,必须从头结点开始遍历。特别是在尾节点做追加操作时,需要将所有节点全部遍历一遍。在时间上花费较多。但是双向链表就不存在这个问题,在对双向链表做追加操作时只需要对头结点的先序节点进行一次遍历就到达了链表的尾部。这样就大大的减少了时间上的开销。

以下是双向链表的结构示意图:

可以看出,每个节点都有两个指针,一个指向前面,一个指向后面。指向前面的叫先序节点,指向后面的叫后继结点。

我们通过这两个指针来访问所有节点,并通过他们来对链表进行操作。

双链表删除节点

以下是对应代码:

voidDeleteNode(Node *head,intnum)//删除一个节点{inti =0;Node *temp =NULL;for(i=0;inext;}temp = head;//先暂存被删除节点head->prior->next = head->next;head->next->prior = head->prior;free(temp);printf("删除完毕\n");}

双链表增加节点



  对应代码:

  void InsertNode(Node *head,int num,int data) //在第num个数后面插入一个节点

  {

  int i= 0;

  Node *temp = (Node*)malloc(sizeof(Node));

  Node *tp = head;

  temp->data = data;

for(i=0;inext!=tp);i++)

  {

  head = head->next;

  }

  temp->next = head->next;

  temp->prior = head;

  head->next->prior = temp;

  head->next = temp;

  printf("插入成功\n");

  }

  为便于测试,我在这里贴上所有代码,如下:

  #define _CRT_SECURE_NO_WARNINGS

#include

#include

#include

  typedef struct ListNode

  {

  int data;

  struct ListNode *prior; //前驱节点

  struct ListNode *next; //后驱节点

  }Node;

  int AddNode(Node *head,int data) //在链表尾部增加一个节点

  {

  Node *temp = (Node *)malloc(sizeof(Node));

  temp->data = data;

  temp->next = head;

  temp->prior = head->prior;

  head->prior->next = temp;

  head->prior = temp;

  }

  void PrintList(Node *head) //打印所有节点

  {

  Node *temp = head;

  while (head->next!=temp) //判断链表是否到了尾部

  {

  head = head->next;

  printf("%d ",head->data);

  }

  printf("\n");

  }

  void Reverse_PrintList(Node *head) //倒序打印所有节点

  {

  Node *temp = head;

  while (head->prior!=temp) //判断链表是否到了头部

  {

  head = head->prior;

  printf("%d ",head->data);

  }

  printf("\n");

  }

  void DeleteNode(Node *head,int num) //删除一个节点

  {

  int i = 0;

  Node *temp = NULL;

for(i=0;i

  {

  head = head->next;

  }

  temp = head; //先暂存被删除节点

  head->prior->next = head->next;

  head->next->prior = head->prior;

  free(temp);

  printf("删除完毕\n");

  }

  void InsertNode(Node *head,int num,int data) //在第num个数后面插入一个节点

  {

  int i= 0;

  Node *temp = (Node*)malloc(sizeof(Node));

  Node *tp = head;

  temp->data = data;

for(i=0;inext!=tp);i++)

  {

  head = head->next;

  }

  temp->next = head->next;

  temp->prior = head;

  head->next->prior = temp;

  head->next = temp;

  printf("插入成功\n");

  }

  int main(int argc,char *argv[])

  {

  int i = 0;

  Node *head = (Node *)malloc(sizeof(Node));

  head->prior = head;

  head->next = head;

  for (i=0;i<5;i++)

  {

  AddNode(head,i);

  }

  PrintList(head);

  AddNode(head,99);

  PrintList(head);

  InsertNode(head,6,66);

  PrintList(head);

  InsertNode(head,3,33);

  PrintList(head);

  Reverse_PrintList(head);

  //printf("Hello World!\r\n");

  system("pause");

  return 0;

  }

还有些资料可以给学习的伙伴参考

循环链表及线性表的应用

http://www.makeru.com.cn/course/details/1902?s=45051

单链表

http://www.makeru.com.cn/live/5413_1924.html?s=45051

C语言编程基础

http://www.makeru.com.cn/live/1758_311.html?s=45051

C语言(系列“点标题下的开始学习就可以看了”)

http://www.makeru.com.cn/course/details/2233?s=45051

提升C编程能力

http://www.makeru.com.cn/live/1392_1166.html?s=45051

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容