双链表的定义
typedef struct DNode{ //定义双链表结点类型
ElemType data; //数据域
struct DNode *prior,*next; //前驱和后继指针
}DNode,*DLinkList;
双链表的初始化
Status InitDLinkList(DLinkList &L){
L = new DNode;
if(!L) return ERROR;
L->prior = NULL;
L->next = NULL;
return OK;
}
void testDLinkList(){
//初始化双链表
DLinkList L;
InitDLinkList(L);
//后续代码
}
双链表的操作
1.获取
DNode * GetElem_Dul(DlinkList &L,int i){
DNode *p;
p = L->next;
int j = 1;
while(p && j<i-1){
p = p->next;
++j;
}
if(!p || j>i-1) return ERROR;
return p;
}
2.插入
第一种
在p节点之后插入s结点
//在p节点之后插入s结点
Status InsertNextDNode(DNode *p,DNode *s){
if(!p || !s) return ERROR;
s->next = p->next; //将结点*s插入到结点*p之后
if(p->next){
p->next->prior = s; //如果p结点有后继结点
}
s->prior = p;
p->next = s;
return OK;
}
第二种
在带头结点的双向链表L中第i个位置之前插入元素e
Status DListInsert(DLinkList &L,int i,ElemType e){
//在带头结点的双向链表L中第i个位置之前插入元素e
if(!(p = GetElem_Dul(L,i))) return ERROR;
s = new DNode;
s->data = e;
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s;
return OK;
}
3.删除
第一种
删除p的后继结点q
//删除p的后继结点q
Status DeleteDNode(DNode *p){
if(!p) return ERROR;
DNode *q;
q = p->next; //找到p的后继结点q
if(!q) return ERROR; //p没有后继
p->next = q->next;
if(q->next){ //如果p结点有后继结点
q->next->prior = p;
}
delete q; //释放结点空间
return OK;
}
第二种
删除带头结点的双向链表L中的第i个元素
//删除带头结点的双向链表L中的第i个元素
Status ListDelete(DLinkList &L,int i){
if(!(p = GetElem_Dul(L,i))) return ERROR;
p->prior->next = p->next;
if(p->next){
p->next->prior = p->prior;
}
delete p;
return OK;
}
当p->next为NULL
不需要对p->next的前继节点操作,修改完后继结点后,直接删除p即可
当p->next不为NULL
需要对p->next的前继节点进行修改,使其指向p的前继节点
4.销毁
void DestoryList(DLinkList &L){
//循环释放各个数据结点
while(L->next){
DeleteNextDNode(L);
}
delete L; //释放头结点
L = NULL; //头指针指向NULL
}
5.遍历
Status DisPlayDLinkList(DLinklist &L){
DNode *p;
p = L->next;
//后向遍历
while(p){
cout<<p->data<<endl;
p = p->next;
}
//前向遍历
while(p){
cout<<p->data<<endl;
p = p->prior;
}
//前向遍历
while(p->prior){
cout<<p->data<<endl;
p = p->prior;
}
return OK;
}