1.结构体定义和初始化
init函数:
头结点申请空间(L为空申请失败), 把next prior 设为空
//双向链表的类型定义
typedef struct DLNode{
int data;
struct DLNode *prior,*next;
}DLNode,*DLinkList;
//双向链表的初始化
bool InitDLinkList(DLinkList &L){
L=(DLNode*)malloc(sizeof(DLNode)); //分配一个头结点
if(L==NULL)
return false; //内存分配失败
L->prior=NULL; //为空
L->next=NULL; //为空
return true;
}
2.插入
(1).p后插入s ------- p和s不为空
(2).分四步,先连后面后连前面;
(3).注意边界条件,插入到最后位置 即插入的结点的next if(p->next!=NULL)
代码:
//p结点后插入s结点
bool InsertNextNode(DLNode *p,DLNode *s){
if(p==NULL||s==NULL) //参数非法
return false;
s->next=p->next; //1
if(p->next!=NULL) //插入的那个点->next不为空
p->next->prior=s;//2
s->prior=p; //3
p->next=s; //4
return true;
//先写后两个箭头
//边界插入到最后一个位置if(p->next=NULL)
}
3.删除
(1).删除p后面的q
(2)p q不为空
(3)三步走 先连p— q-----> x ;再连p<---- q ----x ;释放q
(4)删除最后一个结点: 上面需加条件 q->next!=NULL
//删除p的后继结点q
bool DeleteNextDNode(DNode *p){
DNode *q=p->next;
if(p==NULL)
return false;
if(q==NULL)
return false;
q->next=p->next; //1
if(q->next!=NULL){ 删除的那个点->next不为空
q->next->prior=p; //2
}
free(p); //3
return true;
//边界:删除最后一个结点 if(q->next=NULL)
}
4.遍历 & 查找(按值 按位)
4.1 双向链表的后向+ 前向遍历
(1)后向遍历: ==while(p!=NULL) { p=p->next; } ==
(2)前向遍历:(包括头结点): ==while(p!=NULL) { p=p->prior; } ==
前向遍历(不包括头结点): ==while(p->prior!=NULL) { p=p->prior; } ==
遍历代码:
void printfDLinkList(DLinkList &L){
if(L==NULL)
return ;
DLNode *p=L->next;
while(p!=NULL){
printf("%d\n",p->data);
p=p->next;//后向遍历
}
return;
}
4.2查找代码
==在遍历基础上修改,时间复杂度O(n) ==
按位查找: while(p!=NULL&&j<i)
按值查找: while(p!=NULL&&p->data!=e)
//查找第i元素返回其值---通过遍历实现---O(n)
bool GetElem(DLinkList L,int i,int &e){
if(i<0)
return false;
if(i==0)
e=L->data;
return true;
int j=1; //j=1开始的长度
DLNode *p;
p=L;
if(p==NULL)
return false;
while(p!=NULL&&j<i)//
{
p=p->next;
j++;
}
e=p->data;
return true;
}
//双向链表按值查找---通过遍历实现---O(n)
int DLocateElem(DLinkList L,int e){
int j=1;
DLNode *p;
p=L->next;
while(p!=NULL&&p->data!=e){//
p=p->next;
j++;
printf("%d ",j);
}
if(p==NULL)
return 0;
return (j);
}
5.双向链表完整代码:
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
//双向链表的类型定义
typedef struct DLNode{
int data;
struct DLNode *prior,*next;
}DLNode,*DLinkList;
//双向链表的初始化
bool InitDLinkList(DLinkList &L){
L=(DLNode*)malloc(sizeof(DLNode)); //分配一个头结点
if(L==NULL)
return false; //内存分配失败
L->prior=NULL; //为空
L->next=NULL; //为空
return true;
}
//头插法建立双向链表
DLinkList DList_HeadInsert(DLinkList &L){
int x;
L=(DLNode*)malloc(sizeof(DLNode));
if(L==NULL)
return false;
L->next=NULL;
L->prior=NULL;
scanf("%d",&x);
while(x!=9999){
DLNode *s=(DLNode*)malloc(sizeof(DLNode));
if(s==NULL)
return false;
s->data=x;
s->next=L->next;
if(L->next!=NULL)
L->next->prior=s;
s->prior=L;
L->next=s;
scanf("%d",&x);
}
return L;
}
//尾插法建立双向链表
DLinkList DList_TailInsert(DLinkList &L){
int x;
L=(DLNode*)malloc(sizeof(DLNode));
L->next=NULL;
L->prior=NULL;
scanf("%d",&x);
DLNode *p;
p=L;
while(x!=9999){
DLNode *s=(DLNode*)malloc(sizeof(DLNode));
s->data=x;
p->next=s;
s->prior=p;
p=s;
scanf("%d",&x);
}
p->next=NULL;
return L;
}
//双链表的销毁
void DestoryDList(DLinkList &L)
{
DLNode *p,*q;
p=L;
q=p->next;
while(q!=NULL){
free(p);
p=q;
q=p->next;
}
free(p); //释放头结点
}
//双向链表的清空
bool ClearDLinkList(DLinkList &L){
if(L==NULL)
return false;
DLNode *p;
p=L->next;
while(p!=NULL){
L=p->next;
if(p->next!=NULL)
p->next->prior=L;
free(p);
p=L->next;
}
L->next=NULL;
return true;
}
//判断带头结点的双链表是否为空
bool Empty(DLinkList L){
if(L->next==NULL)
return true;
else
return false;
}
//求双向链表的长度
int DLinkListLen(DLinkList L){
if(L==NULL)
return false;
int j=0;
DLNode *p;
p=L;
while(p->next!=NULL){
p=p->next;
j++;
}
return (j);
}
//查找第i元素返回其值---通过遍历实现---O(n)
bool GetElem(DLinkList L,int i,int &e){
if(i<0)
return false;
if(i==0)
e=L->data;
return true;
int j=1; //j=1开始的长度
DLNode *p;
p=L;
if(p==NULL)
return false;
while(p!=NULL&&j<i)//
{
p=p->next;
j++;
}
e=p->data;
return true;
}
//双向链表按值查找---通过遍历实现---O(n)
int DLocateElem(DLinkList L,int e){
int j=1;
DLNode *p;
p=L->next;
while(p!=NULL&&p->data!=e){//
p=p->next;
j++;
printf("%d ",j);
}
if(p==NULL)
return 0;
return (j);
}
//双向链表的遍历(打印) 后向遍历 前向遍历
/*后向遍历:while(p!=NULL){ p=p->next; }
前向遍历:while(p!=NULL){ p=p->prior; }
前向遍历(不包括头结点):while(p->prior!=NULL) {p=p->prior; }
*/
void printfDLinkList(DLinkList &L){
if(L==NULL)
return ;
DLNode *p=L->next;
while(p!=NULL){
printf("%d\n",p->data);
p=p->next;//后向遍历
}
return;
}
//p结点后插入s结点
bool InsertNextNode(DLNode *p,DLNode *s){
if(p==NULL||s==NULL) //参数非法
return false;
s->next=p->next; //1
if(p->next!=NULL) //插入的那个点->next不为空
p->next->prior=s;//2
s->prior=p; //3
p->next=s; //4
return true;
//先写后两个箭头
//边界插入到最后一个位置if(p->next=NULL)
}
//删除p的后继结点q
bool DeleteNextDNode(DLNode *p){
DLNode *q=p->next;
if(p==NULL) return false;
if(q==NULL) return false;
q->next=p->next; //1
if(q->next!=NULL){ 删除的那个点->next不为空
q->next->prior=p; //2
}
free(p); //3
return true;
//边界:删除最后一个结点 if(q->next=NULL)
}
void main(){
DLinkList L,s;
InitDLinkList(L);
DList_TailInsert(L);
int a= DLinkListLen(L);
printf("双向链表的长度为=%d\n",a);
printfDLinkList(L);
printf("位序为:%d\n",DLocateElem(L,5));
int e;
if(GetElem(L,2,e)==1)
printf("yes\n");
else
printf("no found");
}