数据结构读书报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、需求分析
1、问题描述:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m得人出列,然后从出列得下一个人重新开始报数,数到第m得人又出列,…,如此反复直到所有得人全部出列为止。
二、程序分析
2、1 存储结构
存储结构:循环链表
2、2 关键算法分析
【设计思想】
首先,设计实现约瑟夫环问题得存储结构。由于约瑟夫环本身具有循环性质,考虑采用循环链表,为了统一对表中任意节点得操作,循环链表不带头结点。循环链表得结点定义为如下结构类型:
struct Node
{
int number;
Node *next;
};
其次,建立一个不带头结点得循环链表并由头指针first指示。
最后,设计约瑟夫环问题得算法。
【伪代码】
1、工作指针first,r,s,p,q初始化
2、输入人数(n)与报数(m)
3、循环n次,用尾插法创建链表
Node *q;
for(int i=1;i<=n;i++)
{
Node *p;
p=new Node;
p>number=i;
p>next=NULL;
if(i==1) L=q=p;
else
{
q>next=p;
q=q>next;
}
}
q>next=L;
if(L!=NULL){return(L);}
4、输入报数得起始人号数k;
5、Node *q = new Node;计数器初始化i=1;
6、循环n次删除结点并报出位置(其中第一个人后移k个)
当i 移动指针m2次p=p>next; 删除p结点得后一结点q q=p>next; p>next=q>next; *L = p>next; 报出位置后Delete q; 计数器i++; 【复杂度】 for(int i=1;i<=n;i++) { Node *p; p=new Node; p>number=i; p>next=NULL; if(i==1) L=q=p; else { q>next=p; q=q>next; } 时间复杂度:O(n) if(i==1) i+=LengthList(*L); Node *p; p=*L; int j=0; while(j p>next=p>next>next; *L = p>next; return(q); 时间复杂度:O(n2) 算法得空间复杂度:O(n2) 三、详细设计 #include using namespace std; struct Node//循环节点得定义 { int number;//编号 Node *next; }; Node *CreateList(Node *L,int &n,int &m); //建立约瑟夫环函数 void Joseph(Node *L,int n,int m); //输出每次出列号数函数 Node *DeleteList(Node **L,int i,Node *q); //寻找每次出列人得号数 int LengthList(Node *L); //计算环上所有人数函数 void main//主函数 { Node *L; L=NULL; //初始化尾指针 int n, m; cout<<"请输入人数N:"; cin>>n;//环得长度 if(n<1){cout<<"请输入正整数!";}//人数异常处理 else { cout<<"请输入所报数M:"; cin>>m; if(m<1){cout<<"请输入正整数!";}//号数异常处理 else { L=CreateList(L,n,m);//重新给尾指针赋值 Joseph(L,n,m); } } system("pause"); } Node *CreateList(Node *L,int &n,int &m)//建立一个约瑟夫环(尾插法) { Node *q; for(int i=1;i<=n;i++) { Node *p; p=new Node; p>number=i; p>next=NULL; if(i==1) L=q=p;//工作指针得初始化 else { q>next=p; q=q>next; } } q>next=L; if(L!=NULL){return(L);}//返回尾指针 else cout<<"尾指针异常!"< } void Joseph(Node *L,int n,int m)//输出每次出列得人 { int k; cout<<"请输入第一个报数人:"; cin>>k; if(k<1||k>n){cout<<"请输入1"< { cout<<"\n出列顺序:\n"; for(int i=1;i { Node *q = new Node; if(i==1) q=DeleteList(&L,k+m1,q);//第一个出列人得号数