目录
- 初始化双链表
- 头插法建立双链表
- 尾插法建立双链表
- 查找第一个值域为e的元素序号
- 判断双链表是否为空
- 在双链表第i个位置插入值为e的元素
- 在双链表L中删除第i个结点
- 输出双链表
- 求双链表中第i个元素值
- 求双链表的长度
- 销毁双链表
- 主函数
- 双链表的基本运算的算法
-
初始化双链表
//初始化线性表
void InitList(DLinkNode *&L)
{
//创建头结点
L=(DLinkNode *)malloc(sizeof(DLinkNode));
L->next=L->prior=NULL;
}
-
头插法建立双链表
//采用头插法建立双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
{
DLinkNode *s;
//创建头结点
L=(DLinkNode *)malloc(sizeof(DLinkNode));
//前后指针域置为NULL
L->prior=L->next=NULL;
//循环建立数据结点
for(int i=0;i<n;i++)
{
//创建数据结点s
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=a[i];
//将s结点插入到原开始结点之前,头节点之后
s->next=L->next;
//若L存在数据结构,修改L->next的前驱指针
if(L->next!=NULL)
L->next->prior=s;
L->next=s;
s->prior=L;
}
}
-
尾插法建立双链表
//采用尾插法建立双链表
void CreateListR(DLinkNode *&L,ElemType a[],int n)
{
DLinkNode *s,*r;
//创建头结点
L=(DLinkNode *)malloc(sizeof(DLinkNode));
L->prior=L->next=NULL;
//r始终指向尾节点,开始时指向头结点
r=L;
//循环建立数据结点
for(int i=0;i<n;i++)
{
//创建数据结点s
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=a[i];
//将s结点插入到r结点之后
r->next=s;
s->prior=r;
//r指向尾结点
r=s;
}
//尾结点的next置为NULL
r->next==NULL;
}
-
查找第一个值域为e的元素序号
//查找第一个值域为e的元素序号
int LocateElem(DLinkNode *L,ElemType e)
{
int i=1;
//p指向首结点,i置为1(即首结点的序号为1)
DLinkNode *p=L->next;
//查找data值为e的结点,其序号为i
while(p!=NULL&&p->data!=e)
{
i++;
p=p->next;
}
if(p==NULL)
//不存在值为e的结点,返回0
return(0);
else
//存在值为e的结点,返回逻辑序号
return(i);
}
-
判断双链表是否为空
//判断线性表是否为空
int ListEmpty(DLinkNode *L)
{
return(L->next==NULL);
}
-
在双链表第i个位置插入值为e的元素
//在双链表L的第i个位置插入值为e的结点
int ListInsert(DLinkNode *&L,int i,ElemType e)
{
//p指向头结点,j设为0
int j=0;
DLinkNode *p=L,*s;
//i错误时返回false
if(i<0)
return false;
//查找第i-1个结点
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
//未找到第i-1个结点,返回false
if(p==NULL)
return false;
//找到第i-1个结点
else
{
//创建新结点s
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=e;
//在p结点之后插入s结点
s->next=p->next;
//若p结点存在后继结点,修改其前驱结点
if(p->next!=NULL)
p->next->prior=s;
s->prior=p;
p->next=s;
return true;
}
}
-
在双链表L中删除第i个结点
//在双链表L中删除第i个结点
int ListDelete(DLinkNode*&L,int i,ElemType &e)
{
//p指向头结点,j置为0
int j=0;
DLinkNode *p=L,*q;
//i错误返回false
if(i<=0)
return false;
//查找第i-1个结点
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
//未找到第i-1个结点
if(p==NULL)
return false;
//找到第i-1个结点(由p指向它)
else
{
//q指向第i个结点
q=p->next;
//当不存在第i个结点时返回false
if(q==NULL)
return false;
//储存即将删除的结点到e中
e=q->data;
//从双链表中删除结点q
p->next=q->next;
//若q结点存在后继结点,修改其前驱指针
if(q->next!=NULL)
q->next->prior=p;
free(q);
return true;
}
}
-
输出双链表
//输出线性表
void DispList(DLinkNode *L)
{
DLinkNode *p=L->next;
while(p!=NULL)
{
printf("%c",p->data);
p=p->next;
}
printf("\n");
}
-
求双链表中第i个元素值
//求线性表中第i个元素值
int GetElem(DLinkNode*L,int i,ElemType&e)
{
int j=0;
//p指向头结点,j置为0(即头结点的序号为0)
DLinkNode*p=L;
//若i错误返回0
if(i<=0)
return false;
//找第i个结点p
while(j<i&&p!=NULL)
{
j++;
p=p->next;
}
//不存在第i个数据结点,返回false
if(p==NULL)
return false;
//存在第i个数据结点,返回true
else
{
e=p->data;
return true;
}
}
-
求双链表的长度
//求双链表长度
int ListLength(DLinkNode*L)
{
//p指向头结点,i置为0
int i=0;
DLinkNode*p=L;
//找尾结点
while(p->next!=NULL)
{
//i对应结点p的序号
i++;
p=p->next;
}
return(i);
}
-
销毁双链表
//销毁线性表
void DestroyList(DLinkNode*&L)
{
//pre指向结点p的前驱结点
DLinkNode*pre=L,*p=L->next;
//扫描单链表L
while(p!=NULL)
{
//释放pre结点
free(pre);
//pre、p同步后移一个结点
pre=p;
p=pre->next;
}
//循环结束时p为NULL,pre指向尾结点,释放它
free(pre);
}
-
主函数
int main()
{
int i,n=10;
DLinkNode *L;
ElemType e,a[10];
printf("请输入10个字符:\n");
for(i=0;i<n;i++)
{
scanf("%c",&a[i]);
}
//调用InitList()初始化线性表
printf("<1>初始化双链表\n");
InitList(L);
printf("<2>初始化双链表成功!\n");
//调用DreateListF()头插法建立双链表
printf("<3>用头插法创建双链表:\n");
CreateListF(L,a,n);
//调用DispList()输出双链表
DispList(L);
//调用DreateListR()尾插法建立双链表
printf("<4>用尾插法创建双链表:\n");
CreateListR(L,a,n);
//调用DispList()输出双链表
DispList(L);
//用ListEmpty()判断双链表是否为空
printf("<5>该双链表为%s\n",ListEmpty(L)?"空":"非空");
//调用LocateElem()查找第一个值域为e的元素序号
printf("<6>在双链表中第一个元素值为o的元素序号为:%c\n", LocateElem(L,'o'));
//调用ListInsert()插入元素值
printf("<7>在双链表第3个元素中插入s:\n");
ListInsert(L,3,'s');
//调用DispList()输出双链表
DispList(L);
//调用ListDelete()删除双链表中第6个元素
printf("<8>删除双链表中第6个元素\n");
ListDelete(L,6,e);
//调用DispList()输出双链表
DispList(L);
//调用ListLength()求线性表长度
printf("<9>该线性表的长度为%d\n",ListLength(L));
//调用GetElem()查找线性表中第i个元素值
printf("<10>线性表中第5个元素值为:%c\n",GetElem(L,5,e));
//调用DispList()输出双链表
DispList(L);
//调用DestroyList()销毁线性表
printf("<11>销毁线性表:\n");
DestroyList(L);
printf("<12>销毁成功!");
}
-
双链表的基本运算的算法
#include<stdio.h>
#include<malloc.h>
//定义语句类型
typedef char ElemType;
//声明DLinkNode节点类型
typedef struct DNode
{
//存放元素值
ElemType data;
//指向前驱结点
struct DNode *prior;
//指向后驱结点
struct DNode *next;
}DLinkNode; //双链表的结点类型
//初始化线性表
void InitList(DLinkNode *&L)
{
//创建头结点
L=(DLinkNode *)malloc(sizeof(DLinkNode));
L->next=L->prior=NULL;
}
//采用头插法建立双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
{
DLinkNode *s;
//创建头结点
L=(DLinkNode *)malloc(sizeof(DLinkNode));
//前后指针域置为NULL
L->prior=L->next=NULL;
//循环建立数据结点
for(int i=0;i<n;i++)
{
//创建数据结点s
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=a[i];
//将s结点插入到原开始结点之前,头节点之后
s->next=L->next;
//若L存在数据结构,修改L->next的前驱指针
if(L->next!=NULL)
L->next->prior=s;
L->next=s;
s->prior=L;
}
}
//采用尾插法建立双链表
void CreateListR(DLinkNode *&L,ElemType a[],int n)
{
DLinkNode *s,*r;
//创建头结点
L=(DLinkNode *)malloc(sizeof(DLinkNode));
L->prior=L->next=NULL;
//r始终指向尾节点,开始时指向头结点
r=L;
//循环建立数据结点
for(int i=0;i<n;i++)
{
//创建数据结点s
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=a[i];
//将s结点插入到r结点之后
r->next=s;
s->prior=r;
//r指向尾结点
r=s;
}
//尾结点的next置为NULL
r->next==NULL;
}
//查找第一个值域为e的元素序号
int LocateElem(DLinkNode *L,ElemType e)
{
int i=1;
//p指向首结点,i置为1(即首结点的序号为1)
DLinkNode *p=L->next;
//查找data值为e的结点,其序号为i
while(p!=NULL&&p->data!=e)
{
i++;
p=p->next;
}
if(p==NULL)
//不存在值为e的结点,返回0
return(0);
else
//存在值为e的结点,返回逻辑序号
return(i);
}
//判断线性表是否为空
int ListEmpty(DLinkNode *L)
{
return(L->next==NULL);
}
//在双链表L的第i个位置插入值为e的结点
int ListInsert(DLinkNode *&L,int i,ElemType e)
{
//p指向头结点,j设为0
int j=0;
DLinkNode *p=L,*s;
//i错误时返回false
if(i<0)
return false;
//查找第i-1个结点
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
//未找到第i-1个结点,返回false
if(p==NULL)
return false;
//找到第i-1个结点
else
{
//创建新结点s
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=e;
//在p结点之后插入s结点
s->next=p->next;
//若p结点存在后继结点,修改其前驱结点
if(p->next!=NULL)
p->next->prior=s;
s->prior=p;
p->next=s;
return true;
}
}
//在双链表L中删除第i个结点
int ListDelete(DLinkNode*&L,int i,ElemType &e)
{
//p指向头结点,j置为0
int j=0;
DLinkNode *p=L,*q;
//i错误返回false
if(i<=0)
return false;
//查找第i-1个结点
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
//未找到第i-1个结点
if(p==NULL)
return false;
//找到第i-1个结点(由p指向它)
else
{
//q指向第i个结点
q=p->next;
//当不存在第i个结点时返回false
if(q==NULL)
return false;
//储存即将删除的结点到e中
e=q->data;
//从双链表中删除结点q
p->next=q->next;
//若q结点存在后继结点,修改其前驱指针
if(q->next!=NULL)
q->next->prior=p;
free(q);
return true;
}
}
//输出线性表
void DispList(DLinkNode *L)
{
DLinkNode *p=L->next;
while(p!=NULL)
{
printf("%c",p->data);
p=p->next;
}
printf("\n");
}
//求线性表中第i个元素值
int GetElem(DLinkNode*L,int i,ElemType&e)
{
int j=0;
//p指向头结点,j置为0(即头结点的序号为0)
DLinkNode*p=L;
//若i错误返回0
if(i<=0)
return false;
//找第i个结点p
while(j<i&&p!=NULL)
{
j++;
p=p->next;
}
//不存在第i个数据结点,返回false
if(p==NULL)
return false;
//存在第i个数据结点,返回true
else
{
e=p->data;
return true;
}
}
//求单链表长度
int ListLength(DLinkNode*L)
{
//p指向头结点,i置为0
int i=0;
DLinkNode*p=L;
//找尾结点
while(p->next!=NULL)
{
//i对应结点p的序号
i++;
p=p->next;
}
return(i);
}
//销毁线性表
void DestroyList(DLinkNode*&L)
{
//pre指向结点p的前驱结点
DLinkNode*pre=L,*p=L->next;
//扫描单链表L
while(p!=NULL)
{
//释放pre结点
free(pre);
//pre、p同步后移一个结点
pre=p;
p=pre->next;
}
//循环结束时p为NULL,pre指向尾结点,释放它
free(pre);
}
int main()
{
int i,n=10;
DLinkNode *L;
ElemType e,a[10];
printf("请输入10个字符:\n");
for(i=0;i<n;i++)
{
scanf("%c",&a[i]);
}
//调用InitList()初始化线性表
printf("<1>初始化双链表\n");
InitList(L);
printf("<2>初始化双链表成功!\n");
//调用DreateListF()头插法建立双链表
printf("<3>用头插法创建双链表:\n");
CreateListF(L,a,n);
//调用DispList()输出双链表
DispList(L);
//调用DreateListR()尾插法建立双链表
printf("<4>用尾插法创建双链表:\n");
CreateListR(L,a,n);
//调用DispList()输出双链表
DispList(L);
//用ListEmpty()判断双链表是否为空
printf("<5>该双链表为%s\n",ListEmpty(L)?"空":"非空");
//调用LocateElem()查找第一个值域为e的元素序号
printf("<6>在双链表中第一个元素值为o的元素序号为:%c\n", LocateElem(L,'o'));
//调用ListInsert()插入元素值
printf("<7>在双链表第3个元素中插入s:\n");
ListInsert(L,3,'s');
//调用DispList()输出双链表
DispList(L);
//调用ListDelete()删除双链表中第6个元素
printf("<8>删除双链表中第6个元素\n");
ListDelete(L,6,e);
//调用DispList()输出双链表
DispList(L);
//调用ListLength()求线性表长度
printf("<9>该线性表的长度为%d\n",ListLength(L));
//调用GetElem()查找线性表中第i个元素值
printf("<10>线性表中第5个元素值为:%c\n",GetElem(L,5,e));
//调用DispList()输出双链表
DispList(L);
//调用DestroyList()销毁线性表
printf("<11>销毁线性表:\n");
DestroyList(L);
printf("<12>销毁成功!");
}