一.双链表的定义:
typedef struct DNode{
ElemType data;
struct DNode *prior,*next; //前驱,后继指针
}DNode,*DLinkList;
二.带头结点的双链表的初始化:
//初始化一个双链表
bool InitDLinkList(DLinkList &L){
L=(DNode*)malloc(sizeof(DNode));//分配一个头结点
if(L==NULL)
return false;
L->prior=NULL; //头结点的prior永远指向null
L->next=NULL;
return true;
}
void testDLinkList(){
DLinkList L;
InitDLinkList(L);
//。。。
}
判断一个双链表是否为空:
bool EmptyDLinkList(DLinkList L){
return(L->next==NULL); //与单链表判断是否非空一样
}
三.双链表的插入:
注意:当在最后一个结点执行后插操作的时候,p->next为空指针,空指针没有前驱结点。p->next->prior 这句会报错。所以要加一个判断来区别是否为最后一个结点。
//在p结点后插入s结点
bool InsertNextDNode(DNode *p,DNode *s){
if(p==NULL||s==NULL)
return false;
s->next=p->next; //让s的next指向p的后继结点
if(p->next!=NULL)。 //如果p有后继结点
p->next->prior=s; //p后继结点的前驱指向s
p->next=S;
s->prior=p;
return true;
}
四.双链表的删除:
//删除p的后一个结点
bool DeleteNextDNode(DNode *p){
if(p==NULL)
return false;
DNode *s; //s为p的后一个结点
s=p->next;
if(s==NULL)
return false;
p->next=s->next;
if(s->next!=NULL)
s->next->prior=p;
free(s);
return true;
}
//销毁双链表(循环释放各个结点)
void DestoryList(DLinkList &L){
while(L->next!=NULL)
DeleteNextDNode(L):
free(L); //释放头结点
L=NULL; //头指针指向空(否则成野指针)
}
五.双链表的遍历:
由于双链表由于有前驱与后继,所以遍历的时候可以正向遍历也可以反向遍历。
//后向遍历核心语句
while(p->next!=NULL){
//相应操作。。。
p=p->next;
}
//前向遍历核心语句
while(p!=NULL){
//相应操作。。。
p=p->prior;
}
//跳过头结点的前向遍历
While(p->prior!=NULL){
//相应操作。。。
p=p->prior;
}
按位查找,按值查找都需要遍历实现。时间复杂度都是O(n)。