双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。它其实就是单链表的基础上加入了前驱指针,能够很方便的访问它的前一个数据节点。
和单向链表相比有以下优势:
插入删除不需要移动元素外,可以原地插入删除
可以双向遍历
头文件dlist.h
#pragma once
typedef struct DNode
{
int data;
struct DNode *prio; //前驱指针
struct DNode *next; //后继指针
}DNode,*DList;
void InitList(DList plist);
//头插,*****
bool Insert_head(DList plist,int val);
//尾插 *****
bool Insert_tail(DList plist,int val);
//第一个数据节点的下标为0
bool Insert(DList plist,int pos,int val);//一般不使用
bool IsEmpty(DList plist);
//*****
bool Delete(DList plist,int key);
DNode * Search(DList plist,int key);
void Show(DList plist);
void Destroy(DList plist);
void Clear(DList plist);
//获取有效数据的个数
int GetLength(DList plist);
//链表逆置
void Reverse(DList plist);
具体实现dlist.cpp
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"dlist.h"
void InitList(DList plist)
{
assert(plist != NULL);
plist->next = NULL;
plist->prio = NULL;
}
//头插,*****
bool Insert_head(DList plist,int val)
{
DNode *p=(DNode *)malloc(sizeof(DNode));
p->data = val;
p->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;
for(p=plist;p->next!=NULL;p=p->next);
DNode *q=(DNode *)malloc(sizeof(DNode));
q->data = val;
q->next=p->next;
p->next=q;
q->prio = p;
return true;
}
bool IsEmpty(DList plist)
{
return plist->next == NULL;
}
DNode * Search(DList plist,int key)
{
for(DNode *p=plist->next;p!=NULL;p=p->next)
{
if(p->data == key)
{
return p;
}
}
return NULL;
}
bool Delete(DList plist,int key)
{
DNode *p=Search(plist,key);
if(p == NULL)
{
return false;
}
p->prio->next=p->next;
if(p->next != NULL)//p有可能是尾结点
{
p->next->prio=p->prio;
}
free(p);
return true;
}
void Show(DList plist)
{
for(DNode *p=plist->next;p!=NULL;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
void Destroy(DList plist)
{
DNode *p;
while(p->next != NULL)
{
p=plist->next;
p->next=plist->next;
free(p);
}
}
void Clear(DList plist)
{
Destroy(plist);
}
//获取有效数据的个数
int GetLength(DList plist)
{
int count = 0;
for(DNode*p=plist->next; p!=NULL;p=p->next)
{
count++;
}
return count;
}
void Reverse(DList plist)
{
if(plist==NULL || plist->next==NULL || plist->next->next==NULL)
{
return ;
}
int length = GetLength(plist);
DNode *p = plist->next; //p指向第一个数据节点
DNode *q;
for(q=plist->next;q->next!=NULL;q=q->next) ;//q指向最后一个数据节点
int tmp;
for(int i=0;i<length/2;i++)
{
tmp = p->data;
p->data = q->data;
q->data = tmp;
p = p->next;
q = q->prio;
}
}
测试test.cpp
int main()
{
DNode d;
InitList(&d);
for(int i=0;i<=10;i++)
{
Insert_head(&d,i);
}
Show(&d);
Delete(&d,10);
Show(&d);
Reverse(&d);
Show(&d);
}