敢死队问题(五种算法实现的约瑟夫环)

敢死队问题(五种算法实现的约瑟夫环)
敢死队问题(五种算法实现的约瑟夫环)

2011年12 月 30 日

目录

摘要 (2)

1课题背景的介绍 (2)

1.1 课题背景 (2)

1.2 目的 (3)

2需求分析 (3)

2.1 数据需求分析 (3)

2.2 功能需求分析 (4)

3系统总体设计 (4)

3.1 系统模块划分 (4)

3.2 系统模块结构图 (4)

4 系统详细设计 (5)

4.1 系统操作界面 (5)

4.2 各模块功能实现 (6)

4.2.1顺序存储 (6)

4.2.2单循环链表 (7)

4.2.3 数组 (8)

4.2.4 循环队列 (9)

4.2.5 递归 (11)

4.2.6 主函数 (12)

5 总结 (15)

6 参考文献 (15)

7 附录......................................................................................................... 错误!未定义书签。

7.1人员分工........................................................................................... 错误!未定义书签。

7.2 代码 (15)

摘要

敢死队问题是根据著名的“约瑟夫环”演变而来的敢死队问题的处理与计算来设计的一个系统。整个系统从符合操作简便、界面友好、灵活、实用、安全的要求出发,完成敢死队问题的全过程,包括五种数据结构算法(顺序表、单循环链表、数组、循环队列、递归)、数据的处理与计算、数据的分析、结果的输出。

本课程主要介绍了本课题的开发背景,所要完成的功能和开发的过程。重点说明了系统的设计思路、总体设计、各个功能模块的设计与实现方法。

关键词:敢死队问题,C语言,数据结构,顺序存储结构,单链表存储结构,数组,队列,递归

1课题背景的介绍

1.1课题背景

有M个敢死队员要炸掉敌人的一碉堡,谁都不想去,排长决定用轮回数数的办法来决定哪个战士去执行任务。如果前一个战士没完成任务,则要再派一个战士上去。现给每个战士编一个号,大家围坐成一圈,随便从某一个战士开始计数,当数到5时,对应的战士就去执行任务,且此战士不再参加下一轮计数。如果此战士没完成任务,再从下一个战士开始数数,被数到第5时,此战

士接着去执行任务。以此类推,直到任务完成为止。

排长是不愿意去的,假设排长为1号,请你设计一程序,求出从第几号战士开始计数才能让排长最后一个留下来而不去执行任务。

要求:至少采用两种不同的数据结构的方法实现。

1.2 目的

本课题运用C语言进行开发,C语言能够简单的进行编译一些程序,来实现对一些问题的解决。它虽然比较简单的处理一些问题,但却有更高的效率。它能够被大多数用户所接受,因为它能够呈现出清晰的界面,是人们能够很好的理解。能在一些方面给人们更好的服务,成为人们的好帮手。

经过这一个学期对《数据结构》的学习,我们都学到了不少东西,可能有些学的还不够理想,但无论如何这些知识都为我们的下一步学习打下了坚实的基础。通过做这么个课程设计将理论联系实际,使我更好的理解课本上的知识,发现不足之处,然后更好的学习,使我的编程能力有进一步的提高。

2需求分析

本程序输入队伍人数n为任意的,最终输出记数的初始位置,首先输入一个报数上限m,当达到报数上限时,那名士兵出列执行任务,从下个人开始记数,再次循环,直到只剩一人,得到其在队伍中的位置,通过数学思想求得题目要求即队长为首的情况下需要记数初始位置。

2.1 数据需求分析

由于约瑟夫环模拟的是人的报数操作,固本系统的主要处理的数据是正整数。正整数信息包括:队伍的人数,报数的数值,报数开始的位置。

本程序任务是通过输入任意队伍人数n和报数上限m,输出使排长最后一个执行任务而开始记数的初始位置。首先输入队伍人数n,然后输入报数上限m(m<=n),从1号开始报数,当达到报数上限时,那名士兵出列执行任务,从下个人开始记数,再次循环,直到只剩一人,得到其在队伍中的位置,记下该位置视

为排长位置,则1号即可视为最先报数的人,通过数学计算即可获得所求(z=n-k+2)。

2.2 功能需求分析

本系统主要实现对学生成绩信息进行管理,需要实现以下几个方面的管理功能:(1)创建存储结构:创建顺序表,创建单循环链表,创建数组,创建循环队列。(2)数据的输入:把队伍的人数,报数的数值输入。

(3)数据的处理;对队伍的人数,报数的数值进行计算。

(4)结果的输出:把报数开始的位置输出。

3系统总体设计

3.1 系统模块划分

本系统主要是对敢死队问题的处理,包括了创建存储结构、数据的输入、数据的处理、结果的输出等功能。整个系统分为以下几个模块。

1、操作界面模块本模块提供操作界面的信息输出模式。

2、顺序存储结构模块本模块用于通过运用顺序结构模块来计算结果。

3、单链表存储结构模块本模块用于通过运用单链表结构模块来计算结果。

4、数组模块本模块用于通过运用数组结构模块来计算结果。

5、循环队列模块本模块用于通过运用循环队列模块来计算结果

6、递归实现模块本模块通过递归思想来实现计算结果

3.2 系统模块结构图

根据系统功能设计,对应的系统模块结构图如图所示

4系统详细设计

4.1 系统操作界面

由于敢死队问题处理的是数字的调度问题,固不需要一些复杂的功能,因此根据实际需求设计了如下比较简洁的界面供用户使用。该界面简单明了,根据界面上的提示信息,用户能很快的使用该系统。

4.2 各模块功能实现

4.2.1顺序存储

(1)算法思想

将有n个人的队列存入顺序表中,然后从顺序表的第一个元素开始按间隔人数m读取数据,当报数报到m的时候出队,同时将该位置上的值置为0,以该位置的下一个(值为非0)位置为起始位置,以此循环报数直到剩下最后一个数为止,假设最后这个数为k。通过数学运算z=n-k+2,得到第一个报数的人的编号。

注意:

在报数的过程中如果出现位置上的值为0的情况,则跳过该位置,继续往下报数,直到有m 个非0的数为止。

(2)代码实现

#include

#include

#include

const int max=100;

int array[max],num,Templete;//Templete保存递归算法的返回值

//以下数组操作都是从下标0开始,真正的数据编号是从1开始

#pragma region ["用顺序表实现"]

typedef struct CirCleNode

{

int data[max];

int last;//顺序表的大小

}*CNode;

CNode CreateCirCleNode(int n)//往顺序表中读入数据

{

CNode cn;

cn=new CirCleNode;

int i;

for(i=0;i

{

cn->data[i]=i+1;

}

cn->last=n;

return cn;

}

int PushCirCleNode(CNode cn,int m)//顺序表出队

{

int count=0,i=0,num=0,j=0,Temp[max];

while(countlast)

{

while(numlast)

{

i=i%cn->last+1;//约瑟夫环的每轮起始位置

if(cn->data[i-1])//非0的时候让计数器自加

{

num++;

}

}

count++;

Temp[j++]=cn->data[i-1];

cn->data[i-1]=0;//出队的时候置为0

num=0;//计数器清零

}

/*

for(j=0;jlast;j++)

{

printf("--%d",Temp[j]);

}*/

return Temp[cn->last-1];

}

#pragma endregion ["顺序表执行"]

4.2.2单循环链表

(1)算法思想

创建不带头结点的单循环链表,创建完链表之后返回链表的第一个结点指针。从第一个结点开始按照以m为间隔,找到要出队的结点的前驱结点和后继结点,将前驱结点的下一个结点指针指向其后继结点,同时删除该结点,以此循环下去直到该循环链表只剩下最后一个结点为止。

(2)代码实现

#pragma region ["单循环链表实现"]

typedef struct node

{

int data;

struct node *next;

}*Node;

Node CreteNode(int n)//创建不带头结点单链表

{

Node p,q,t;

int i;

t=p=new node;

p->data=1;

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

{

q=new node;//申请新的结点插入链表

q->data=i;

p->next=q;

p=q;

//printf("--%d",p->data);

}

p->next=t;

return t;

}

int DeleteNode(Node nd,int m)//出队

{

Node t;

int i;

while(nd->next!=nd)

{

for(i=1;i

nd=nd->next;

t=nd->next;

//printf("->%d",t->data);

nd->next=t->next;

delete t;

nd=nd->next;//将结点指向被删除结点后一个结点

}

return nd->data;

}

#pragma endregion ["单循环链表"]

4.2.3 数组

(1)算法思想

用数组实现敢死队问题的关键在于用数组的下标构造一个虚假循环,从第一节点开始,以人数m为间隔,找到要删除结点的下标k,将k以后的所有队员依次往前移动一个位置。以此循环下去直到数组中只剩下一个数为止。

(2)代码实现

#pragma region ["数组实现敢死队问题"]

int Array(int n,int m)

{

int i,temp,j;

int k=0;//假设从第一个开始报数

int Jsp[max];

for(i=0;i

{

Jsp[i]=i+1;

}

for(i=n;i>=1;i--)

{

k=(k+m-1)%i;//用数组的下标构造一个虚假循环

temp=Jsp[k];//temp保存要出队的值

for(j=k;j

{

Jsp[j]=Jsp[j+1];

}

// printf("--%d",temp);

}

return temp;

}

#pragma endregion ["数组列实现"]

4.2.4 循环队列

(1)算法思想

队列操作的最主要思想是先进先出,并且每次操作都是从队首删除,队尾进队。创建循环队列,从结点的第一个结点开始按照m人数间隔查找到要出队的结点,并且修改头结点的指针使其指向该结点,同时将该结点上的数据值修改为0。依次循环下去查找余下的非零结点,直到剩下一个非零结点为止。

注意:

1、队列的队首指的是队中第一个元素的前一个结点,因此在查找之前,先将头结点的指针指向第一个结点。

2、在报数的过程中如果出现位置上的值为0的情况,则跳过该位置,继续往下报数,直到有m个非0的数为止。

(2)代码实现

//队列操作是先进先出,且每次删除队首,队尾进

#pragma region ["循环队列实现"]

typedef struct Seque

{

int data[max];

int front;

int rear;

} *SequeNode;

//置空队

void Iniqueue(SequeNode p)

{

p->front=0;

p->rear=0;

}

int AddQueue(SequeNode p,int n)//入队

{

if((p->rear+1)%n==p->front)

{

return 0;

}

else

{

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

{

p->rear=(p->rear+1)%n;

p->data[p->rear]=i;

// printf("--%d",p->data[p->rear]);

}

return 1;

}

}

int outQueue(SequeNode p,int n,int m)

{

int temp=0,k=0,Temp[max];

if(p->rear==(p->front+1)%n)

{

return 0;

}

else

{

p->front=(p->front+1)%n;

for(int i=0;i

{

while(temp

{

p->front=(p->front+1)%n;

if(p->front==0)//当头结点的下标是0时改变其下标

{

p->front=n;

}

if(p->data[p->front-1]!=0)//非零结点时让temp++

temp++;

}

Temp[i]=p->data[p->front-1];

p->data[p->front-1]=0;//把找到的那个结点置零

// printf("--%d",Temp[i]);

temp=0;

}

return Temp[n-1];

}

}

#pragma endregion ["循环队列"]

4.2.5 递归

(1)算法思想

参照数组实现。。。。

(2)代码实现

#pragma region["递归实现敢死队问题"]

//Templete保存最后的返回值,results保存下标void CreateArray(int n)

{

int i;

for(i=0;i

{

array[i]=i+1;

}

}

int SearchArray(int n,int m)//思路参照数组

{

int results;

if(n>num)

{

return 0;

}

else

{

if(n==1)

{

results=0;

}

results=(SearchArray(n+1,m)+m-1)%n;

}

Templete=array[results];

for(int j=results;j

{

array[j]=array[j+1];

}

return Templete,results;

}

#pragma endregion["递归结束"]

4.2.6 主函数

(1)核心算法

运用数学思想求得敢死队的最初报数位置。假设总人数为n,报数间隔为m,最后一个出队人的标号为k,第一个出队人的下标为t,则t=n-k+2。

(1)代码实现:

int main()

{

int push,flag;//num总人数,以push出队

int result=0,temp=0;//result最后出队的人的编号

SequeNode SNode=new Seque;

printf("**********************敢死队问题*********************\n");

printf("*****************************************************\n");

printf("请输入总人数:");

scanf("%d",&num);

printf("*****************************************************\n");

printf("请输入间隔人数:");

scanf("%d",&push);

if(num<1 || push<1)

{

printf("输入错误请重新输入:\n");

exit(1);

}

if(num==1)

{

printf("要使排长安全则应该从第%d号开始.\n",num);

exit(1);

}

printf("*****************************************************\n");

printf("根据菜单提示选择相应的算法\n");

printf("*****************************************************\n");

printf("1、顺序表2、链表3、数组4、队列5、递归6、退出\n");

while(scanf("%d",&flag))

{

if(flag==6)

{

break;

}

switch(flag)

{

case 1:

CNode cnode;

cnode=CreateCirCleNode(num);

result=PushCirCleNode(cnode,push);

break;

case 2:

Node LNode;

LNode=CreteNode(num);

result=DeleteNode(LNode,push);

break;

case 3:

result=Array(num,push);

break;

case 4:

Iniqueue(SNode);

AddQueue(SNode,num);

result=outQueue(SNode,num,push);

break;

case 5:

CreateArray(num);

SearchArray(1,push);

result=Templete;

break;

default :

result=0;

printf("<<请根据菜单提示操作>>\n");

break;

}

if(result!=0)

{

temp=(num-result+2)%num;//运用数学思想求出第一个开始位置

if(temp==0)

{

printf("要使排长安全则应该从第%d号开始报数.\n",num);

}

else

{

printf("要使排长安全则应该从第%d号开始报数.\n", temp);

}

}

}

printf("*****************************************************\n");

return 0;

}

(2)函数执行结果测试数据1:

测试数据2:

5总结

本课程设计《敢死队问题》处理系统,从开发到实现再到最后的测试结果来看,基本上实现了敢死队的五大算法功能模块:顺序存储、单循环链表、数组、循环队列、递归。并达到操作过程中的直观,方便,使用。系统采用模块化的程序设计,便于系统功能的组合和修改。另外通过本次的课程设计使我对《数据结构与算法》这门课程有了进一步的认识,通过系统中的发现的问题,再到解决问题这个阶段,让我体会到了编程的乐趣。

经过这一个学期对《数据结构与算法》的学习,我们都学到了不少东西,可能有些学的还不够理想,但无论如何这些知识都为我们的下一步学习打下了坚实的基础。通过做这么个课程设计将理论联系实际,使我更好的理解课本上的知识,发现不足之处,然后更好的学习,使我的编程能力有进一步的提高。

6参考文献

《c语言》-----------------------------------------------------------------------------谭浩强

《数据结构与算法》----------------------------------------------------------------宁正元

7. 代码

#include

#include

#include

const int max=100;

int array[max],num,Templete,push;//Templete保存递归算法的返回值

//以下数组操作都是从下标0开始,真正的数据编号是从1开始

#pragma region ["用顺序表实现"]

typedef struct CirCleNode

{

int data[max];

int last;//顺序表的大小

}*CNode;

CNode CreateCirCleNode(int n)//往顺序表中读入数据

{

CNode cn;

cn=new CirCleNode;

int i;

for(i=0;i

{

cn->data[i]=i+1;

}

cn->last=n;

return cn;

}

int PushCirCleNode(CNode cn,int m)//顺序表出队

{

int count=0,i=0,num=0,j=0,Temp[max];

while(countlast)

{

while(numlast)

{

i=i%cn->last+1;//约瑟夫环的每轮起始位置

if(cn->data[i-1])//非0的时候让计数器自加

{

num++;

}

}

count++;

Temp[j++]=cn->data[i-1];

cn->data[i-1]=0;//出队的时候置为0

num=0;//计数器清零

}

/*

for(j=0;jlast;j++)

{

printf("--%d",Temp[j]);

}*/

return Temp[cn->last-1];

}

#pragma endregion ["顺序表执行"]

#pragma region ["单循环链表实现"]

typedef struct node

{

int data;

struct node *next;

}*Node;

Node CreteNode(int n)//创建不带头结点单链表

{

Node p,q,t;

int i;

t=p=new node;

p->data=1;

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

{

q=new node;//申请新的结点插入链表

q->data=i;

p->next=q;

p=q;

//printf("--%d",p->data);

}

p->next=t;

return t;

}

int DeleteNode(Node nd,int m)//出队

{

Node t;

int i;

while(nd->next!=nd)

{

for(i=1;inext;

t=nd->next;

//printf("->%d",t->data);

nd->next=t->next;

delete t;

nd=nd->next;//将结点指向被删除结点后一个结点}

return nd->data;

}

#pragma endregion ["单循环链表"]

#pragma region ["数组实现敢死队问题"]

int Array(int n,int m)

{

int i,temp,j;

int k=0;//假设从第一个开始报数

int Jsp[max];

for(i=0;i

{

Jsp[i]=i+1;

}

for(i=n;i>=1;i--)

{

k=(k+m-1)%i;//用数组的下标构造一个虚假循环

temp=Jsp[k];//temp保存要出队的值

for(j=k;j

{

Jsp[j]=Jsp[j+1];

}

// printf("--%d",temp);

}

return temp;

}

#pragma endregion ["数组列实现"]

//队列操作是先进先出,且每次删除队首,队尾进

#pragma region ["循环队列实现"]

typedef struct Seque

{

int data[max];

int front;

int rear;

} *SequeNode;

//置空队

void Iniqueue(SequeNode p)

{

p->front=0;

p->rear=0;

}

int AddQueue(SequeNode p,int n)//入队

{

if((p->rear+1)%n==p->front)

{

return 0;

}

else

{

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

{

p->rear=(p->rear+1)%n;

p->data[p->rear]=i;

// printf("--%d",p->data[p->rear]);

}

return 1;

}

}

int outQueue(SequeNode p,int n,int m)

{

int temp=0,k=0,Temp[max];

if(p->rear==(p->front+1)%n)

{

return 0;

}

else

{

p->front=(p->front+1)%n;

for(int i=0;i

{

while(temp

{

p->front=(p->front+1)%n;

if(p->front==0)//当头结点的下标是0时改变其下标

{

p->front=n;

}

if(p->data[p->front-1]!=0)//非零结点时让temp++

temp++;

}

Temp[i]=p->data[p->front-1];

p->data[p->front-1]=0;//把找到的那个结点置零

// printf("--%d",Temp[i]);

temp=0;

}

return Temp[n-1];

}

}

#pragma endregion ["循环队列"]

#pragma region["递归实现敢死队问题"]

//Templete保存最后的返回值,results保存下标

void CreateArray(int n)

{

int i;

for(i=0;i

{

array[i]=i+1;

}

}

int SearchArray(int n,int m)//思路参照数组

{

int results;

if(n>num)

{

return 0;

}

else

{

if(n==1)

{

results=0;

}

results=(SearchArray(n+1,m)+m-1)%n;

}

Templete=array[results];

for(int j=results;j

{

array[j]=array[j+1];

}

return Templete,results;

}

#pragma endregion["递归结束"]

void function()

{

printf("*****************************************************\n");

printf("请输入总人数:");

scanf("%d",&num);

printf("*****************************************************\n");

printf("请输入间隔人数:");

scanf("%d",&push);

if(num<1 || push<1)

{

printf("输入错误请重新输入:\n");

exit(1);

约瑟夫环课程设计实验报告

《数据结构》 课程设计报告 课程名称:《数据结构》课程设计课程设计题目:joseph环 姓名: 院系:计算机学院 专业: 年级: 学号: 指导教师: 2011年12月18日

目录 1 课程设计的目的 (2) 2 需求分析 (2) 3 课程设计报告内容 (3) 1、概要设计 (3) 2、详细设计 (3) 3、调试分析 (x) 4、用户手册 (x) 5、测试结果 (6) 6、程序清单 (7) 4 小结 (10) 1、课程设计的目的 (1)熟练使用C++编写程序,解决实际问题; (2)了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力; (3)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能; (4)提高综合运用所学的理论知识和方法独立分析和解决问题的能力; 2、需求分析 1、问题描述: 编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计一个程序来求出出列顺序。 2、要求: 利用不带表头结点的单向循环链表存储结构模拟此过程,按照出列的顺序输出各个人的编号。 3、测试数据: m的初值为20,n=7 ,7个人的密码依次为3,1,7,2,4,7,4,首先m=6,则正确的输出是什么? 输出形式:建立一个输出函数,将正确的输出序列

3、课程设计报告内容 概要设计: 在理解了题目后,我先想到的是我们所学的单链表,利用单链表先建立循环链表进行存贮,建立完循环链表后,我将所要编写的函数分为了两块,一块是经过学过的单链表改编的循环链表的基本操作函数,还有一块是运行约瑟夫环的函数。 详细设计: 我先建立一个结构体,与单链表一样,只是多了一个存密码的code域 struct LinkNode { int data; /删除的是尾结点时(不知道为什么我写程序里总是编译出现错误){ q->next=head; //重新链接 delete a; len--; return out; } else { q->next=a->next; delete a; len--; return out; } } } } 5、测试结果:

基于Matlab的数字锁相环的仿真设计金佳琪

基于Matlab的数字锁相环的仿真设计 1115101021 金佳琪 摘要:锁相环是一个能够跟踪输入信号相位变化的闭环自动跟踪系统。它广泛应用于无线电的各个领域,并且,现在已成为通信、雷达、导航、电子仪器等设备中不可缺少的一部分。然而由于锁相环设计的复杂性,用SPICE对锁相环进行仿真,数据量大,仿真时间长,而且需进行多次仿真以提取设计参数,设计周期长。本文借助于Matlab中Simulink仿真软件的灵活性、直观性,在Simulink 中利用仿真模块搭建了全数字锁相环的仿真模型。利用仿真模块搭建了全数字锁相环的仿真模型,通过仿真达到了设计的目的,验证了此全数字锁相环能达到的各项功能要求。 关键词:锁相环,MATLAB,锁定,Simulink,频率合成 全数字锁相环 随着最近几年数字电路技术的发展,锁相环路在数字领域获得了越来越多的使用。与模拟锁相环相比,全数字锁相环不含无源器件、面积小、具有较强的抗噪声能力,锁定时间短,可以很方便地在各个工艺之间转换,重用性高,设计周期短。 方案介绍 全数字锁相环包括数字鉴相鉴频器(PDF)、数字滤波器(LPF)、数字振荡器(NCO)三部分,如下图12所示: 图1 全数字锁相环的仿真框图 由图12和图11的比较可以看出,全数字锁相环实际上是通过将模拟锁相环路替换成数字电路得到的。这意味着鉴相鉴频器(PDF)、环路低通滤波器(LPF)需要转换到离散系统。环路低通滤波器(LPF)可以通过一个希望的传输函数的拉普拉斯变换的z变换而得到。压控振荡器需要转换成数控振荡器(Numerically Controlled Oscilaator)。下面详细讨论鉴相鉴频器(PDF)、环路低通滤波器(LPF)以及数控振荡器(Numerically Controlled Oscilaator)模型的建立。 模型的建立 正和上述基于频率合成的模拟锁相环的仿真模型的建立相似,全数字锁相环仿真模型的建立也基于相同的算法: 锁相环闭环系统状态的变化依赖于PFD输出的相位误差。相位误差输出一次,锁相环状态改变一次;PFD不输出相位误差,锁相环里的所有信号均不改变状态。根据上

约瑟夫环实验报告

课程实验报告 题目:2016.4.6 学生姓名:黄玲 学生学号:201408070105 专业班级:智能1401 指导老师:骆嘉伟 完成日期:2016.4.6

一.需求分析 1.本实验基本要求是用数组来实现线性表,再基于线性表的基本操作(插入、删除、修改等)来实现约瑟夫问题 2.由键盘输入总人数n和出列报数m 3.在DOS界面上显示依次出圈的人的编号和最后一个留下的人,在当前文件夹里生成一个文本文件,里面是相同的输出。 4.测试数据: 输入: 10,3 输出: 3 6 9 2 7 1 8 5 10 4//DOS 3 6 9 2 7 1 8 5 10 4//TXT 二.概要设计 §抽象数据类型 为实现上述程序的逻辑功能,应以整数存储用户的输入 用线性表实现,线性表定义如下: ADT LISt 数据对象:整数 基本操作: AList(100);//构建一个最大人数为100的顺序表(数组)来存储人 Next();//指向下一个人 moveStart();//回到第一个人继续数数 Length();//查看圈里还剩多少人 currPos();//查看当前数到人的编号 getValue();//查看当前编号的人是否还在圈内 §程序的流程 以书上的代码案例为参考,编写线性表的ADT在继承线性表的基础上编写顺序表(数组)的类文件编写主函数,创建类的对象,完成程序 三.详细设计 §物理数据类型 将大小为n的数组赋好值,其值为他本身的编号,即数组下标。 §程序思路的具体步骤实现 设一个标志点,在数组中移动,同时报数,当报到m时,当前人的值变为0,出圈,然后继续移动,重新数。当数到值为0的人时自动跳过(已出圈),当数

数字锁相环研究

数字锁相环研究 刘飞雪 摘要:全数字锁相环路,所谓全数字化,就是环路部件全部数字化,采用数字鉴相器(DPD)、数字环路滤波器(DLF)和数控振荡器(DCO)构成的锁相环路。同步是通信系统中的一个重要实际问题。在数字通信系统中,位同步(又称码元同步)提取是更为重要的一个环节。因为确定了每一个码元的起始时刻,便可以对数字信息做出正确判决。利用全数字锁相环(DPLL)便可以直接从所接收的数字信号中提取位同步信号。用来实现位时钟同步提取的主要是超前—滞后型数字锁相环(LL-DPLL)。本文通过对全数字锁相环的种类及其相应实现功能的研究,确定了对位同步全数字锁相环路的设计方案,设计位同步全数字锁相环各个模块,本文中设计了3个模块,其中第2块包含2个小模块,第3块又包含3 个小模块,用Verilog HDL硬件描述语言对系统中的每个模块进行描述、仿真,然后将三个模块连接成反馈环路系统,使用仿真工具QuartusⅡ6.0进行编译、仿真,调试输出正确波形,最后分析电路性能。 关键词:全数字锁相环路,位同步数字锁相环路,超前-滞后型数字锁相环,数字鉴相器,数字滤波器,数控振荡器 Abstract All Digital Phase-Locked Loop is called because every module is digital. The loop contains these modules such as Digital Phase Discriminator (DPD), Digital Loop Frequency (DLF), Digital Control Oscillator (DCO). The synchronization is the key part of application in communication systems. In the field of digital communication systems, pick-up bit synchronization (also called code synchronization) is a more important part., because the definition of originate time of every code could make correct judgement. The usage of Digital Phase-Locked Loop (DPLL) could pick-up bit synchronous signal from digital signal directly. We use Lead-Lag Digital Phase-Locked Loop (LL-DPLL) to realize bit synchronous clock. This paper first introduced DPLL kinds and function. Then it designed the theory and every modules of DPLL. This paper designed three modules. In it, the second contained 2 modules and the third contained 3 modules. Using Verilog HDL to describe and simulate every module of the system, then connecting these modules to realize the system and using simulator named QuartusⅡ6.0 to compile and simulate correct wave. Key word: DPLL, bit synchronous DPLL, LL-DPLL,DPD, DLF, DCO 第一章绪论 1.1 全数字锁相环的背景及发展状况 锁相环路已经在模拟和数字通信及无线电电子学的各个领域得到了极为广泛的应用。伴随着大规模、超高速数字集成电路的发展及计算机的普遍应用,在传统的模拟锁相环路(APLL)应用领域中,一部分已经被数字锁相环路(DPLL)所取代。从六十年代起,人们就开始对数字锁相环路研究。起初,只是把模拟锁相环路中的部分部件数字化。比如,引进数控振荡器(DCO)代替模拟锁相环路中的压控振荡器(VCO)。这样做的优点是能在不牺牲压控振荡器频率稳定度的情况下,加大频率牵引的范围。从而提高整个环路的工作稳定性和可靠性。另外,用数字集成电路制作的鉴相器非常广泛的被应用在模拟锁相环路中,使环路性能大大提高。 此后,出现了全数字化锁相环。所谓全数字化,就是环路部件全部数字化,采用数字鉴相器(DPD)、数字环路滤波器(DLF)和数控振荡器(DCO)构成的锁相环路。目前,全数字锁相环路的研究日趋成熟,无论在理论研究还是在硬件实现方面,国内外均有大量的文献报道。并已经制成全数字化锁相环路FSK信号解调器、PSK信号解调器、位时钟提取器以及同步载波提取器等。国外已有单片全数字化锁相环路商品。全数字化锁相环路的共同特点是: 它们都具有一切数字系统所特有的显著优点,即电路完全数字化,使用逻辑门电路和触发器电路。因此,

约瑟夫问题算法及数据结构课程设计报告

线性表的操作及其应用 一、问题描述 线性表、队列是一种常用的数据结构,有顺序和链式两种存储结构,在实际中应用十分广泛,而链表又分为单链表和循环链表,队列又分为链式队列和循环队列。这些数据结构都可用来解决约瑟夫环问题。约瑟夫环问题是算法设计中的一个经典问题,是顺序编号的一组n个人围坐一圈,从第1个人按一定方向顺序报数,在报到m时该人出列,然后按相同方法继续报数,直到所有人出列。设计算法求约瑟夫环中人员的出列顺序。 二、基本要求 1、选择合适的存储结构,建立线性表; 2、利用顺序存储结构求解约瑟夫环问题; 3、利用单链表和循环链表分别求解约瑟夫环问题; 4、利用队列求解约瑟夫环问题。 三、测试数据 约瑟夫环的测试数据为7,报数为1至3。 四、算法思想 由于用到四种不同的存储结构,它们的算法思想依次是: 1、首先建立一个顺序表模拟整个约瑟夫环,手动输入顺序表长(即参加约瑟夫循环的人数)和循环的次数和表元素。用已经输出总人数和顺序表长作比较,作为外层循环条件。并对每一个输出后的元素重新赋值以为标记。对于每次循环,首先检查顺序表此次是不是我们设立的标记,如果不是则循环次数加1,当达到要求的循环次数时就将循环次数设置为0,输出该元素到屏幕并将总输出元素加1。每次外循环我们都会移到表的下一个位置,作为新的判断条件,每次报到表尾的时候,我们都将重新设置到表尾,作为下次循环的表元素。 2、首先采用链式循环链表建立整个约瑟夫环,手动输入第一次的循环次数和每个人所持下一个循环次数。设立判断指针指向表头,并将该指针是否为空作为外层循环条件。做一个内层循环,将判断指针移动到循环要输出的数,并设立一个前指针指向该指针的前一个位置,输出该元素后,将循环次数重新赋值成该元素。接着判断前指针和判断指针比较,如果相等说明整个表已经输出完毕,否则将删除该位置的元素。 3、用链式队列建立循环约瑟夫环,手动输入人数,第一次的循环次数和每个人所持下一个循环次数。并将每一个元素依次入队列,根据第一次循环次数,建立一个for循环,每一次循环都出队列,如果达到要求的循环次数就输出,否则进队列,这样这个数字就出现在队尾。第一个数输出后,以队列的非空作为循环条件,判断方式如上。 4、用循环队列建立约瑟夫环,将1-7个元素依次进入循环队列,以队列的长度作为与已输出的元素作为判断条件,对每一个输出后的元素重新赋值以为标记。对于每次循环,首先检查该该位置的元素是不是我们设立的标记-1,如果不是则循环次数加1,将队首指针移

约瑟夫环实验报告

一.需求分析 1.约瑟夫环(Joseph)问题的一种描述是:编号为1,2……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。 2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,有用户在键盘上输入演示程序中规定的运算命令,相应的输入数据和运算结果显示在其后。 3.程序执行的命令包括: 1)输入初始密码和人数2)输入所有人的密码3)显示输入的所有人的编号及相应的密码4)输出出列密码及编号5)结束 4.测试数据 (1)m=20, n=7, 7个人的密码依次为3,1,7,2,4,8,4 (2)m=20,n=1 (3)m=20,n=0 前面一组为常规数据,后面两组为边缘数据 二、概要设计 为实现上述功能,应以有序单向循环链表表示约瑟夫环。为此,需要有一个抽象数据类型。该抽象数据类型的定义为: ADT LinkList { 数据对象:D={ ai | ai ∈termset,i=1,2,……n,n>=0}, termset中每个元素包含编号,密码,和一个指向下一节点的指针数据关系:R1={ | ai-1, ai ∈D , i=2,……n} 基本操作: LinkList EvaluList(int n);//对单向循环链表进行尾插入赋值 int size(LinkList L);//求链表的节点个数 Status ScanList(LinkList L);//遍历单向循环链表 Status Joseph(LinkList &L,int m);//约瑟夫环的实现 } 此抽象数据类型中的一些常量如下:#define TRUE 1 #define FALSE 0 #define OK 1

基于matlab的二阶锁相环仿真设计

1 绪论 1.1 课题背景及研究意义 在现代集成电路中,锁相环(Phase Locked Loop)是一种广泛应用于模拟、数字及数模混合电路系统中的非常重要的电路模块。该模块用于在通信的接收机中,其作用是对接收到的信号进行处理,并从其中提取某个时钟的相位信息。或者说,对于接收到的信号,仿制一个时钟信号,使得这两个信号从某种角度来看是同步的(或者说,相干的)。其作用是使得电路上的时钟和某一外部时钟的相位同步,用于完成两个信号相位同步的自动控制,即锁相。它是一个闭环的自动控制系统,它将自动频率控制和自动相位控制技术融合,它使我们的世界的一部分有序化,它的输出信号能够自动跟踪输入信号的相位变化,也可以将之称为一个相位差自动跟踪系统,它能够自动跟踪两个信号的相位差,并且靠反馈控制来达到自动调节输出信号相位的目的。其理论原理早在上世纪30年代无线电技术发展的初期就已出现,至今已逐步渗透到各个领域。伴随着空间技术的出现,锁相技术大力发展起来,其应用范围已大大拓宽,覆盖了从通信、雷达、计算机到家用电器等各领域。锁相环在通信和数字系统中可以作为时钟恢复电路应用;在电视和无线通信系统中可以用作频率合成器来选择不同的频道;此外,PLL还可应用于频率调制信号的解调。总之,PLL已经成为许多电子系统的核心部分。 锁相环路种类繁多,大致可分类如下]1[。 1.按输入信号特点分类 [1]恒定输入环路:用于稳频、频率合成等系统。 [2]随动输入环路:用于跟踪解调系统。 2.按环路构成特点分类 [1]模拟锁相环路:环路部件全部采用模拟电路,其中鉴相器为模拟乘法器,该类型的锁相环也被称作线性锁相环。 [2]混合锁相环路:即由模拟和数字电路构成,鉴相器由数字电路构成,如异或门、JK触发器等,而其他模块由模拟电路构成。 [3]全数字锁相环路:即由纯数字电路构成,该类型的锁相环的模块完全由数字电路构成而且不包括任何无源器件,如电阻和电容。 [4]集成锁相环路:环路全部构成部件做在一片集成电路中。

课程设计(约瑟夫环)[1]

课程设计报告 课程名称:数据结构课程设计课程设计题目:约瑟夫环问题 姓名:余明旭 系:计算机科学与技术专业:计算机科学与技术年级:2010级 学号:100310236 指导教师:陈老师 职称:学生

一、需求分析 1、输入的形式和输入值的范围: 本程序中,输入报数上限值n,初始报数者s,初始报数者携带的密码m1,n-2个人携带的密码m(最后一人携带的密码没用),均限定为正整数,输入的形式为一个以“回车符”为结束标志的正整数。 2、输出的形式: 从屏幕显示出列顺序。 3、程序所能够达到的功能: 提供用户从键盘输入,Joseph约瑟夫环的必要数据,并显示出列顺序。4、测试数据: 输入 8 1 4 4 4 4 4 4 4 输出 4 8 5 2 1 3 7 6 一、详细设计 以单向循环链表实现该结构: 1、抽象数据类型的定义为: struct LNode { ElemType data; LNode* next; }; 2、本程序包含以下模块: 主程序模块: Void main() { 初始化; 输入数据; 执行功能; 显示结果; } 各功能模块:实现单链表的各项功能。 Void fun() { } 3、各模块的调用关系:

三、调试分析 程序的编写和调试基本正常,遇到的问题主要是:指针的指向的边界问题,如何每次正确找到出列的人的位置。 解决方法: for(int j=1;jnext; if(cp==HL) { ap=HL; cp=HL->next; } } a[i]中存储了每个人的密码,就可以准确知道每个人的位置。 通过约瑟夫环算法的课题设计让我理解了循环队列,不单单只是书本上文字的循环队列的概念,更多是自己能够通过实际的操作对循环队列有了更深的了解。上机的编程的过程是对数据结构的基础的进一步的巩固。学习过程体验到了学习的乐趣,实验课题使我认识到平时学习的漏洞和知识的缺乏,为以后的学习敲了一下警钟,数据结构是门基础,要学习扎实才行。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。 数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安 排。数据结构是数据存在的形式。 数据结构是信息的一种组织方式,其目的是为了提高算法的效率,它通常与一组算法的集合相对应,通过这组算法集合可以对数据结构中的数据进行某种操作。数据结构课程的主要目的是介绍一些常用的数据结构,阐明数据结构内在的逻辑关系,讨论它们在计算机中的存储表示,并结合各种数据结构,讨论对它们实行的 各种运算的实现算法。很多算法实际上是对某种数据结构施行的一种变换,研究算法也就是研究在实施变换过程中数据结构的动态性质。 学习的过程需要合作,而且在合作中提到自己的编程水平,借鉴他人好的地方,改掉原先自己不足,书本知识的与实际的联系,使自己的编程不在局限于原来的纸上谈兵,更多的是积累了经验,培养了能力。 四、用户手册 如何使用,详细步骤,根据提示输入。 示例: 主程序 Void main() 模块 Viod fun()

锁相环Simulink仿真模型

锁相环学习总结 通过这段的学习,我对锁相环的一些基本概念、结构构成、工作原理、主要参数以及simulink 搭建仿真模型有了较清晰的把握与理解,同时,在仿真中也出现了一些实际问题,下面我将对这段学习中对锁相环的认识和理解、设计思路以及中间所遇到的问题作一下总结: 1. 概述 锁相环(PLL )是实现两个信号相位同步的自动控制系统,组成锁相环的基本部件有检相器(PD )、环路滤波器(LF )、压控振荡器(VCO ),其结构图如下所示: 2. 锁相环的基本概念和重要参数指标 锁相是相位锁定的简称,表示两个信号之间相位同步。若两正弦信号如下所示: 相位同步是指两个信号频率相等,相差为一固定值。 ) (sin )sin()()(sin )sin()('t U t U t u t U t U t u o o o o o i i i i i θθωθθω=+==+=

当i ω=o ω,两个信号之间的相位差 为一固定值, 不 随时间变化而变化,称两信号相位同步。 当i ω≠o ω,两个信号的相位差 ,不论i θ 是否等于o θ,只要时间有变化,那么相位差就会随时间变化而 变化,称此时两信号不同步。若这两个信号分别为锁相环的输入和输出,则此时环路出于失锁状态。 当环路工作时,且输入与输出信号频差在捕获带范围之内,通过环路的反馈控制,输出信号的瞬时角频率)(t v ω便由o ω向i ω方向变化,总会有一个时刻使得i ω=o ω,相位差等于0或一个非常小的常数,那么此时称为相位锁定,环路处于锁定状态。若达到锁定状态后,输入信号频率变化,通过环路控制,输出信号也继续变化 并向输入信号频率靠近,相位差保持在一个固定的常数之内,则称环路此时为跟踪状态。锁定状态可以认为是静态的相位同步,而跟踪状态则为动态的相位同步。 环路从失锁进入到锁定状态称为捕获状态。 其他几个环路工作时的重要概念: 快捕带:能使环路快捕入锁的最大频差称为环路的快捕带,记为 L ω?,两倍的快捕带为快捕范围。 捕获带:能使环路进入锁定的最大固有频差,用P ω?表示,两倍的捕获带为捕获范围。 同步带:环路在所定条件下,可缓慢增加固有频差,直到环路失锁,把能够维持环路锁定的最大固有频差成为同步带,用H ω?, o i t t θθθθ-=-)()('o i o i t t t θθωωθθ-+-=-)()()('

数据结构实验报告(约瑟夫环)

基础成绩:82分《数据结构》课程实验 实验报告 题目:Joseph问题求解算法的设计与实现 专业:网络工程 班级:网络102 姓名:张晨曦 学号: 102534 完成日期:2012/6/20 一、试验内容

- 约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。 二、试验目的 掌握链表的基本操作:插入、删除、查找等运算,能够灵活应用链表这种数据结构。 三、流程图 struct list {

- int num,code; struct list *next; }; void main() { printf("Joseph问题求解算法的设计与实现\n \n"); int i,j,m=1; int key; // 密码. int n; //人数. list *p,*s,*head; head=(list *)malloc(sizeof(list)); //为头结点分配空间. p=head; //使指针指向头节点 printf("输入人的总个数:"); scanf("%d",&n); for(i=1;i<=n;i++) { printf("第%d个人的密码:\n",i); scanf("%d",&key); s=p; p=(list *)malloc(sizeof(list)); //创建新的结点. s->next=p; p->num=i; p->code=key; } p->next=head->next; p=head; head=head->next; free(p); //释放头结点. p=head; printf("\n\n输入初始值:\n"); scanf("%d",&key); printf("\n出列顺序为:\n"); do { j=1; p=head; while(jnext;//使P指向下一结点 j++; } //报数过程. i=p->num; key=p->code; printf("%d\n",i); s->next=p->next;

数据结构课程设计——约瑟夫环报告(含代码)

#include #include typedef struct LNode { //数据域 int cipher; //密码 int number; //编号 struct LNode *next; //指针域 }LNode,*LinkList; void InitList(LinkList &L) //创建一个只有头结点链表{ L = (LinkList)malloc(sizeof(LNode)); if(!L) { exit(1); printf("/n/nError!/n/n"); } L->next = L; } void CreateList(int n,LinkList &L) //初始化循环单链表 { LinkList p,q; q = L; printf("分别输入每个人的密码:"); for(int i = 1;i <= n;i++) { int k; scanf("%d",&k); if(k <= 0) { printf("\n\n密码有误!\n\n"); exit(1); } p = (LinkList)malloc(sizeof(LNode)); if(!p) { exit(1); printf("/n/nError!/n/n"); } p->cipher = k; p->number = i;

L->next = p; L = p; } L->next = q->next; free(q); } void PrintList(int x,int n,LinkList L) //输出出列顺序 { LinkList p,q; p = L; for(int i = 1;i <= n;i++) { for(int j = 1;j < x;j++) p = p->next; q = p->next; x = q->cipher; printf("%d ",q->number); p->next = q->next; free(q); } } int main() { printf("=============约瑟夫环==============\n\n\n"); int n,x; LinkList L; L = NULL; InitList(L); //构造空链表 printf("输入初始密码:"); scanf("%d",&x); //初始密码为x printf("\n"); printf("输入参与总人数:"); scanf("%d",&n); //总共的人数n printf("\n"); CreateList(n,L); //建立好一个约瑟夫环printf("\n\n\n===================================\n\n"); printf("出列编号为:"); PrintList(x,n,L); //输出出列顺序 printf("\n\n"); return 0; }

约瑟夫环程序设计报告书

4:课程设计报告书附件 《数据结构》课程设计报告 环Joseph)约瑟夫( 第七组别组组长成组员成绩教师指导 计算机科学与技术系 日11月6年2014. 摘要 约瑟夫环问题是典型的线性表的应用实例,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的库。而对于后者则要求应用程序功能完备,易使用等特点。经过分析,我们使用MICROSOFT公司的Microsoft Visual C++6.0开发工具,利用其提供的各种面向对象的开发工具,尤其是数据窗口这一能方便而简洁操作数据库的智能化对象,首先在短时间内建立系统原型,然后,对初始原型系统进行需求迭代,不断修正和改进,直到形成用户满意的可行系统。 关键词:单循环链表;c 语言;约瑟夫环;

序言 数据结构是研究数据元素之间的逻辑关系的一门课程,以及数据元素及其关系在计算机中的存储表示和对这些数据所施加的运算。该课程设计的目的是通过课程设计的综合训练,培养分析和编程等实际动手能力,系统掌握数据结构这门课程的主要内容。 本次课程设计的内容是用单循环链表模拟约瑟夫环问题,循环链表是一种首尾相接链表,其特点是无须增加存储容量,仅对表的链接方式稍作改变,使表处理更加灵活,约瑟夫环问题就是用单循环链表处理的一个实际应用。通过这个设计实例,了解单链表和单循环链表的相同与不同之处,进一步加深对链表结构类型及链表操作的理解。 通过该课程设计,能运用所学知识,能上机解决一些实际问题,了解并初步掌握设计、实现较大程序的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。 章节安排 1........................... 摘要、序言.... 一、问题描述 1、课程设计目的.................. (4) 2、课程设计任务.................. (4) 二、设计过程 1、设计思想(数据结构).................. . (4) 2、设计表示(函数说明).................. . (5) 3、详细设计(主要算法).................. . (6) 4、用户手册(使用说明).................. . (6) 三、测试报告

基于Matlab的数字锁相环的仿真设计

基于Matlab的数字锁相环的仿真设计 摘要:锁相环是一个能够跟踪输入信号相位变化的闭环自动跟踪系统。它广泛应用于无线电的各个领域,并且,现在已成为通信、雷达、导航、电子仪器等设备中不可缺少的一部分。然而由于锁相环设计的复杂性,用SPICE对锁相环进行仿真,数据量大,仿真时间长,而且需进行多次仿真以提取设计参数,设计周期长。本文借助于Matlab中Simulink仿真软件的灵活性、直观性,在Simulink 中利用仿真模块搭建了全数字锁相环的仿真模型。先借助模拟锁相环直观形象、易于理解的特点,通过锁相环在频率合成方面的应用,先对模拟锁相环进行了仿真,对锁相环的工作原理进行了形象的说明。在模拟锁相环的基础上,重新利用仿真模块搭建了全数字锁相环的仿真模型,通过仿真达到了设计的目的,验证了此全数字锁相环完全能达到模拟锁相环的各项功能要求。 关键词:锁相环,压控振荡器,锁定,Simulink,频率合成,仿真模块 1引言 1932年法国的H.de Bellescize提出同步捡波的理论,首次公开发表了对锁相环路的描述。到1947年,锁相环路第一次应用于电视接收机的水平和垂直扫描的同步。到70年代,随着集成电路技术的发展,逐渐出现集成的环路部件、通用单片集成锁相环路以及多种专用集成锁相环路,锁相环路逐渐变成了一个成本低、使用简便的多功能组件,为锁相技术在更广泛的领域应用提供了条件。锁相环独特的优良性能使其得到了广泛的应用,其被普遍应用于调制解调、频率合成、电视机彩色副载波提取、FM立体声解码等。随着数字技术的发展,相应出现了各种数字锁相环,它们在数字信号传输的载波同步、位同步、相干解调等方面发挥了重要的作用。而Matlab强大的数据处理和图形显示功能以及简单易学的语言形式使Matlab在工程领域得到了非常广泛的应用,特别是在系统建模与仿真方面,Matlab已成为应用最广泛的动态系统仿真软件。利用MATLAB建模可以快速地对锁相环进行仿真进而缩短开发时间。 1.1选题背景与意义 Matlab是英文MATrix LABoratory(矩阵实验室)的缩写。1980年,时任美国新墨西哥大学计算机系主任的Cleve Moler教授在给学生讲授线性代数课程时,为使学生从繁重的数值计算中解放出来,用FORTRAN语言为学生编写了方便使用Linpack和Eispack的接口程序并命名为MATLAB,这便是MATLAB的雏形。经过几年的校际流

数据结构实验报告 约瑟夫环问题

信息学院 数据结构实验报告 学号:姓名:班级 课程名称:数据结构实验名称:约瑟夫环 实验性质:①综合性实验√②设计性实验③验证性实验实验时间:2017.10 试验地点: 本实验所用设备:PC及VS2010 【数据结构】: typedef struct _RingNode { int pos; // 位置 struct _RingNode *next; }RingNode, *RingNodePtr; 【算法思想】: 以单链表实现约瑟夫环 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。(约瑟夫环问题Josephus)。以环状链表实现 【算法描述】: void CreateRing(RingNodePtr pHead, int count) { RingNodePtr pCurr = NULL, pPrev = NULL; int i = 1; pPrev = pHead; while(--count > 0) { pCurr = (RingNodePtr)malloc(sizeof(RingNode)); i++; pCurr->pos = i; pPrev->next = pCurr; pPrev = pCurr; } pCurr->next = pHead; // 构成环状链表 }

void PrintRing(RingNodePtr pHead) { RingNodePtr pCurr; printf("%d", pHead->pos); pCurr = pHead->next; while(pCurr != NULL) { if(pCurr->pos == 1) break; printf("\n%d", pCurr->pos); pCurr = pCurr->next; } } void KickFromRing(RingNodePtr pHead, int m) { RingNodePtr pCurr, pPrev; int i = 1; // 计数 pCurr = pPrev = pHead; while(pCurr != NULL) { if (i == m) { // 踢出环 printf("\n%d", pCurr->pos); // 显示出圈循序 pPrev->next = pCurr->next; free(pCurr); pCurr = pPrev->next; i = 1; } pPrev = pCurr; pCurr = pCurr->next; if (pPrev == pCurr) { // 最后一个 printf("\n%d", pCurr->pos); // 显示出圈循序 free(pCurr); break; } i++; } } int main()

约瑟夫环-joseph环-数据结构与算法课程设计报告

合肥学院 计算机科学与技术系 课程设计报告 2009~2010学年第二学期 课程数据结构与算法 课程设计名称joseph环 学生姓名朱玉庭 学号0804012029 专业班级08计本(2) 指导教师王昆仑、张贯虹 2010 年06月08号

一、问题分析和任务定义: 约瑟夫环是一个数学游戏,根据游戏内容的描述,能够很容易的看出,游戏中的玩家顺时针围坐一圈,能够很容易的发现,这跟本课上的单循环链表非常相似,所以可以通过单循环链表存储结构模拟此过程,当游戏中的玩家出列时,可以通过删除单循环链表中的结点来实现。 二、数据结构的选择和概要设计: 选择带为指针的单循环链表来解决这个问题,先建立一个空链表,然后根据人数生成具有相应结点的单循环链表,知道密码后,通过循环来找到对应的结点,然后将该结点的编号输出,改变密码,最后删除结点,以此类推,知道编码全部输完,即可得到结果序列。 三、详细设计和编码: 本题目是通过单循环链表存储结构来模拟此过程的,首先要先明确该单循环链表中结点的结构类型,定义如下: typedef struct Node { int key; //每个人持有的密码 int num; //这个人的编号 struct Node *next; //指向下一个结点 }Link; 当生成单循环链表时,就需要用到课本上创建单循环链表的有关内容了,可以先通过子函数Link *InitList()建立一个空链表,返回指针L,然后将返回的指针代入子函数Link *Creater(Link *L,int n)的形参中,对循环链表进行初始化,并且也返回一个指针,然后再将这个返回的指针代入到输出函数void Output(Link *L,int n,int m)的形参中,要想根据题目要求完成序列的输出,需要通过两个for循环来实现,第一个循环for(i=1;i<=n;i++) ,因为一个用n个人,所以结果要输出n个编号,这个循环每循环一次输出一个编号即printf("%d ",q->num),并将该编号下的密码赋值给m 即m=q->key,当循环完毕时正好将编号全部输出,第二个循环for(j=1;jnext; q=p->next; 用以找到相应的结点,并用指针q指向它,当完成了编号的输出和密码的赋值后,删除q指向的结点,将两个循环适当结合,即可输出正确的结果序列,其中的人数n和初始密码在主函数中确定。 四、上机调试: (1)有2个玩家,初始密码为21; (2)有3个玩家,初始密码为5:

数据结构约瑟夫环实验报告

《数据结构与算法设计》约瑟夫环实验报告 ——实验一 专业:物联网工程 班级:物联网1班 学号: 姓名:刘沛航

一、实验目的 1、熟悉VC环境,学习使用C语言利用链表的存储结构解决实际的问题。 2、在编程、上机调试的过程中,加深对线性链表这种数据结构的基本概念理解。 3、锻炼较强的思维与动手能力与更加了解编程思想与编程技巧。 二、实验内容 1、采用单向环表实现约瑟夫环。 请按以下要求编程实现: ①从键盘输入整数m,通过create函数生成一个具有m个结点的 单向环表。环表中的结点编号依次为1,2,……,m。 ②从键盘输入整数s(1<=s<=m)与n,从环表的第s个结点开始计 数为1,当计数到第n个结点时,输出该第n结点对应的编号, 将该结点从环表中消除,从输出结点的下一个结点开始重新计 数到n,这样,不断进行计数,不断进行输出,直到输出了这个环 表的全部结点为止。 例如,m=10,s=3,n=4。则输出序列为:6,10,4,9,5,2,1,3,8,7。 三、程序设计 1、概要设计 为了解决约瑟夫环的问题,我们可以建立单向环表来存储每个人的信息(该人的编号以及其下一个人的编号),及结点,人后通

过查找每个结点,完成相应的操作来解决约瑟夫问题。 (1) 抽象数据类型定义 ADT Joh{ 数据对象:D={|,1,2,,,0}i i a a ElemSet i n n ∈=≥ 数据关系:R1=11{,|,,1,2,,}i i i i a a a a D i n --<>∈= 基本操作: create(&J, n) 操作结果:构造一个有n 个结点的单向环表J 。 show(J) 初始条件:单向环表J 已存在。 操作结果:按顺序在屏幕上输出J 的数据元素。 calculate( J,s,n) 初始条件:单向环表J 已存在,s>0,n>0,s<环表结点 数。 操作结果:返回约瑟夫环的计算结果。 }ADT Joh (2)宏定义 #define NULL 0 #define OK 1 #define ERROR -1 (3)主程序流程

数据结构课程设计报告约瑟夫环完整版

******************* 实践教学 ******************* 兰州理工大学 软件职业技术学院 2011年春季学期 算法与数据结构课程设计 题目:约瑟夫环 专业班级: 姓名: 学号: 指导教师: 成绩:

摘要 约瑟夫环问题是典型的线性表的应用实例,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的库。而对于后者则要求应用程序功能完备,易使用等特点。 经过分析,我们使用MICROSOFT公司的Microsoft Visual C++6.0开发工具,利用其提供的各种面向对象的开发工具,尤其是数据窗口这一能方便而简洁操纵数据库的智能化对象,首先在短时间内建立系统应用原型,然后,对初始原型系统进行需求迭代,不断修正和改进,直到形成用户满意的可行系统。 关键词:单循环链表;c语言;约瑟夫环;

序言 数据结构是研究数据元素之间的逻辑关系的一门课程,以及数据元素及其关系在计算机中的存储表示和对这些数据所施加的运算。该课程设计的目的是通过课程设计的综合训练,培养分析和编程等实际动手能力,系统掌握数据结构这门课程的主要内容。 本次课程设计的内容是用单循环链表模拟约瑟夫环问题,循环链表是一种首尾相接链表,其特点是无须增加存储容量,仅对表的链接方式稍作改变,使表处理更加灵活,约瑟夫环问题就是用单循环链表处理的一个实际应用。通过这个设计实例,了解单链表和单循环链表的相同与不同之处,进一步加深对链表结构类型及链表操作的理解。 通过该课程设计,能运用所学知识,能上机解决一些实际问题,了解并初步掌握设计、实现较大程序的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。

相关文档
最新文档