当前位置:首页 > 工作计划 > 约瑟夫环课程设计实验报告【约瑟夫环数据结构实验报告】
 

约瑟夫环课程设计实验报告【约瑟夫环数据结构实验报告】

发布时间:2019-07-17 15:14:33 影响了:

数据结构实验报告

实习1 线性表及其应用

题目:编制一个演示约瑟夫环的程序

班级:1403011班 姓名:付尧 学号:[1**********] 完成日期:2015.10.25

一.需求分析

1.本程序中,人数n为任意整数,首先输入一个报数上限值整数m,程序应能自动将出列的人所持的密码赋给m,再次作为报数上限,如此循环,直至所有人都出列为止。

2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入相应数据(即每个人所持的密码),每个人的序号由程序自动分配。

3.程序执行的命令包括:

(1)构造线性表;(2)输入数据;(3)执行报数,删除出列人的信息以及把出列人的密码赋给m;(4)结束。

4.测试数据

(1)m初值为20,n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6,则正确的出列顺序为6,1,4,7,2,3,5。

二.概要设计

为了实现程序上述功能,应以单向循环链表为存储结构。

1. 基本操作:

void createList()

操作结果:构造单向循环链表,初始化每个人的密码并分配序号。

void Josephus()

初始条件:链表存在。

操作结果:删除出列人的节点并重新报数。

2. 本程序包含三个模块:

(1)主程序模块;

(2)构造链表并输入信息模块;

(3)执行约瑟夫环函数模块;

三.详细设计

1.元素类型,结点类型和指针类型:

struct node{

int num;

int code;

struct node *next;

};

typedef struct node NODE;

NODE *head,*tail;

int m,n;

2.每个模块的分析:

(1)主程序模块:

int main(){

createList();

Josephus(head,m);

return 0;

}

(2)构造链表模块:

void createList(){

//申请头结点空间

//生成头结点

printf("请输入m和n\n");

//读取m,n

printf("请输入每个人的密码\n");

//创建节点并写入密码分配相应序号。

//形成循环链表

}

(3)约瑟夫环函数模块:

void Josephus(NODE *p,int m){

NODE *q;

int count=0; //报数计数器

q=tail; //q为尾结点

p=p->next; //p为第一个数据

while (p->next!=p){

count++; //当循环链表所剩元素大于1时

if (count==m){

//输出当前出列者的序号

//更新m为出列者的密码

//删除p节点

//令p指向下一个数据结点

count=0;

}

else {

//维护p和q到下一个结点

}

}

//打印最后剩下的人的序号

}

四.调试分析

(1)设计过程中对函数结束的条件感到疑惑,经过考虑,采取 p==p->next来判断,非常简捷方便

(2)算法的时间复杂度为n^2,空间复杂度为n,时间复杂度偏高,如果遇到数据过多可能会变得很慢。可以将m转化为m除以当前人数的余数,可以减少时间复杂度。

(3)这道题第一眼看觉得十分复杂,但编写中就会发现并不难。调试过程中我对链表的建立和插入删除操作更加熟练,也加深了对算法的认识。

五.用户使用说明

(1)本程序的运行环境为VS2010。

(2)进入演示程序后即显示提示信息:

请输入m和n:

输入m和n

请输入每个人的密码:

输入密码

输入完毕后就进行报数操作:

六.测试结果

当输入m=20,n=7,每个人所持密码一次为:3,1,7,2,4,8,4时,则输出正确的出列顺序为:6,1,4,7,2,3,5。

七.附录

#include

#include

struct node{

//建立链表数据类型

int num;

int code;

struct node *next;

};

typedef struct node NODE; //定义NODE为链表数据类型

NODE *head,*tail; //声明头指针,尾指针

int m,n;

void createList(){

//建立链表函数

NODE *p,*q;

int i;

p=new NODE; //申请头结点空间

p->next=NULL;

head=p; //生成头结点

printf("请输入m和n\n");

scanf("%d %d",&m,&n);//读取m,n

printf("请输入每个人的密码\n");

for (i=1;i

q=new NODE; //申请结点空间

q->num=i; //为节点排序

scanf("%d",&q->code); //记录该节点密码

p->next=q; //插入节点P

p=q;

}

tail=p; //保存尾指针

tail->next=head->next; //形成循环链表

}

void Josephus(NODE *p,int m){

//约瑟夫函数

NODE *q;

int count=0; //报数计数器

q=tail; //q为尾结点

p=p->next; //p为第一个数据

while (p->next!=p){

count++; //当循环链表所剩元素大于1时

if (count==m){

printf("%d ",p->num); //输出当前出列者的序号

m=p->code; //更新m为出列者的密码

q->next=p->next; //删除p节点

delete(p);

p=q->next; //令p指向下一个数据结点

count=0;

}

else {

q=p;

p=p->next;

}

}

printf("%d ",p->num); //打印最后剩下的人的序号

}

int main(){

createList();

Josephus(head,m);

return 0;

}

猜你想看
相关文章

Copyright © 2008 - 2022 版权所有 职场范文网

工业和信息化部 备案号:沪ICP备18009755号-3