数据结构与算法joseph环Word格式.docx

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

数据结构与算法joseph环Word格式.docx

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

数据结构与算法joseph环Word格式.docx

结果说明-------------------------------------------------------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->

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;

number=1;

printf("

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

"

);

scanf("

%d"

&

head->

password);

//从键盘中读取编号为1的人的密码

getchar();

//接收回车

r=head;

for(inti=2;

i<

=n;

i++)

{

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

s->

number=i;

printf("

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

i);

scanf("

s->

//从键盘读入每个编号的密码

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;

出列顺序为:

while(head!

=head->

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

if(m!

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

for(inti=1;

=m-1;

i++)//报数直到第m-1个结点

s=s->

next;

p=s;

//p指向第m-1个结点

s=s->

//s指向第m个结点

%4d"

s->

number);

//输出第m个结点的编号

m=s->

password;

//将第m个结点的密码作为新的m值

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

head=s->

p->

//删除第m个结点

s=p;

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

//输出链表里剩下的唯一一个结点

完整代码

#include<

stdio.h>

stdlib.h>

m--;

while(head->

next!

=head)

=1)

if(s==head)

voidmain()

intm,n;

请输入报数上限值:

m);

请输入参加报数的人数:

n);

PersonList*q=CreateList(n);

Exports(q,m);

\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的人出列

总结

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

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

当前位置:首页 > PPT模板 > 节日庆典

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

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