关于双向链表的操作详解

来源:互联网 发布:休格兰特 知乎 编辑:程序博客网 时间:2024/06/11 10:17

一、概述

    双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。它其实就是单链表的基础上加入了前驱指针,能够很方便的访问它的前一个数据节点。



从图中可以看出我们的struct需要3个成员:data、prio  、next;
我们再加入一些链表的基本操作可得:
#pragma once//预防头文件被重复使用typedef struct DNode{int data;struct DNode *next;//后继指针struct DNode *prio;//前驱指针}DNode,*DList;void InitList(DList plist);//头插bool Insert_head(DList plist,int val);//尾插bool Insert_tail(DList plist,int val);DNode *Search(DList plist,int key);bool Delete(DList plist,int key);bool IsEmpty(DList plist);int GetLength(DList plist);void Show(DList plist);
接下来是各个部分功能的实现:
void InitList(DList plist)//初始化{assert(plist != NULL);判断链表是否成功生成if(plist == NULL){return ;}plist->prio = NULL;制成空指针plist->next = NULL;}
头插法:
bool Insert_head(DList plist,int val){DNode *p = (DNode *)malloc(sizeof(DNode));//在堆上开辟新的节点p->data = val;//把数据赋给datap->next = plist->next;//先将数据连起来,防止数据丢失plist->next = p;连接后继p->prio = plist;//连接前驱if(p->next != NULL)//判断该节点的下个节点是否有节点,有就要连接下个节
                           // 点的前驱{
             p->next->prio = p;连接后继的前驱}return true;}



尾插法:操作过程与头插一样,但要先找到尾节点。
bool Insert_tail(DList plist,int val)//尾插{DNode *p = (DNode *)malloc(sizeof(DNode));p->data = val;DNode *q;for(q=plist;q->next != NULL;q=q->next);p->next = q->next;//****q->next = p;q->prio = plist;if(p->next != NULL){p->next->prio = p;}return true;}
获得链表长度:
int GetLength(DList plist){DNode *p;int count = 0;//计数器for(p=plist;p->next != NULL;p=p->next){count++;}return count;}
查找节点:
DNode *Search(DList plist,int key){DNode *p;for(p=plist;p->next!= NULL;p=p->next)//遍历找key
                  if(p->data == key){return p;}}return NULL;}

删除节点:可以利用查找函数,找到之后free它

bool Delete(DList plist,int key){DNode *p;p = Search(plist,key);if(p == NULL) //d等于空说明没有找到
{    return false;}p->prio->next = p->next;//穿过它,将它前一个节点的下一个节点给它的下一个节点if(p->next != NULL)  {p->next->prio = p->prio;//如果后面还有数据,将它的后面也处理好(将后继的前驱制成自己)}free(p);return true;}  

销毁:

void Destroy(DList plist){DNode *p;while(plist->next!= plist->prio){p = plist->next;plist->next = p->next;free(p);}}
程序测试:

#include<stdio.h>#include"dlist.h"#include<vld.h>int main(){DNode sa;InitList(&sa);int i;for(i=0;i<10;i++){Insert_head(&sa,i );}Show(&sa);printf("%d\n",GetLength(&sa));Delete(&sa,1);Delete(&sa,2);Delete(&sa,4);Delete(&sa,9);//Destroy(&sa);//Destroy(&sa);//Destroy(&sa);Show(&sa);printf("%d\n",Search(&sa,7));}
运行结果: