双向链表:
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
图示:
代码如下:
DoubleList.h
#ifndef DOUBLELIST_H_
#define DOUBLELIST_H_
typedef char ElemType;
typedef struct DNode
{
ElemType data;
struct DNode *prior;//指向前驱结点
struct DNode *next;//指向后继结点
}DLinkList;//双向链表类型定义
/*初始化双向链表*/
void InitList(DLinkList *&L);//&L是以应用方式调用L,可以修改指针L
/*释放双向链表*/
void DestroyList(DLinkList *&L);
/*判断双向链表是否为空*/
int ListEmpty(DLinkList *L);
/*返回双向链表结点的个数*/
int ListLength(DLinkList *L);
/*打印双向链表*/
void PrintList(DLinkList *L);
/*获取双向链表中第i个元素*/
int GetElem(DLinkList *L,int i,ElemType &e);
/*在双向链表中查找元素e,返回它的序号*/
int LocateElem(DLinkList *L,ElemType e);
/*在双向链表的第i个位置插入元素e*/
int InsertList(DLinkList *&L,int i,ElemType e);//&L是以应用方式调用L,可以修改指针L
/*在双向链表中删除第i个元素*/
int ListDelete(DLinkList *&L,int i,ElemType &e);//&L是以应用方式调用L,可以修改指针L
#endif
DoubleList.cpp
#include <iostream>
#include <malloc.h>
#include "DoubleList.h"
using namespace std;
/*初始化双向链表*/
void InitList(DLinkList *&L)//&L是以应用方式调用L,可以修改指针L
{
L=(DLinkList*)malloc(sizeof(DLinkList));//创建头结点
L->next=NULL;
L->prior=NULL;
}
/*释放双向链表*/
void DestroyList(DLinkList *&L)
{
DLinkList *p=L,*q=L->next;
while(q!=NULL)
{
free(p);
p=q;
q=p->next;
}
free(p);
}
/*判断双向链表是否为空*/
int ListEmpty(DLinkList *L)
{
return (L->next==NULL);
}
/*返回双向链表结点的个数*/
int ListLength(DLinkList *L)
{
DLinkList *p=L->next;//p指向第一结点
int n=0;
while(p!=NULL)
{
n++;
p=p->next;
}
return n;
}
/*打印双向链表*/
void PrintList(DLinkList *L)
{
DLinkList *p=L->next;
while(p!=NULL)
{
cout<<p->data<<'\t';
p=p->next;
}
cout<<endl;
}
/*获取双向链表中第i个元素*/
int GetElem(DLinkList *L,int i,ElemType &e)
{
DLinkList *p=L->next;
int j=0;
while(p!=NULL&&j<i)
{
p=p->next;
j++;
}
if(p==NULL)
return 0;
else
{
e=p->data;
return 1;
}
}
/*在双向链表中查找元素e,返回它的序号*/
int LocateElem(DLinkList *L,ElemType e)
{
DLinkList *p=L->next;
int i=0;
while(p!=NULL&&p->data!=e)
{
p=p->next;
i++;
}
if(p==NULL)
return 0;
else
{
return i;
}
}
/*在双向链表的第i个位置插入元素e*/
int InsertList(DLinkList *&L,int i,ElemType e)//&L是以应用方式调用L,可以修改指针L
{
DLinkList *p=L,*q;
int j=0;
while(p!=NULL&&j<i)
{
p=p->next;
j++;
}
if(p==NULL)
return 0;
else
{
q=(DLinkList*)malloc(sizeof(DLinkList));
q->data=e;
q->next=p->next;
if(p->next!=NULL)
p->next->prior=q;
q->prior=p;
p->next=q;
return 1;
}
}
/*在双向链表中删除第i个元素*/
int ListDelete(DLinkList *&L,int i,ElemType &e)//&L是以应用方式调用L,可以修改指针L
{
DLinkList *p=L->next,*q;
int j=0;
while(j<i-1&&p!=NULL)
{
p=p->next;
j++;
}
if(p==NULL)
return 0;
else
{
q=p->next;//q指向被删除的结点
if(q==NULL)
return 0;//不存在第i个结点
e=q->data;
p->next=q->next;//删除结点q
if(p->next!=NULL)//删除的是最后一个结点
p->next->prior=p;
free(q);
return 1;
}
}
main.cpp
#include<iostream>
#include<malloc.h>
#include"DoubleList.h"
using namespace std;
int main()
{
DLinkList *L;
ElemType e;
cout<<"(1)初始化双向链表L"<<endl;
InitList(L);
cout<<"(2)依次采用尾插入法插入a,b,c,d,e,g,h元素"<<endl;
InsertList(L,0,'a');
InsertList(L,1,'b');
InsertList(L,2,'c');
InsertList(L,3,'d');
InsertList(L,4,'e');
InsertList(L,5,'g');
InsertList(L,6,'h');
cout<<"(3)输出双向链表"<<endl;
PrintList(L);
cout<<"(4)双向链表的长度Length="<<ListLength(L)<<endl;
cout<<"(5)判断双向链表是否为空"<<endl;
if (ListEmpty(L))
{
cout<<"双向链表为空"<<endl;
}
else
{
cout<<"双向链表不为空"<<endl;
}
GetElem(L,4,e);
cout<<"(6)双向表L的第4个元素为="<<e<<endl;
cout<<"(7)双向表中元素g的位置i="<<LocateElem(L,'g')<<endl;
cout<<"(8)在第4个元素位置上插入f元素"<<endl;
InsertList(L,4,'f');
cout<<"(9)输出双向表"<<endl;
PrintList(L);
cout<<"(10)删除双向表中的第3个元素"<<endl;
ListDelete(L,3,e);
cout<<"(11)输出双向表L"<<endl;
PrintList(L);
cout<<"(12)再在头结点处插入新结点"<<endl;
InsertList(L,0,'m');
cout<<"(13)输出双向表L"<<endl;
PrintList(L);
cout<<"(14)释放双向表L"<<endl;
DestroyList(L);
return 0;
}
结果如下: