数据结构与算法joseph环.docx

上传人:b****5 文档编号:7743202 上传时间:2023-01-26 格式:DOCX 页数:7 大小:29.11KB
下载 相关 举报
数据结构与算法joseph环.docx_第1页
第1页 / 共7页
数据结构与算法joseph环.docx_第2页
第2页 / 共7页
数据结构与算法joseph环.docx_第3页
第3页 / 共7页
数据结构与算法joseph环.docx_第4页
第4页 / 共7页
数据结构与算法joseph环.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

数据结构与算法joseph环.docx

《数据结构与算法joseph环.docx》由会员分享,可在线阅读,更多相关《数据结构与算法joseph环.docx(7页珍藏版)》请在冰豆网上搜索。

数据结构与算法joseph环.docx

数据结构与算法joseph环

 

数据结构与算法课程设计

joseph环

 

152********6

张小莲

 

需求分析-------------------------------------------------------03

算法分析-------------------------------------------------------04

该单循环链表的逻辑结构------------------------------------------04

删除出列的结点-------------------------------------------------04

判断是否所有人全部出列------------------------------------------04

算法设计-------------------------------------------------------05

PersonList结构体-----------------------------------------------05

CreateList函数-------------------------------------------------05

Exports函数---------------------------------------------------05

完整代码-------------------------------------------------------07

结果说明-------------------------------------------------------09

总结------------------------------------------------------------10

 

需求分析

编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。

设计一个程序来求出出列顺序。

 

算法分析

1.该单循环链表的逻辑结构

由于题目要求“从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去”,队伍中编号最大的人报数完毕后编号最小的人应紧接着报数,所以创建链表时链表中最后一个结点的next指针直接指向首结点而不是头结点比较合适。

该单循环链表的逻辑结构如下:

2.删除出列的结点

某结点出列后,应将该结点从单循环链表里删除,则需要找到该结点的前一个结点,并由p指向它,通过修改指针域使结点p的直接后继为s的直接后继,即p->next=s->next。

当m=1时,即将出列的结点的前一个结点就是还未进行移动的当前的s指针指向的结点。

当要删除的结点恰好为head指向的结点时,删除前应修改head指向的结点为s->next。

3.判断是否所有人全部出列

由于结点出列后的删除操作,整个单循环链表的表长是逐渐缩短的,直至单链表只剩下头结点和首结点:

此时已经无法在进行删除结点操作,因为该结点的直接后继就是自己。

但实际上,当只剩下一个人时无论m为何值此人直接出列就可以了。

也就是说,当链表里只剩下最后一个结点时已经不必进行删除操作,直接输出该结点的编号即可。

于是问题就转化成如何判断链表里只剩最后一个结点,判断head->next是否与head相等可以解决问题。

 

算法设计

1.PersonList结构体

每个结点包含编号,密码以及指向下一个结点的指针域三个数据。

typedefstructnode

{

intpassword;//密码

intnumber;//编号

structnode*next;//指针域

}PersonList;

2.CreateList函数

该函数的功能是建立单循环链表,并从键盘读入每个编号的密码,入口参数n为单循环链表所包含的结点的个数,函数返回一个PersonList类型的指针。

PersonList*CreateList(intn)

{

PersonList*head,*s,*r;

head=(PersonList*)malloc(sizeof(PersonList));

head->next=NULL;

head->number=1;

printf("请输入编号为1的人的密码:

");

scanf("%d",&head->password);//从键盘中读取编号为1的人的密码

getchar();//接收回车

r=head;

for(inti=2;i<=n;i++)

{

s=(PersonList*)malloc(sizeof(PersonList));

s->next=NULL;

s->number=i;

printf("请输入编号为%d的人的密码:

",i);

scanf("%d",&s->password);//从键盘读入每个编号的密码

getchar();//接收回车

r->next=s;//插入新结点

r=s;//将尾指针指向新结点

}

r->next=head;//将最后一个结点的指针域指向首结点

returnhead;

}

3.Exports函数

该函数的功能是模拟出列的过程,并按照出列的顺序输出每个人的编号,入口参数head为单循环链表,入口参数m为初始报数上限值。

voidExports(PersonList*head,intm)

{

PersonList*s,*p;

s=head;

m=m-1;

printf("出列顺序为:

");

while(head!

=head->next)//当链表里有一个以上的结点时

{

if(m!

=1)//若m=1可跳过for循环

for(inti=1;i<=m-1;i++)//报数直到第m-1个结点

s=s->next;

p=s;//p指向第m-1个结点

s=s->next;//s指向第m个结点

printf("%4d",s->number);//输出第m个结点的编号

m=s->password;//将第m个结点的密码作为新的m值

if(s==head)//若要删除的结点恰好是首结点,移动head指针

head=s->next;

p->next=s->next;//删除第m个结点

s=p;//s指向报数1结点的前一个结点,为下一次报数做准备

}

printf("%4d",s->number);//输出链表里剩下的唯一一个结点

}

 

完整代码

#include

#include

typedefstructnode

{

intpassword;

intnumber;

structnode*next;

}PersonList;

PersonList*CreateList(intn)

{

PersonList*head,*s,*r;

head=(PersonList*)malloc(sizeof(PersonList));

head->next=NULL;

head->number=1;

printf("请输入编号为1的人的密码:

");

scanf("%d",&head->password);

getchar();

r=head;

for(inti=2;i<=n;i++)

{

s=(PersonList*)malloc(sizeof(PersonList));

s->next=NULL;

s->number=i;

printf("请输入编号为%d的人的密码:

",i);

scanf("%d",&s->password);

getchar();

r->next=s;

r=s;

}

r->next=head;

returnhead;

}

voidExports(PersonList*head,intm)

{

PersonList*s,*p;

s=head;

m--;

printf("出列顺序为:

");

while(head->next!

=head)

{

if(m!

=1)

for(inti=1;i<=m-1;i++)

s=s->next;

p=s;

s=s->next;

printf("%4d",s->number);

m=s->password;

if(s==head)

head=s->next;

p->next=s->next;

s=p;

}

printf("%4d",s->number);

}

voidmain()

{

intm,n;

printf("请输入报数上限值:

");

scanf("%d",&m);

printf("请输入参加报数的人数:

");

scanf("%d",&n);

PersonList*q=CreateList(n);

Exports(q,m);

printf("\n");

}

 

结果说明

第一轮报数m=7编号为7的人出列

第二轮报数m=4编号为1的人出列

第三轮报数m=5编号为6的人出列

第四轮报数m=4编号为2的人出列

第五轮报数m=2编号为4的人出列

第六轮报数m=1编号为5的人出列

第七轮报数m=9编号为8的人出列

第八轮报数m=7编号为9的人出列

第九轮报数m=8编号为3的人出列

第十轮报数m=3编号为10的人出列

 

总结

课本里提供了单循环链表的置空,建立,求表长,取结点,定位,插入,删除等操作代码,理解每个方法的原理便于面对实际问题时化繁为简灵活运用。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 文化宗教

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1