约瑟夫环(N个人围桌,C语言,数据结构)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了约瑟夫环(N个人围桌,C语言,数据结构),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3244字,纯文字阅读大概需要5分钟。
内容图文

约瑟夫环问题(C语言、数据结构版)
一、问题描述
N个人围城一桌(首位相连),约定从1报数,报到数为k的人出局,然后下一位又从1开始报,以此类推。最后留下的人获胜。(有很多类似问题,如猴子选代王等等,解法都一样)
二、思路分析
(1)可将人的顺序简单编号,从1到N;
(2)构造一个循环链表,可以解决首位相连的问题,同时如果将人的编号改为人名或者其他比较方便
(3)将人的编号插入到结构体的Data域;
(4)遍历人的编号,输出参与的人的编号;
(5)开始报数,从头报数,报到k的人出局(删除次结点),(输出出局的人更人性化)避免浪费,可释放次结点。直到人数只有一个人时,退出循环。输出获胜的人。
三、算法实现
(1)构造结构体
typedef struct Node{
int Num;//Data域
struct Node *next;
}JoseNode, *PNode, *HNode;//PNode为指针变量,HNode为头结点
(2)得到头结点
HNode h = ((HNode)malloc(sizeof(JoseNode)));
(3)初始化循环单链表
int JoseInit(HNode *h)
{
if (!h)
{
printf("初始化链表错误!\n");
return 0;
}
(*h)->next = (*h);//循环单链表
return 1;
}
(4)插入算法
int JoseInsert(JoseNode *h, int pos, int x)
{
PNode p=h,q;
int i=1;
if (pos == 1)/*尾插法*/
{
p->Num = x;
p->next = p;
return 1;
}
while(i<pos-1)
{
p=p->next;
i++;
}
q=(PNode)malloc(sizeof(JoseNode));
q->Num=x;
q->next=p->next;
p->next=q;
return 1;
}
for (i = 1; i <=N; i++)
{
JoseInsert(h, i, i);
}
(4)遍历算法
void TraverseList(HNode h, int M)
{
int i = 0;
PNode p = h;
printf("参与的人的编号为:\n");
while (i<M)
{
printf("%d\t", p->Num);
p = p->next;
i++;
}
printf("\n");
}
(5)找到出局的人,并删除(删除算法)
int JoseDelete(HNode h, int M, int k)
{ int i;
PNode p=h,q;
while(M>1)//循环终止条件,只剩一个人时
{
for(i=1;i<k-1;i++)//此处为i<k-1,因为要找到的是出局的人的前一个结点①
{
p=p->next;
}
q=p->next;
p->next=q->next;
printf("出局的人为:%d号\n",q->Num);
free(q);//释放次结点
p=p->next;//与①处的相对应,①处找到的只是出局的人的前一个结点
M--;
}
printf("***************获胜者为:%d号***************",p->Num);
return 1;
}
四、完整代码
#include <stdio.h>
#include <malloc.h>
/*构建结构体*/
typedef struct Node{
int Num;
struct Node *next;
}JoseNode, *PNode, *HNode;
/**********初始化循环单链表*********/
int JoseInit(HNode *h)
{
if (!h)
{
printf("初始化链表错误!\n");
return 0;
}
(*h)->next = (*h);//循环单链表
return 1;
}
/*************单链表插入操作**********/
int JoseInsert(JoseNode *h, int pos, int x)
{
PNode p=h,q;
int i=1;
if (pos == 1)/*尾插法*/
{
p->Num = x;
p->next = p;
return 1;
}
while(i<pos-1)
{
p=p->next;
i++;
}
q=(PNode)malloc(sizeof(JoseNode));
q->Num=x;
q->next=p->next;
p->next=q;
return 1;
}
/*遍历*/
void TraverseList(HNode h, int M)
{
int i = 0;
PNode p = h;
printf("参与的人的编号为:\n");
while (i<M)
{
printf("%d\t", p->Num);
p = p->next;
i++;
}
printf("\n");
}
/**************出局函数****************/
int JoseDelete(HNode h, int M, int k)
{ int i;
PNode p=h,q;
while(M>1)
{
for(i=1;i<k-1;i++)
{
p=p->next;
}
q=p->next;
p->next=q->next;
printf("出局的人为:%d号\n",q->Num);
free(q);
p=p->next;
M--;
}
printf("***************获胜者为:%d号***************",p->Num);
return 1;
}
/***************************************/
int main()
{
int i;//计数器
int N;//参与的人数
int k;//报数密码
printf("请输入参与人数:");
scanf("%d",&N);
printf("请输入出局密码:");
scanf("%d",&k);
/**************得到头结点****************/
HNode h = ((HNode)malloc(sizeof(JoseNode)));
/***************初始化单链表************/
JoseInit(&h);
/******将编号插入到循环单链表中******/
for (i = 1; i <=N; i++)
{
JoseInsert(h, i, i);
}
/**************遍历单链表***************/
TraverseList(h,N);
/**************************************/
JoseDelete(h, N, k);
printf("\n");
printf("\n");
return 0;
}
五、实验验证
经过验证,实验成功!如果有不足的地方,请大家指出来,一起探讨!写得不清楚的可以与我联系。
原文:http://www.cnblogs.com/deom/p/4858010.html
内容总结
以上是互联网集市为您收集整理的约瑟夫环(N个人围桌,C语言,数据结构)全部内容,希望文章能够帮你解决约瑟夫环(N个人围桌,C语言,数据结构)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。