课程设计—约瑟夫双向生死问题
来源:互联网 发布:unix环境高级编程 chm 编辑:程序博客网 时间:2024/05/22 09:07
问题及描述:
约瑟夫双向生死问题是建立在约瑟夫问题基础上,正向计数后反向计数,然后在正向计数,然后在正向计数。具体描述如下:30个旅客同乘一条船,因为严重过载,加上风浪高大,危险万分;因此船长告诉乘客,只有将全船一半的旅客投入海中,其余人才能幸免遇难。无奈,大家只得同意这种方法,并议定30个人围成一圈,由第一个人开始,顺时针依次报数,数到第九人,便把他投入大海中,然后从他的下一个人数起,逆时针数到第5人,将他投入大海,然后从他逆时针的下一个人数起,顺时针数到第9人,再将他投入大海,如此循环,直到剩下15个乘客为止。问那些乘客是将被扔下大海的位置。
顺序表方式:
list.h
#define MaxSize 50 typedef int ElemType; typedef struct { ElemType data[MaxSize]; int length; } SqList; void CreateList(SqList *&L, ElemType a[], int n);//用数组创建线性表 void InitList(SqList *&L);//初始化线性表InitList(L) void DestroyList(SqList *&L);//销毁线性表DestroyList(L) bool ListEmpty(SqList *L);//判定是否为空表ListEmpty(L) int ListLength(SqList *L);//求线性表的长度ListLength(L) void DispList(SqList *L);//输出线性表DispList(L) bool GetElem(SqList *L,int i,ElemType &e);//求某个数据元素值GetElem(L,i,e) int LocateElem(SqList *L, ElemType e);//按元素值查找LocateElem(L,e) bool ListInsert(SqList *&L,int i,ElemType e);//插入数据元素ListInsert(L,i,e) bool ListDelete(SqList *&L,int i,ElemType &e);//删除数据元素ListDelete(L,i,e)
list.cpp (对算法的listdelete进行修改)
#include <stdio.h> #include <malloc.h> #include "list.h" //用数组创建线性表 void CreateList(SqList *&L, ElemType a[], int n) { int i; L=(SqList *)malloc(sizeof(SqList)); for (i=0; i<n; i++) L->data[i]=a[i]; L->length=n; } //初始化线性表InitList(L) void InitList(SqList *&L) //引用型指针 { L=(SqList *)malloc(sizeof(SqList)); //分配存放线性表的空间 L->length=0; } //销毁线性表DestroyList(L) void DestroyList(SqList *&L) { free(L); } //判定是否为空表ListEmpty(L) bool ListEmpty(SqList *L) { return(L->length==0); } //求线性表的长度ListLength(L) int ListLength(SqList *L) { return(L->length); } //输出线性表DispList(L) void DispList(SqList *L) { int i; if (ListEmpty(L)) return; for (i=0; i<L->length; i++) printf("%d ",L->data[i]); printf("\n"); } //求某个数据元素值GetElem(L,i,e) bool GetElem(SqList *L,int i,ElemType &e) { if (i<1 || i>L->length) return false; e=L->data[i-1]; return true; } //按元素值查找LocateElem(L,e) int LocateElem(SqList *L, ElemType e) { int i=0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) return 0; else return i+1; } //插入数据元素ListInsert(L,i,e) bool ListInsert(SqList *&L,int i,ElemType e) { int j; if (i<1 || i>L->length+1) return false; //参数错误时返回false i--; //将顺序表逻辑序号转化为物理序号 for (j=L->length; j>i; j--) //将data[i..n]元素后移一个位置 L->data[j]=L->data[j-1]; L->data[i]=e; //插入元素e L->length++; //顺序表长度增1 return true; //成功插入返回true } //删除数据元素ListDelete(L,i,e) bool ListDelete(SqList *&L,int i,ElemType &e) { int j; if (i<0 || i>L->length) //参数错误时返回false return false; if(i==0) //i=L->length; // 对j=0 的修改(2行) i--; //将顺序表逻辑序号转化为物理序号 e=L->data[i]; for (j=i; j<L->length-1; j++) //将data[i..n-1]元素前移 L->data[j]=L->data[j+1]; L->length--; //顺序表长度减1 return true; //成功删除返回true }
main.cpp
#include "list.h" #include <stdio.h> void main() { SqList *sq; int n,f,s; //n代表船上的总人数,f代表第一次顺时针方向数的个数,s代表第二次逆时针的个数 int i,j=1; // j记录当前位置 printf("请输入船上的总人数:\n"); scanf("%d",&n); printf("请输入顺时针方向的人数:\n"); scanf("%d",&f); printf("请输入逆时针方向的人数:\n"); scanf("%d",&s); printf("请输入开始位置的人的序号:\n"); scanf("%d",&j); ElemType x[1000],e; for(i=0;i<n;i++) x[i]=i+1; //初始化数组 CreateList(sq, x, n); // 创建线性表 for(i=0;i<n/2;i++) //从第一个位置开始,第一次顺时针9人,第二次逆时针5人如此循环 { if(i%2==0) // 以奇偶区分顺、逆时针方向 { j=((j+f-1)+sq->length)%sq->length; //从第一个位置开始,顺时针数9个位置,应移动8个位置8 if(j==0)j=sq->length; // j=0 表示为最后一个元素if(ListDelete(sq,j,e)) printf("第%d次出局的序号为:%d\n",i+1,e); //删除并输出该元素 j=j%sq->length; // 结果修正( 处理j为最后一个元素的情况 下一次j开始时是从第一个位置 )} //顺时针的方法下一次开始的位置为j(在删除元素时是一次从下一个位置补上来) else // 逆时针移动5个位置 { j=((j-(s-1))+sq->length)%sq->length; //从第一个位置开始,逆时针数5个位置,应为移动4个位置 if(j==0)j=sq->length;if(ListDelete(sq,j,e)) printf("第%d次出局的序号为:%d\n",i+1,e); //删除并输出该元素 j=(j-1)%sq->length; // 结果修正(j为第一个元素)} //逆时针的方法下一次开始的位置为j-1 } printf("剩余的序号为:\n"); DispList(sq); }
运行结果:
循环双链表方式:
cdlinklist.h
#ifndef CDLINKLIST_H_INCLUDED#define CDLINKLIST_H_INCLUDED//循环双链表基本运算函数typedef int ElemType;typedef struct DNode //定义双链表结点类型{ ElemType data; struct DNode *prior; //指向前驱结点 struct DNode *next; //指向后继结点} CDLinkList;void CreateListF(CDLinkList *&L,ElemType a[],int n); //头插法建立循环双链表void CreateListR(CDLinkList *&L,ElemType a[],int n); //尾插法建立循环双链表void InitList(CDLinkList *&L); //初始化循环双链表void DestroyList(CDLinkList *&L); //销毁bool ListEmpty(CDLinkList *L); //判断是否为空int ListLength(CDLinkList *L); //求链表长度void DispList(CDLinkList *L); //输出链表bool GetElem(CDLinkList *L,int i,ElemType &e); //取链表元素int LocateElem(CDLinkList *L,ElemType e); //查找元素bool ListInsert(CDLinkList *&L,int i,ElemType e); //插入节点bool ListDelete(CDLinkList *&L,int i,ElemType &e); //删除节点#endif // CDLINKLIST_H_INCLUDED
cdlinklist.cpp
#include <stdio.h>#include <malloc.h>#include "cdlinklist.h"void CreateListF(CDLinkList *&L,ElemType a[],int n) //头插法建立循环双链表{ CDLinkList *s; int i; L=(CDLinkList *)malloc(sizeof(CDLinkList)); //创建头结点 L->next=NULL; for (i=0; i<n; i++) { s=(CDLinkList *)malloc(sizeof(CDLinkList));//创建新结点 s->data=a[i]; s->next=L->next; //将*s插在原开始结点之前,头结点之后 if (L->next!=NULL) L->next->prior=s; L->next=s; s->prior=L; } s=L->next; while (s->next!=NULL) //查找尾结点,由s指向它 s=s->next; s->next=L; //尾结点next域指向头结点 L->prior=s; //头结点的prior域指向尾结点}void CreateListR(CDLinkList *&L,ElemType a[],int n) //尾插法建立循环双链表{ CDLinkList *s,*r; int i; L=(CDLinkList *)malloc(sizeof(CDLinkList)); //创建头结点 L->next=NULL; r=L; //r始终指向尾结点,开始时指向头结点 for (i=0; i<n; i++) { s=(CDLinkList *)malloc(sizeof(CDLinkList));//创建新结点 s->data=a[i]; r->next=s; s->prior=r; //将*s插入*r之后 r=s; } r->next=L; //尾结点next域指向头结点 L->prior=r; //头结点的prior域指向尾结点}void InitList(CDLinkList *&L) //初始化循环双链表{ L=(CDLinkList *)malloc(sizeof(CDLinkList)); //创建头结点 L->prior=L->next=L;}void DestroyList(CDLinkList *&L) //销毁{ CDLinkList *p=L,*q=p->next; while (q!=L) { free(p); p=q; q=p->next; } free(p);}bool ListEmpty(CDLinkList *L) //判断是否为空{ return(L->next==L);}int ListLength(CDLinkList *L) //求链表长度{ CDLinkList *p=L; int i=0; while (p->next!=L) { i++; p=p->next; } return(i);}void DispList(CDLinkList *L) //输出链表{ CDLinkList *p=L->next; while (p!=L) { printf("%d ",p->data); p=p->next; } printf("\n");}bool GetElem(CDLinkList *L,int i,ElemType &e) //取链表元素{ int j=0; CDLinkList *p; if (L->next!=L) //双链表不为空表时 { if (i==1) { e=L->next->data; return true; } else //i不为1时 { p=L->next; while (j<i-1 && p!=L) { j++; p=p->next; } if (p==L) return false; else { e=p->data; return true; } } } else //双链表为空表时 return 0;}int LocateElem(CDLinkList *L,ElemType e) //查找元素{ int n=1; CDLinkList *p=L->next; while (p!=NULL && p->data!=e) { n++; p=p->next; } if (p==NULL) return(0); else return(n);}bool ListInsert(CDLinkList *&L,int i,ElemType e) //插入节点{ int j=0; CDLinkList *p=L,*s; if (p->next==L) //原双链表为空表时 { s=(CDLinkList *)malloc(sizeof(CDLinkList)); //创建新结点*s s->data=e; p->next=s; s->next=p; p->prior=s; s->prior=p; return true; } else if (i==1) //原双链表不为空表但i=1时 { s=(CDLinkList *)malloc(sizeof(CDLinkList)); //创建新结点*s s->data=e; s->next=p->next; p->next=s; //将*s插入到*p之后 s->next->prior=s; s->prior=p; return true; } else { p=L->next; while (j<i-2 && p!=L) { j++; p=p->next; } if (p==L) //未找到第i-1个结点 return false; else //找到第i-1个结点*p { s=(CDLinkList *)malloc(sizeof(CDLinkList)); //创建新结点*s s->data=e; s->next=p->next; //将*s插入到*p之后 if (p->next!=NULL) p->next->prior=s; s->prior=p; p->next=s; return true; } }}bool ListDelete(CDLinkList *&L,int i,ElemType &e) //删除节点{ int j=0; CDLinkList *p=L,*q; if (p->next!=L) //原双链表不为空表时 { if (i==1) //i==1时 { q=L->next; //删除第1个结点 e=q->data; L->next=q->next; q->next->prior=L; free(q); return true; } else //i不为1时 { p=L->next; while (j<i-2 && p!=NULL) { j++; p=p->next; } if (p==NULL) //未找到第i-1个结点 return false; else //找到第i-1个结点*p { q=p->next; //q指向要删除的结点 if (q==NULL) return 0; //不存在第i个结点 e=q->data; p->next=q->next; //从单链表中删除*q结点 if (p->next!=NULL) p->next->prior=p; free(q); //释放*q结点 return true; } } } else return false; //原双链表为空表时}
main.cpp
#include <malloc.h> #include <stdio.h> #include "cdlinklist.h" void main() { int n,f,s,st,m=1; //n代表船上的总人数,f代表第一次顺时针方向数的个数,s代表第二次逆时针的个数,a为开始位置的人的序号 CDLinkList *dl,*p; //*dl 为双链表的头指针 *p指向当前指针 printf("请输入船上的总人数:\n"); // 在创建循环双链表的时候,实际创建的有n+1个元素 头结点也算在其中 scanf("%d",&n); printf("请输入顺时针方向的人数:\n"); scanf("%d",&f); printf("请输入逆时针方向的人数:\n"); scanf("%d",&s); printf("请输入开始位置的人的序号:\n"); scanf("%d",&st); int a[1000]; int i;for(i=0;i<n;i++) a[i]=i+1; // 初始化数组 InitList(dl); CreateListR(dl, a, n); //尾插法建立双链表 p=dl->next; //指向表头节点 while(m<st) //指向开始位置的节点{p=p->next;m++;}// 删除过程 for(i=0;i<n/2;i++) //从第一个位置开始,第一次顺时针9人,第二次逆时针5人如此循环 if(i%2==0) // 以奇偶区分顺、逆时针方向 { CDLinkList *a; int j=0; while(j<f-1) //顺时针数9个人,即从第一个位置开始移动8个位置 { p=p->next; if(p==dl) j--; // 运行到头结点时在进行一次移动 j++; } printf("出局的序号为:%d\n",p->data); a=p; a->prior->next=a->next; a->next->prior=a->prior; p=a->next; // 下一次节点开始的位置(顺时针) free(a); } else // 逆时针移动5个位置 { CDLinkList *a; int j=0; while(j<s-1) //逆时针数5个人,即从第一个位置开始移动4个位置 { p=p->prior; if(p==dl) j--; j++; } printf("出局的序号为:%d\n",p->data); a=p; //删除节点 a->prior->next=a->next; a->next->prior=a->prior; p=a->prior; // 下一次节点开始的位置(逆时针) free(a); } printf("剩余的序号为:\n"); DispList(dl); //输出剩余的序号 }
运行结果:
0 0
- 课程设计—约瑟夫双向生死问题
- 数据结构程序设计--约瑟夫双向生死问题
- 项目-约瑟夫双向生死游戏
- 数据结构程序设计——约瑟夫双向生死杀人游戏
- 约瑟夫生死问题
- 约瑟夫生死问题
- 约瑟夫生死问题递归算法
- 数据结构——双向约瑟夫问题
- 1. 双向约瑟夫问题
- 双向约瑟夫问题
- 【数据结构基础】双向约瑟夫问题
- 约瑟夫问题——猴子选大王 双向指针
- 约瑟夫生死游戏
- 利用双向链表实现约瑟夫问题
- 双向链表解决约瑟夫问题
- uva133救济金发放(双向约瑟夫问题)
- 约瑟夫问题(双向循环链表)
- 约瑟夫问题---list双向链表
- [iOS 转]iOS开发中怎么创建Plist文件
- Yii gii的使用方法
- express + node.js 入门(4)数据读取接口
- 改错第一集
- Linux运行级别
- 课程设计—约瑟夫双向生死问题
- start
- 数论初步<最大公约,最小共倍,唯一分解定理,素数筛选,扩展欧几里德,取mod运算>
- php异步处理繁重的业务,避免主业务被长时间阻塞
- 搜索引擎Bing必应高级搜索语法
- LR性能测试结果样例分析
- MPAndroidChart的属性和方法
- 小程序解密,官方Demo竟然没有C#,贴这里备用
- 三层数据控件的动态设置