03 线性表的链式存储
线性表的链式存储
目录
一、线性表的链式结构分类
1、单链表 Link
1.建立单链表
引用的用处实际上就是使传入变量的本身可以被修改。
①传入引用型指针变量L , 数组a, 长度n
②定义一个指向结构体的指针变量s。
③初始化空链表L;
④循环:
1.为指针s分配新的结点,并赋予数组的对应值,
2.将s插入至头结点之后。
s->next = L->next;
L->next = s;尾插法
①传入引用型指针变量L , 数组a, 长度n
②定义两个指向结构体的指针变量s,r。
③初始化空链表L;
④令r = L,等价于尾结点。
④循环:
1.为指针s分配新的结点,并赋予数组的对应值;
2.将s插入在尾结点r之后;
3.令r = s,重新成为尾结点。
⑤ r->next = NULL;
/*头插法*/
void CreateListF(LinkNode *&L, ElemType a[], int n){
LinkNode *s;
L = (LinkNode *)malloc(sizeof(LinkNode));
L->next = NULL;
for(int i = 0; i < n; i++){
s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = a[i];
s->next = L->next;
L->next = s;
}
}
/*尾插法*/
void CreateListR(LinkNode *&L, ElemType a[], int n){
LinkNode *s,*r;
L = (LinkNode *)malloc(sizeof(LinkNode));
L->next = NULL;
r = L;
for(int i = 0; i < n; i++){
s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = a[i];
r->next = s;
r = s;
}
r->next = NULL;
}
2.初始化链表
void InitList(ListNode *&L){
L = (LinkNode *)malloc(sizeof(LinkNode));
L->next = NULL;
}
3.销毁链表
①传入引用型指针变量L
②定义指向结构体的指针pre,并使其指向L;定义指向结构体的指针p,使其指向pre->next;
③循环:只要p!=NULL
1.释放p的前一个结点pre;
2.pre=p;
p=pre->next;
④释放最后一个.pre
void DestroyList(LinkNode *&L){
LinkNode *pre = L, *P = pre->next;
while(P != NULL){
free(pre);
pre = p;
p = pre->next;
}
free(pre);
}
4.是否为空
bool ListEmpty(LinkNode *L)
{
return(L->next==NULL);//判断下一个指向的结构体指针是否为空
}
5.返回长度
①传入结构体指针L
②定义指向L的结构体指针p
③循环遍历p->next != NULL,i++
④返回 i
int ListLength(LinkNode *L)
{
LinkNode *p=L;
int i=0;
while (p->next!=NULL)/
{
i++;
p = p->next;
}
return i;//比实际结点数少1,因为有空头结点
}
6.输出单链表
void DispList(LinkNode *L)
{
LinkNode *p = L->next;
while (p!=NULL)
{ printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
7.获取第i个元素值
bool GetElem(LinkNode *L, int i, ElemType &e){
int j = 0;
LinkNode *p =L;
if(i<=0)
return false;
while(j < i && p != NULL){
j++;
p = p->next;
}
if(p == NULL)
return false;
else{
e = p->data;
return true;
}
}
8.确认某个元素的位置
int LocateElem(LinkNode *L,ElemType e)
{
LinkNode *p=L->next;
int n = 1;
while (p!=NULL && p->data!=e)
{ p = p->next;
n++;
}
if (p==NULL)
return 0;
else
return n;
}
9.第i个位置插入元素
①判断 i
②查到第 i-1个 结点p
③插入至 p 后
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
int j = 0;
LinkNode *p = L,*s;
if(i<=0)
return false; //i错误返回假
while(j<i-1 && p!=NULL) //查找第i-1个结点p
{
j++;
p=p->next;
}
if (p == NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点*p
{
s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
s->data = e;
s->next = p->next; //将s结点插入到结点p之后
p->next = s;
return true;
}
}
10.删除第i个元素
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
int j = 0;
LinkNode *p = L,*q;
if (i <= 0)
return false; //i错误返回假
while (j < i-1 && p!=NULL) //查找第i-1个结点
{
j++;
p=p->next;
}
if (p == NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点p
{
q = p->next; //q指向要删除的结点
if(q==NULL)
return false; //若不存在第i个结点,返回false
e = q->data;
p->next = q->next; //从单链表中删除q结点
free(q); //释放q结点
return true;
}
}
-
全部代码
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next; //指向后继结点
} LinkNode;
void CreateListF(LinkNode *&L,ElemType a[],int n);
void CreateListR(LinkNode *&L,ElemType a[],int n);
void InitList(LinkNode *&L);
void DestroyList(LinkNode *&L);
bool ListEmpty(LinkNode *L);
int ListLength(LinkNode *L);
void DispList(LinkNode *L);
bool GetElem(LinkNode *L, int i, ElemType &e);
int LocateElem(LinkNode *L, ElemType e);
bool ListInsert(LinkNode *&L,int i,ElemType e);
bool ListDelete(LinkNode *&L,int i);
void CreateListF(LinkNode *&L,ElemType a[],int n)
//头插法建立单链表
{
LinkNode *s;
L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next=NULL;
for (int i=0;i<n;i++)
{
s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
s->data=a[i];
s->next=L->next; //将结点s插在原开始结点之前,头结点之后
L->next=s;
}
}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//尾插法建立单链表
{
LinkNode *s,*r;
L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next=NULL;
r=L; //r始终指向终端结点,开始时指向头结点
for (int i=0;i<n;i++)
{
s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
s->data=a[i];
r->next=s; //将结点s插入结点r之后
r=s;
}
r->next=NULL; //终端结点next域置为NULL
}
void InitList(LinkNode *&L)
{
L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next=NULL;
}
void DestroyList(LinkNode *&L)
{
LinkNode *pre=L,*p=pre->next;
while (p!=NULL)
{ free(pre);
pre=p;
p=pre->next;
}
free(pre); //此时p为NULL,pre指向尾结点,释放它
}
bool ListEmpty(LinkNode *L)
{
return(L->next==NULL);
}
int ListLength(LinkNode *L)
{
LinkNode *p=L;int i=0;
while (p->next!=NULL)
{ i++;
p=p->next;
}
return(i);
}
void DispList(LinkNode *L)
{
LinkNode *p=L->next;
while (p!=NULL)
{ printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
int j=0;
LinkNode *p=L;
if (i<=0) return false; //i错误返回假
while (j<i && p!=NULL)
{ j++;
p=p->next;
}
if (p==NULL) //不存在第i个数据结点
return false;
else //存在第i个数据结点
{ e=p->data;
return true;
}
}
int LocateElem(LinkNode *L,ElemType e)
{
LinkNode *p=L->next;
int n=1;
while (p!=NULL && p->data!=e)
{ p=p->next;
n++;
}
if (p==NULL)
return(0);
else
return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
int j=0;
LinkNode *p=L,*s;
if (i<=0) return false; //i错误返回假
while (j<i-1 && p!=NULL) //查找第i-1个结点p
{ j++;
p=p->next;
}
if (p==NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点*p
{ s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
s->data=e;
s->next=p->next; //将s结点插入到结点p之后
p->next=s;
return true;
}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
int j=0;
LinkNode *p=L,*q;
if (i<=0) return false; //i错误返回假
while (j<i-1 && p!=NULL) //查找第i-1个结点
{ j++;
p=p->next;
}
if (p==NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点p
{ q=p->next; //q指向要删除的结点
if (q==NULL)
return false; //若不存在第i个结点,返回false
e=q->data;
p->next=q->next; //从单链表中删除q结点
free(q); //释放q结点
return true;
}
}
int main()
{
LinkNode *lk;
ElemType a[6]= {5,8,7,2,4,9};
ElemType e;
int i,x,choice;
printf("第一步.创建单链表......\n");
CreateListF(lk, a, 6);
while(1){
printf("创建成功!请选择菜单执行相关操作\n");
printf(" 1.销毁单链表\n");
printf(" 2.判定单链表是否为空\n");
printf(" 3.求单链表的长度\n");
printf(" 4.输出单链表\n");
printf(" 5.求单链表第i个位置上的元素\n");
printf(" 6.查找单链表中元素e的位置\n");
printf(" 7.在单链表第i个位置插入元素\n");
printf(" 8.删除单链表第i个位置上的元素\n");
printf(" 0.退出\n");
printf(" 请输入你的选择:");
scanf("%d",&choice);
switch(choice)
{
case 0: exit(0);
case 1: DestroyList(lk);
printf("单链表销毁成功~~程序直接退出!!");
exit(0);
case 2: if(ListEmpty(lk))
printf("单链表为空!");
else
printf("单链表不为空!");
break;
case 3: printf("该单链表长度为%d\n",ListLength(lk));
break;
case 4: printf("输出单链表:\n");
DispList(lk);
break;
case 5: printf("请输入待查找元素的位置:");
scanf("%d",&i);
GetElem(lk, i, e);
printf("第%d个位置上的元素为%d",i,e);
break;
case 6: printf("请输入要查找的元素:");
scanf("%d",&x);
printf("%d元素在单链表的第%d个位置\n",x,LocateElem(lk,x));
break;
case 7: printf("请输入要插入位置和值(空格隔开):");
scanf("%d%d",&i,&x);
ListInsert(lk,i,x);
break;
case 8: printf("请输入要删除的位置");
scanf("%d",&i);
ListDelete(lk, i, e);
break;
}
printf("按任意键继续……");
getchar();getchar();
}
return 0;
}
2.循环链表 CLinkNode
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LinkNode;
//头插法建立循环单链表
void CreateListF(LinkNode *&L,ElemType a[],int n)
{
LinkNode *s;
int i;
L=(LinkNode *)malloc(sizeof(LinkNode));
L->next=NULL;
for (i=0;i<n;i++)
{
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=a[i];
s->next=L->next;
L->next=s;
}
/*令尾结点next指向头结点*/
s=L->next;
while (s->next!=NULL)//查找尾结点,由s指向它
s=s->next;
s->next=L;//尾结点next域指向头结点
}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//尾插法建立循环单链表
{
LinkNode *s,*r;
int i;
L=(LinkNode *)malloc(sizeof(LinkNode));
L->next=NULL;
r=L;//r始终指向终端结点,开始时指向头结点
for (i=0;i<n;i++)
{
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=a[i];
r->next=s;
r=s;
}
r->next=L;//尾结点next域指向头结点
}
void InitList(LinkNode *&L)
{
L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next=L;
}
void DestroyList(LinkNode *&L)
{
LinkNode *p=L,*q=p->next;
while (q!=L)
{
free(p);
p=q;
q=p->next;
}
free(p);
}
bool ListEmpty(LinkNode *L)
{
return(L->next==L);
}
int ListLength(LinkNode *L)
{
LinkNode *p=L;
int i=0;
while (p->next!=L)
{
i++;
p=p->next;
}
return(i);
}
void DispList(LinkNode *L)
{
LinkNode *p=L->next;
while (p!=L)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
int j=0;
LinkNode *p;
if (L->next!=L)//单链表不为空表时
{
if(i==1)
{
e=L->next->data;
return true;
}
else//i不为1时
{
p=L->next;
while (j<i-1 && p!=L)//j==i-1或者p==L时退出循环
{
j++;
p=p->next;
}
if (p==L)
return false;
else
{
e=p->data;
return true;
}
}
}
else//单链表为空表时
return false;
}
int LocateElem(LinkNode *L,ElemType e)
{
LinkNode *p=L->next;
int n=1;
while (p!=L && p->data!=e)
{
p=p->next;
n++;
}
if (p==L)
return(0);
else
return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
int j=0;
LinkNode *p = L, *s;
if(p->next == L || i == 1)//原单链表为空表或i==1时
{
s = (LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
s->data = e;
s->next = p->next;//将结点s插入到结点p之后
p->next = s;
return true;
}
else
{
p=L->next;
while (j<i-2 && p!=L)//第i-1个结点的序标为i-2
{
j++;
p=p->next;
}
if (p==L)//未找到第i-1个结点
return false;
else//找到第i-1个结点p
{
s=(LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
s->data=e;
s->next=p->next;//将结点s插入到结点p之后
p->next=s;
return true;
}
}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
int j=0;
LinkNode *p=L,*q;
if(p->next!=L)//原单链表不为空表时
{
if(i==1)//i==1时
{
q=L->next;//删除第1个结点
e=q->data;
L->next=q->next;
free(q);
return true;
}
else//i不为1时
{
p=L->next;
while (j<i-2 && p!=L)//第i-1个结点的序标为i-2
{
j++;
p=p->next;
}
if(p==L)//未找到第i-1个结点
return false;
else//找到第i-1个结点p
{
q=p->next;//q指向要删除的结点
e=q->data;
p->next=q->next;//从单链表中删除q结点
free(q);
return true;
}
}
}
else return false;
}
int main()
{
LinkNode *lk;
ElemType a[6]= {5,8,7,2,4,9};
ElemType e;
int i,x,choice;
printf("第一步.创建循环单链表......\n");
CreateListF(lk, a, 6);
while(1){
printf("创建成功!请选择菜单执行相关操作\n");
printf(" 1.销毁循环单链表\n");
printf(" 2.判定循环单链表是否为空\n");
printf(" 3.求循环单链表的长度\n");
printf(" 4.输出循环单链表\n");
printf(" 5.求循环单链表第i个位置上的元素\n");
printf(" 6.查找循环单链表中元素e的位置\n");
printf(" 7.在循环单链表第i个位置插入元素\n");
printf(" 8.删除循环单链表第i个位置上的元素\n");
printf(" 0.退出\n");
printf(" 请输入你的选择:");
scanf("%d",&choice);
switch(choice)
{
case 0: exit(0);
case 1: DestroyList(lk);
printf("单链表销毁成功~~程序直接退出!!");
exit(0);
case 2: if(ListEmpty(lk))
printf("单链表为空!");
else
printf("单链表不为空!");
break;
case 3: printf("该单链表长度为%d\n",ListLength(lk));
break;
case 4: printf("输出单链表:\n");
DispList(lk);
break;
case 5: printf("请输入待查找元素的位置:");
scanf("%d",&i);
GetElem(lk, i, e);
printf("第%d个位置上的元素为%d",i,e);
break;
case 6: printf("请输入要查找的元素:");
scanf("%d",&x);
printf("%d元素在单链表的第%d个位置\n",x,LocateElem(lk,x));
break;
case 7: printf("请输入要插入位置和值(空格隔开):");
scanf("%d%d",&i,&x);
ListInsert(lk,i,x);
break;
case 8: printf("请输入要删除的位置");
scanf("%d",&i);
ListDelete(lk, i, e);
break;
}
printf("按任意键继续……");
getchar();getchar();
}
return 0;
}
3.双链表 DLinkList
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct DNode//定义双链表结点类型
{
ElemType data;
struct DNode *prior;//指向前驱结点
struct DNode *next;//指向后继结点
} DLinkNode;
//头插法建双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
{
/* L、L->next*/
/* L、S、L->next*/
DLinkNode *s;
L = (DLinkNode *)malloc(sizeof(DLinkNode));
L->prior = L->next=NULL;//前驱后继初始化时均赋NULL
for(int i = 0; i < n; i++)
{
s = (DLinkNode *)malloc(sizeof(DLinkNode));
s->data = a[i];
s->next = L->next;//first
if (L->next != NULL)
L->next->prior = s;//second
L->next = s;//third
s->prior = L;//forth
}
}
//尾插法建双链表
void CreateListR(DLinkNode *&L,ElemType a[],int n)
{
/*r*/
/*r、s*/
DLinkNode *s, *r;
L = (DLinkNode *)malloc(sizeof(DLinkNode));
L->prior = L->next = NULL;//前驱后继初始化时均赋NULL
r = L;//r始终指向终端结点,开始时指向头结点
for(int i = 0; i < n; i++)
{
s = (DLinkNode *)malloc(sizeof(DLinkNode));
s->data = a[i];
r->next = s;//first
s->prior = r;//second
r = s;//third
}
r->next = NULL;//forth:尾结点next域置为NULL
}
void InitList(DLinkNode *&L)
{
L = (DLinkNode *)malloc(sizeof(DLinkNode));
L->prior = L->next = NULL;
}
void DestroyList(DLinkNode *&L)
{
DLinkNode *pre = L,*p = pre->next;
while (p!=NULL)
{
free(pre);
pre = p;
p = pre->next;
}
free(pre);
}
bool ListEmpty(DLinkNode *L)
{
return(L->next==NULL);
}
int ListLength(DLinkNode *L)
{
DLinkNode *p=L;
int i=0;
while (p->next!=NULL)
{
i++;
p=p->next;
}
return(i);
}
void DispList(DLinkNode *L)
{
DLinkNode *p=L->next;
while (p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
bool GetElem(DLinkNode *L,int i,ElemType &e)
{
int j=0;
DLinkNode *p=L;
if (i<=0)
return false;
while (j < i && p!=NULL)
{
j++;
p = p->next;
}
if (p==NULL)
return false;
else
{
e=p->data;
return true;
}
}
int LocateElem(DLinkNode *L,ElemType e)
{
int n=1;
DLinkNode *p=L->next;
while (p!=NULL && p->data!=e)
{
n++;
p=p->next;
}
if (p==NULL)
return(0);
else
return(n);
}
bool ListInsert(DLinkNode *&L, int i, ElemType e)
{
/* L、L->next*/
/* L、S、L->next*/
int j=0;
DLinkNode *p=L,*s;
if (i<=0)
return false;//i错误返回假
while (j<i-1 && p!=NULL)
{
j++;
p=p->next;
}
if (p==NULL)//未找到第i-1个结点
return false;
else//找到第i-1个结点p
{
s = (DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点s
s->data = e;
s->next = p->next;//first
if (p->next != NULL)
p->next->prior = s;//second
s->prior = p;//third
p->next = s;//forth
return true;
}
}
bool ListDelete(DLinkNode *&L,int i,ElemType &e)
{
/*注意找的是前驱,第i-1个结点*/
/*p、q*/
/*i-1、i*/
int j = 0;
DLinkNode *p = L,*q;
if (i<=0)
return false;
while (j < i-1 && p != NULL)
{
j++;
p = p->next;
}
if(p == NULL)//未找到第i-1个结点
return false;
else//找到第i-1个结点p
{
q = p->next;//q指向要删除的结点
if (q == NULL)
return false;//不存在第i个结点
e = q->data;
p->next = q->next;//从单链表中删除*q结点
if(p->next!=NULL)
p->next->prior = p;
free(q);
return true;
}
}
int main()
{
DLinkNode *lk;
ElemType a[6]= {5,8,7,2,4,9};
ElemType e;
int i,x,choice;
printf("第一步.创建双链表......\n");
CreateListF(lk, a, 6);
while(1){
printf("创建成功!请选择菜单执行相关操作\n");
printf(" 1.销毁双链表\n");
printf(" 2.判定双链表是否为空\n");
printf(" 3.求双链表的长度\n");
printf(" 4.输出双链表\n");
printf(" 5.求双链表第i个位置上的元素\n");
printf(" 6.查找双链表中元素e的位置\n");
printf(" 7.在双链表第i个位置插入元素\n");
printf(" 8.删除双链表第i个位置上的元素\n");
printf(" 0.退出\n");
printf(" 请输入你的选择:");
scanf("%d",&choice);
switch(choice)
{
case 0: exit(0);
case 1: DestroyList(lk);
printf("双链表销毁成功~~程序直接退出!!");
exit(0);
case 2: if(ListEmpty(lk))
printf("双链表为空!");
else
printf("双链表不为空!");
break;
case 3: printf("该双链表长度为%d\n",ListLength(lk));
break;
case 4: printf("输出双链表:\n");
DispList(lk);
break;
case 5: printf("请输入待查找元素的位置:");
scanf("%d",&i);
GetElem(lk, i, e);
printf("第%d个位置上的元素为%d",i,e);
break;
case 6: printf("请输入要查找的元素:");
scanf("%d",&x);
printf("%d元素在双链表的第%d个位置\n",x,LocateElem(lk,x));
break;
case 7: printf("请输入要插入位置和值(空格隔开):");
scanf("%d%d",&i,&x);
ListInsert(lk,i,x);
break;
case 8: printf("请输入要删除的位置");
scanf("%d",&i);
ListDelete(lk, i, e);
break;
}
printf("按任意键继续……");
getchar();getchar();
}
return 0;
}
4.循环双链表 CDLinkList
//循环双链表基本运算算法
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct DNode//定义双链表结点类型
{
ElemType data;
struct DNode *prior;//指向前驱结点
struct DNode *next;//指向后继结点
} DLinkNode;
//头插法建立循环双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
{
DLinkNode *s;
int i;
L = (DLinkNode *)malloc(sizeof(DLinkNode));
L->next = NULL;
for(i = 0; i < n; i++)
{
s = (DLinkNode *)malloc(sizeof(DLinkNode));
s->data = a[i];
s->next = L->next;//first
if (L->next != NULL)
L->next->prior = s;//second
L->next = s;//third
s->prior = L;//forth
}
s = L->next;
while (s->next!=NULL)//查找尾结点,使s指向它
s = s->next;
s->next = L;//first:使尾结点s的next域指向头结点
L->prior = s;//second:头结点的prior域指向尾结点
}
void CreateListR(DLinkNode *&L,ElemType a[],int n)
//尾插法建立循环双链表
{
DLinkNode *s,*r;
int i;
L = (DLinkNode *)malloc(sizeof(DLinkNode));
L->next=NULL;
r = L;//r始终指向尾结点,开始时指向头结点
for(i = 0; i < n; i++)
{
s = (DLinkNode *)malloc(sizeof(DLinkNode));
s->data = a[i];
r->next = s;//first
s->prior = r;//second
r = s;//third
}
r->next = L;//first:尾结点next域指向头结点
L->prior = r;//second:头结点的prior域指向尾结点
}
void InitList(DLinkNode *&L)
{
L = (DLinkNode *)malloc(sizeof(DLinkNode));
L->prior = L->next = L;
}
void DestroyList(DLinkNode *&L)
{
DLinkNode *p = L, *q = p->next;
while(q!=L)
{
free(p);
p = q;
q = p->next;
}
free(p);
}
bool ListEmpty(DLinkNode *L)
{
return(L->next==L);
}
int ListLength(DLinkNode *L)
{
DLinkNode *p = L;
int i = 0;
while (p->next!=L)
{
i++;
p = p->next;
}
return(i);
}
void DispList(DLinkNode *L)
{
DLinkNode *p = L->next;
while (p!=L)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
bool GetElem(DLinkNode *L, int i, ElemType &e)
{
int j = 0;
DLinkNode *p;
if (L->next != L)//双链表不为空表时
{
if (i==1)
{
e = L->next->data;
return true;
}
else//i不为1时
{
p = L->next;
while (j<i-1 && p!=L)
{
j++;
p = p->next;
}
if(p == L)
return false;
else
{
e = p->data;
return true;
}
}
}
else//双链表为空表时
return 0;
}
int LocateElem(DLinkNode *L,ElemType e)
{
int n = 1;
DLinkNode *p = L->next;
while (p!=NULL && p->data!=e)
{
n++;
p = p->next;
}
if (p == NULL)
return(0);
else
return(n);
}
bool ListInsert(DLinkNode *&L,int i,ElemType e)
{
int j = 0;
DLinkNode *p = L,*s;
if (p->next==L)//原双链表为空表时
{
/* p、s */
s = (DLinkNode *)malloc(sizeof(DLinkNode));
s->data = e;
p->next = s;//first:即p->next指向p/L变为指向s
s->next = p;//second:即s->next指回p
p->prior = s;//third :即p->prior指向p/l变为指向s
s->prior = p;//forth :s->prior指回p
return true;
}
else if(i == 1)//原双链表不为空表但i=1时
{
/* p、p->next*/
/* p、s、p->next*/
s = (DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点s
s->data = e;
s->next = p->next;//first
p->next = s;//second
s->next->prior = s;//third
s->prior = p;//forth
return true;
}
else//插入i位置不为1时
{
p = L->next;
while (j < i-2 && p!=L)//第i-1个结点的序标为i-2
{
j++;
p = p->next;
}
if(p==L)//未找到第i-1个结点
return false;
else//找到第i-1个结点
{
s = (DLinkNode *)malloc(sizeof(DLinkNode));
s->data = e;
s->next = p->next;//first
if (p->next!=NULL)
p->next->prior=s;//second
s->prior = p;//third
p->next = s;//forth
return true;
}
}
}
bool ListDelete(DLinkNode *&L,int i,ElemType &e)
{
int j = 0;
DLinkNode *p=L,*q;
if (p->next!=L)//原双链表不为空表时
{
if(i==1)//i==1时
{
q=L->next;//删除第1个结点
e=q->data;
L->next=q->next;
q->next->prior=L;
free(q);
return true;
}
else//i不为1时
{
p=L->next;
while(j<i-2 && p!=NULL)//第i-1个结点的序标为i-2
{
j++;
p=p->next;
}
if(p==NULL)//未找到第i-1个结点
return false;
else//找到第i-1个结点p
{
q=p->next;//q指向要删除的结点
if (q==NULL)
return 0;//不存在第i个结点
e=q->data;
p->next=q->next;//从单链表中删除q结点
if (p->next!=NULL) p->next->prior=p;
free(q);
return true;
}
}
}
else return false;//原双链表为空表时
}
int main()
{
DLinkNode *lk;
ElemType a[6]= {5,8,7,2,4,9};
ElemType e;
int i,x,choice;
printf("第一步.创建循环双链表......\n");
CreateListF(lk, a, 6);
while(1){
printf("创建成功!请选择菜单执行相关操作\n");
printf(" 1.销毁循环双链表\n");
printf(" 2.判定循环双链表是否为空\n");
printf(" 3.求循环双链表的长度\n");
printf(" 4.输出循环双链表\n");
printf(" 5.求循环双链表第i个位置上的元素\n");
printf(" 6.查找循环双链表中元素e的位置\n");
printf(" 7.在循环双链表第i个位置插入元素\n");
printf(" 8.删除循环双链表第i个位置上的元素\n");
printf(" 0.退出\n");
printf(" 请输入你的选择:");
scanf("%d",&choice);
switch(choice)
{
case 0: exit(0);
case 1: DestroyList(lk);
printf("循环双链表销毁成功~~程序直接退出!!");
exit(0);
case 2: if(ListEmpty(lk))
printf("循环双链表为空!");
else
printf("循环双链表不为空!");
break;
case 3: printf("该循环双链表长度为%d\n",ListLength(lk));
break;
case 4: printf("输出循环双链表:\n");
DispList(lk);
break;
case 5: printf("请输入待查找元素的位置:");
scanf("%d",&i);
GetElem(lk, i, e);
printf("第%d个位置上的元素为%d",i,e);
break;
case 6: printf("请输入要查找的元素:");
scanf("%d",&x);
printf("%d元素在循环双链表的第%d个位置\n",x,LocateElem(lk,x));
break;
case 7: printf("请输入要插入位置和值(空格隔开):");
scanf("%d%d",&i,&x);
ListInsert(lk,i,x);
break;
case 8: printf("请输入要删除的位置");
scanf("%d",&i);
ListDelete(lk, i, e);
break;
}
printf("按任意键继续……");
getchar();getchar();
}
return 0;
}
5.链栈 Listack
//链栈基本运算算法
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int ElemType;
typedef struct linknode
{
ElemType data; //数据域
struct linknode *next; //指针域
} LinkStNode; //链栈类型
void InitStack(LinkStNode *&s)
{
s=(LinkStNode *)malloc(sizeof(LinkStNode));
s->next=NULL;
}
void DestroyStack(LinkStNode *&s)
{
LinkStNode *p=s->next;
while (p!=NULL)
{
free(s);
s=p;
p=p->next;
}
free(s); //s指向尾结点,释放其空间
}
bool StackEmpty(LinkStNode *s)
{
return(s->next==NULL);
}
int StackLength(LinkStNode *s){
int i = 0;
while(s->next != NULL){
i++;
s = s -> next;
}
return i;
}
void Push(LinkStNode *&s,ElemType e)
{
/*头插法*/
LinkStNode *p;
p=(LinkStNode *)malloc(sizeof(LinkStNode));
p->data=e; //新建元素e对应的结点p
p->next=s->next; //插入p结点作为开始结点
s->next=p;
}
bool Pop(LinkStNode *&s,ElemType &e)//出栈,由于头插法,因此很方便
{
LinkStNode *p;
if (s->next==NULL) //栈空的情况
return false;
p=s->next; //p指向开始结点
e=p->data;
s->next=p->next; //删除p结点
free(p); //释放p结点
return true;
}
bool GetTop(LinkStNode *s,ElemType &e)
{
if (s->next==NULL) //栈空的情况
return false;
e=s->next->data;
return true;
}
int main(){
LinkStNode *s;
ElemType e;
int i, x, choice;
printf("第一步.创建链栈......\n");
InitStack(s);
while(1){
printf("创建成功!请选择菜单执行相关操作\n");
printf(" 1.销毁链栈\n");
printf(" 2.判定链栈是否为空\n");
printf(" 3.求链栈的长度\n");
printf(" 4.输入入栈元素进栈\n");
printf(" 5.使栈顶元素出栈\n");
printf(" 6.获取栈顶元素\n");
printf(" 0.退出\n");
printf(" 请输入你的选择:");
scanf("%d",&choice);
switch(choice)
{
case 0: exit(0);
case 1: DestroyStack(s);
printf("链栈销毁成功~~程序直接退出!!");
exit(0);
case 2: if(StackEmpty(s))
printf("链栈为空!");
else
printf("链栈不为空!");
break;
case 3: printf("该链栈长度为%d\n",StackLength(s));
break;
case 4: printf("请输入入栈元素:");
fflush(stdin);
scanf("%d",&e);//根据ElemType类型
Push(s, e);
break;
case 5: printf("令栈顶元素出栈:");
Pop(s, e);
printf("出栈元素为%d\n",e);//根据ElemType类型
break;
case 6: printf("获取栈顶元素:");
GetTop(s, e);
printf("栈顶元素为%d\n",e);//根据ElemType类型
break;
}
printf("按任意键继续……");
getchar();getchar();
}
return 0;
}
二、其它算法
-
如何判断链表是否有环,以及如何求该入环点
-
如何判断两条链表是否有交点,以及如何求该交点
-
两个循环链表合并为一张表