php面试约瑟夫环问题,面试系列2约瑟夫环问题-Josephus-

面试系列2约瑟夫环问题-Josephus-

分类:软考

|

更新时间:2016-07-07|

来源:中华网考试

原题:

用户输入m,n值,从1至n开始顺序循环数数,每数到m输出该数值,直至全部输出。写出c程序。(约瑟夫环问题 josephus)

提示:

由于当某个人退出圆圈后,报数的工作要从下一个人开始继续,剩下的人仍然是围成一个圆圈的,可以使用循环表,由于退出圆圈的工作对应着表中结点的删除操作,对于这种删除操作频繁的情况,选用效率较高的链表结构,为了程序指针每一次都指向一个具体的代表一个人的结点而不需要判断,链表不带头结点。所以,对于所有人围成的圆圈所对应的数据结构采用一个不带头结点的循环链表来描述。设头指针为p,并根据具体情况移动。

为了记录退出的人的先后顺序,采用一个顺序表进行存储。程序结束后再输出依次退出的人的编号顺序。由于只记录各个结点的number值就可以,所以定义一个整型一维数组。如:int  quit[n];n为一个根据实际问题定义的一个足够大的整数。

代码:

/********************************************************************

created:    2006/06/14

filename:   c:/documents and settings/administrator/桌面/tmpp/josephus.c

file path:  c:/documents and settings/administrator/桌面/tmpp

file base:  josephus

file ext:   c

author:     a.tng

version:    0.0.1

purpose:    实现 josephus 环问题

用户输入m,n值,从1至n开始顺序循环数数,每数到m输出该数值,

直至全部输出。写出c程序。(约瑟夫环问题 josephus)

*********************************************************************/

#include

#include

#include

#include

/* 结构体和函数声明 */

typedef struct _node_t

{

int             n_num;

struct _node_t *next;

} node_t;

node_t         *node_t_create(int n);

node_t         *node_t_get(node_t **pn, int m);

/* 功能函数实现 */

/*

*  name: node_t_create

*  params:

*    n         [in]        输入要构造的链表的个数

*  return:

*    返回构造成功的环形单向链表指针

*  notes:

*    构造节点数量为 n 的环形单向链表

*

*  author: a.tng 2006/06/14 17:56

*/

node_t * node_t_create(int n)

{

node_t *p_ret   = null;

if (0 != n)

{

int     n_idx   = 1;

node_t *p_node  = null;

/* 构造 n 个 node_t */

p_node = (node_t *) malloc(n * sizeof(node_t));

if (null == p_node)

return null;

else

memset(p_node, 0, n * sizeof(node_t));

/* 内存空间申请成功 */

p_ret = p_node;

for (; n_idx < n; n_idx++)

{

p_node->n_num = n_idx;

p_node->next = p_node + 1;

p_node = p_node->next;

}

p_node->n_num = n;

p_node->next = p_ret;

}

return p_ret;

}

/*

*  name: main

*  params:

*    none

*  return:

*    int

*  notes:

*    main function

*

*  author: a.tng 2006/06/14 18:11

*/

int main()

{

int     n, m;

node_t *p_list, *p_iter;

n = 20; m = 6;

/* 构造环形单向链表 */

p_list = node_t_create(n);

/* josephus 循环取数 */

p_iter = p_list;

m %= n;

while (p_iter != p_iter->next)

{

int i   = 1;

/* 取到第 m-1 个节点 */

for (; i < m - 1; i++)

{

p_iter = p_iter->next;

}

/* 输出第 m 个节点的值 */

printf('%d/n', p_iter->next->n_num);

/* 从链表中删除第 m 个节点 */

p_iter->next = p_iter->next->next;

p_iter = p_iter->next;

}

printf('%d/n', p_iter->n_num);

/* 释放申请的空间 */

free(p_list);

system('pause');

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值