前言
对双线性链表进行一些基础操作
一、初始化双线性链表
利用尾插法建立一个双向链表
代码示例
void InitDList(DLinkList*L)
{
(*L)=(DLNode*)malloc(sizeof(DLNode));
(*L)->pre=NULL;
(*L)->next=NULL;
(*L)->data=0;
if((*L)==NULL)
{
printf("DLinkList error!\n");
}
int num;
scanf("%d",&num);
DLNode*p;//建立一个存储当前数据的节点
DLNode*last=(*L);//建立一个指向表尾节点的指针
while(num!=-1)//利用后插法输入初始的链表数据
{
p=(DLNode*)malloc(sizeof(DLNode));
p->data=num;
p->next=NULL;
last->next=p;//原始表尾节点的后向指针指向当前输入数据节点
p->pre=last;//当前输入数据节点的前向指针指向原始表尾
last=last->next;//尾节点指针再次指向表尾
scanf("%d",&num);
}
last->next=NULL;
}
二、双向链表的节点插入
插入节点的位置要分情况讨论,第一个位置,中间位置,最后一个位置
void InsertDList(DLinkList*L,int InsertSite,int value)
{
int len=Get_length(*L);//获取当前链表的长度
int flag=1;
DLNode*p=(DLNode*)malloc(sizeof(DLNode));//定义一个存储插入数据的节点
p->next=NULL;
p->pre=NULL;
p->data=value;
if(InsertSite<1||InsertSite>(len+1))
{
flag=0;//插入位置出现错误
}
if(flag==0)
{
printf("插入错误!\n");
}else{
if(InsertSite==1)//分情况讨论插入位置
{
p->next=(*L);
(*L)->pre=p;
(*L)=p;
}else if(InsertSite==len+1)
{
DLNode*q=(*L);//定义一个指针指向表尾
while(q->next)
{
q=q->next;
}
q->next=p;
p->pre=q;
}else{
DLNode*q=(*L);
int i;
for(i=1;i<InsertSite-1;i++)
{
q=q->next;
}
DLNode*qNext=q->next;
p->next=qNext;//先将要插入节点与后向节点建立联系
qNext->pre=p;
q->next=p;
p->pre=q;
}
}
}
二、双向链表的节点删除
按照位置删除
void DeleDList(DLinkList*L,int DeleSite)
{
int flag=1;
int len=Get_length(*L);
if(DeleSite<1||DeleSite>len)
{
flag=0;
}
if(flag==0)
{
printf("删除错误!\n");
}else{
if(DeleSite==1)
{
(*L)=(*L)->next;
(*L)->pre=NULL;
}else if(DeleSite==len){
DLNode*q=(*L);
while(q->next)
{
q=q->next;
}
q=q->pre;
q->next=NULL;
}else{
DLNode*q=(*L);
int i;
for(i=1;i<DeleSite-1;i++)
{
q=q->next;
}
DLNode*qNext=q->next;
DLNode*p=qNext->next;
q->next=p;
p->pre=q;
}
}
}
按照数值删除
void DeleDList_value(DLinkList*L,int value)
{
int flag=0;
int len=Get_length(*L);
DLNode*p=(*L);
int count=0;
int cou[len];
int i;
for(i=1;i<=len;i++)
{
if(p->data==value)
{
flag=1;
cou[count]=i;
count++;
}
p=p->next;
}
if(flag==0)
{
printf("删除错误!\n");
}else{
for(i=0;i<count;i++)
{
DeleDList(L,cou[i]-i);
}
}
}
三、双向链表的节点修改
按照位置修改
void ChangeDList_site(DLinkList*L,int Change_Site,int value)
{
int flag=1;
int len=Get_length(*L);
if(Change_Site<1||Change_Site>len)
{
flag=0;
}
if(flag==0)
{
printf("修改错误!\n");
}else{
DLNode*p=(*L);
int i;
for(i=1;i<Change_Site;i++)
{
p=p->next;
}
p->data=value;
}
}
按照数值修改
void ChangeDList_value(DLinkList*L,int Change_value,int num)
{
int flag=0;
int len=Get_length(*L);
int i;
int count;
int cou[len];
DLNode*p=(*L);
for(i=1;i<=len;i++)
{
if(p->data==Change_value)
{
flag=1;
cou[count]=i;
count++;
}
p=p->next;
}
if(flag==0)
{
printf("修改错误!\n");
}else
{
for(i=0;i<count;i++)
{
ChangeDList_site(L,cou[i],num);
}
}
}
四、双向链表的打印
#include<stdio.h>
#include<stdlib.h>
typedef struct DLNode{
int data;
struct DLNode *pre,*next;
}DLNode,*DLinkList;
void InitDList(DLinkList*L);
void OutputDList(DLinkList L);
void InsertDList(DLinkList*L,int InsertSite,int value);
void DeleDList(DLinkList*L,int DeleSite);
void DeleDList_value(DLinkList*L,int value);
void ChangeDList_site(DLinkList*L,int Change_Site,int value);
void ChangeDList_value(DLinkList*L,int Change_value,int num);
int Get_length(DLinkList L);
int main()
{
DLinkList L;
InitDList(&L);
OutputDList(L);
InsertDList(&L,6,5);
OutputDList(L);
DeleDList(&L,6);//按位删除链表中的节点
OutputDList(L);
DeleDList_value(&L,2);//按值删除链表中的节点
OutputDList(L);
ChangeDList_site(&L,5,99);//按位修改
OutputDList(L);
ChangeDList_value(&L,99,88);//按值修改
OutputDList(L);
return 0;
}
void InitDList(DLinkList*L)
{
(*L)=(DLNode*)malloc(sizeof(DLNode));
(*L)->pre=NULL;
(*L)->next=NULL;
(*L)->data=0;
if((*L)==NULL)
{
printf("DLinkList error!\n");
}
int num;
scanf("%d",&num);
DLNode*p;//建立一个存储当前数据的节点
DLNode*last=(*L);//建立一个指向表尾节点的指针
while(num!=-1)//利用后插法输入初始的链表数据
{
p=(DLNode*)malloc(sizeof(DLNode));
p->data=num;
p->next=NULL;
last->next=p;//原始表尾节点的后向指针指向当前输入数据节点
p->pre=last;//当前输入数据节点的前向指针指向原始表尾
last=last->next;//尾节点指针再次指向表尾
scanf("%d",&num);
}
last->next=NULL;
}
void OutputDList(DLinkList L)
{
DLNode*p=L;//不带头节点
while(p)
{
printf("%d\t",p->data);
p=p->next;
}
printf("\n");
int len=Get_length(L);
DLNode*q=L;
int i;
for(i=1;i<len;i++)
{
q=q->next;
}
while(q)
{
printf("%d\t",q->data);
q=q->pre;
}
printf("\n");
}
void InsertDList(DLinkList*L,int InsertSite,int value)
{
int len=Get_length(*L);//获取当前链表的长度
int flag=1;
DLNode*p=(DLNode*)malloc(sizeof(DLNode));//定义一个存储插入数据的节点
p->next=NULL;
p->pre=NULL;
p->data=value;
if(InsertSite<1||InsertSite>(len+1))
{
flag=0;//插入位置出现错误
}
if(flag==0)
{
printf("插入错误!\n");
}else{
if(InsertSite==1)//分情况讨论插入位置
{
p->next=(*L);
(*L)->pre=p;
(*L)=p;
}else if(InsertSite==len+1)
{
DLNode*q=(*L);//定义一个指针指向表尾
while(q->next)
{
q=q->next;
}
q->next=p;
p->pre=q;
}else{
DLNode*q=(*L);
int i;
for(i=1;i<InsertSite-1;i++)
{
q=q->next;
}
DLNode*qNext=q->next;
p->next=qNext;//先将要插入节点与后向节点建立联系
qNext->pre=p;
q->next=p;
p->pre=q;
}
}
}
int Get_length(DLinkList L)
{
int len=0;
while(L)
{
len++;
L=L->next;
}
printf("length=%d\n",len);
return len;
}
void DeleDList(DLinkList*L,int DeleSite)
{
int flag=1;
int len=Get_length(*L);
if(DeleSite<1||DeleSite>len)
{
flag=0;
}
if(flag==0)
{
printf("删除错误!\n");
}else{
if(DeleSite==1)
{
(*L)=(*L)->next;
(*L)->pre=NULL;
}else if(DeleSite==len){
DLNode*q=(*L);
while(q->next)
{
q=q->next;
}
q=q->pre;
q->next=NULL;
}else{
DLNode*q=(*L);
int i;
for(i=1;i<DeleSite-1;i++)
{
q=q->next;
}
DLNode*qNext=q->next;
DLNode*p=qNext->next;
q->next=p;
p->pre=q;
}
}
}
void DeleDList_value(DLinkList*L,int value)
{
int flag=0;
int len=Get_length(*L);
DLNode*p=(*L);
int count=0;
int cou[len];
int i;
for(i=1;i<=len;i++)
{
if(p->data==value)
{
flag=1;
cou[count]=i;
count++;
}
p=p->next;
}
if(flag==0)
{
printf("删除错误!\n");
}else{
for(i=0;i<count;i++)
{
DeleDList(L,cou[i]-i);
}
}
}
void ChangeDList_site(DLinkList*L,int Change_Site,int value)
{
int flag=1;
int len=Get_length(*L);
if(Change_Site<1||Change_Site>len)
{
flag=0;
}
if(flag==0)
{
printf("修改错误!\n");
}else{
DLNode*p=(*L);
int i;
for(i=1;i<Change_Site;i++)
{
p=p->next;
}
p->data=value;
}
}
void ChangeDList_value(DLinkList*L,int Change_value,int num)
{
int flag=0;
int len=Get_length(*L);
int i;
int count;
int cou[len];
DLNode*p=(*L);
for(i=1;i<=len;i++)
{
if(p->data==Change_value)
{
flag=1;
cou[count]=i;
count++;
}
p=p->next;
}
if(flag==0)
{
printf("修改错误!\n");
}else
{
for(i=0;i<count;i++)
{
ChangeDList_site(L,cou[i],num);
}
}
}
总结
双向链表与单向链表类似,区别在于多了一个前向指针,可以双向访问节点的前后;