mysql 线性表_数据结构(二)线性表——链表

通常情况下,链接可分为单链表、双向链表和循环链表三种常用类型。

一、单链表基本操作的实现

使用链式存储结构来实现的线性表称为链表。首元结点、头结点、头指针、空指针。

1.单链表的类型定义

typedef struct LNode//结点类型

{

LElemType data;//数据域

struct LNode * next;//指针域

} LNode, * LinkList;

2.初始化操作InitLinkList(&L)

Status InitLinkList(LinkList &L)

{//创建空的带头结点的单链表L

L=(LinkList)malloc(sizeof(LNode));//申请头结点

if(!F) return OVERFLOW;//若失败

L->next=NULL;//头结点的后继指针域赋为NULL

returnOK;

}

3.求表长操作listLength(&L)

intlistLength(LinkList L)

{

LNode*p=L;//p指向头结点

int j=0;while(p->next)//当存在

{

p=p->next;//指针后移,指向后继

j++;

}return j;//返回计数器

}

4.取元素操作getElem(LinkList L,int i,LElemType &e)

Status getElem(LinkList L,int i,LElemType &e)

{

LNode*p=L;int j=0;while(jnext)//不为i结点,且不为最后一个

{

p=p->next;//向后查找

j++;

}if(j==i)//若找到

{

e=p->data;//由e返回其值

returnOK;

}else return ERROR;//若没找到,返回ERROR

}

5.按值查找locateElem(L,e)

LinkList locateElem(LinkList L,LElemType e)

{

LNode*p=L->next;//p指向第一个结点

while(p&&!equal(p->data,e))//若不等于e

p=p->next;//向后查找

if(p) return p;//找到

else return NULL;//没找到

}

6.插入操作listInsert(&L,i,e)

Status listInsert(LinkList &L,inti,LElemType e)

{//在单链表L的第i个位置插入一个值为e的结点

LNode *p=L,*q;//q用于指向想要插入的结点

int j=0;while(jnext)

{

p=p->next;

j++;

}if(j==i-1)//在j后插入新结点

{

q=(LNode *)malloc(sizeof(LNode));//生成新结点

if(!q) returnOVERFLOW;

q->data=e;

q->next=p->next;

p->next=q;returnOK;

}else returnERROR;

}

7.删除操作listDelete(&L,i,&e)

Status listDelete(LinkList &L,int i,LElemType &e)

{

LNode*p=L,*q;int j=0;while(jnext)

{

p=p->next;

j++;

}if(j==i-1&&p->next)//判断i结点是否存在

{

q=p->next;

p->next=q->next;

e=q->data;//由e返回删除元素的值

free(q);

}else returnERROR;

}

8.头插法建立单链表操作createList(&L,n)

void createList(LinkList &L,intn)

{//依次读入n个元素,建立单链表L

LNode *p;inti;

L=(LinkList)malloc(sizeof(LNode));

L->next=NULL;for(i=1;i<=n;i++)

{

p=(LNode *)malloc(sizeof(LNode));//生成p结点

inputListElem(p->data);//调用元素读入函数

p->next=L->next;

L->next=P;

}

}

9.尾插法建立单链表操作createList(&L,n)

void createList(LinkList &L,intn)

{//依次读入n个元素,建立单链表L

LNode *p,*r;inti;

L=(LinkList)malloc(sizeof(LNode));//生成头结点

r=L;//尾指针r指向头结点

for(i=1;i<=n;i++)

{

p=(LNode *)malloc(sizeof(LNode));//生成p结点

inputListElem(p->data);//调用元素读入函数,读入p结点的值

r->next=p;//把p结点放到r结点后,尾

r=p; //重置r

}

r->next=NULL; //最后一个结点后继指针为空

}

二、双向链表基本操作的实现

1.双向链表的类型定义

typedef structDLNode

{

LElemType data;struct DLNode *prior;struct DLNode *next;

}DLNode,* DLinkList;

2.插入操作算法

Status listInsert(DLinkList &L,inti,LElemType e)

{

DLNode*p=L,*q;int j=0;while(p->next&&j

{

p=p->next;

j++;

}if(j==i-1)

{

q=(DLNode *)malloc(sizeof(DLNode));if(!q) returnOVERFLOW;

q->data=e;

q->next=p->next;

q->prior=p;if(p->next) p->next->prior=q;

p->next=q;returnOK;

}else returnFALSE;

}

3.删除操作算法

Status listDelete(DLinkList &L,int i,LElemType &e)

{

DLNode*p=L;int j=0;while(p->next&&j

{

p=p->next;

j++;

}if(j==i)

{

e=p->data;

p->prior->next=p->next;if(p->next) p->next->prior=p->prior;free(p);returnOK;

}else returnFLASE;

}

三、循环链表的认识和使用

首尾相接的链表就是循环链表,单链表和双链表均可以构成循环链表。

1.循环链表 表尾结点的判定p->next=L;2.循环单链表合并算法

void unionCirList(LinkList &R1,LinkList &R2)

{

LNode*q=R2->next;

R2->next=R1->next;

R1->next=q->next;free(q);

}

四、链表实例——约瑟夫环问题

1.问题描述:

设编号为1、2、3...、n的n个人围坐一圈,约定从编号为k(1=

2.算法描述:

1 #include

2 #include

3 typedef structpersonNode4 {5 int num;//人员编号

6 struct personNode *next;7 }personNode,*personList;8 //由n个人组成的约瑟夫环问题,从第k个人开始,数到m就出列

9 void Josephus(int n,int m,intk)10 {11 inti,j;12 personList r,p;13 r=NULL;//尾指针

14 if(n>0)//创建第一个结点

15 {16 r=(personList)malloc(sizeof(personNode));17 r->num=1;18 r->next=r;19 }20 for(i=2;i<=n;i++)21 {22 p=(personList)malloc(sizeof(personNode));23 p->num=i;24 p->next=r->next;25 r->next=p;//在r结点后插入p结点

26 r=p;//重置r

27 }28 p=r->next;//p指向第1个人员结点

29 for(i=1;inext;//p指向第k个结点

33 }34 for(i=1;inext;//p指向出列结点

40 }41 printf("%d",p->num);//输出人员编号

42 r->next=p->next;43 free(p);//删除已出列的结点

44 p=r->next;//下一计数为1的结点

45 }46 printf("%d\n",r->num);//输出最后出列人员编号

47 free(r);//删除最后一个结点

48 }49

50 intmain()51 {52 intn,m,k;53 printf("**********约瑟夫环问题************\n");54 printf("输入n,m,k:");55 scanf("%d,%d,%d",&n,&m,&k);56 printf("出列的人员顺序为:");57 Josephus(n,m,k);58 system("pause");59 return 0;60 }

输出结果:

e90bd444b15ba3be71b2faf7e50fcc3f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值