您的位置:首页 > 其它

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

2015-09-04 16:28 579 查看
用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序



[cpp] view
plaincopy

// 用户输入M,N值,从1至N开始顺序

// 循环数数,每数到M输出该数值,

// 直至全部输出

#include <stdio.h>



// 节点

typedef struct node

{

int data;

node* next;

}node;



// 创建循环链表

void createList(node*& head, node*& tail, int n)

{

if(n<1)

{

head = NULL;

return ;

}

head = new node();

head->data = 1;

head->next = NULL;



node* p = head;

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

{

p->next = new node();

p = p->next;

p->data = i;

p->next = NULL;

}



tail = p;

p->next = head;

}



// 打印循环链表

void Print(node*& head)

{

node* p = head;



while(p && p->next!=head)

{

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

p=p->next;

}

if(p)

{

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

}

}



// 用户输入M,N值,从1至N开始顺序

// 循环数数,每数到M输出该数值,

// 直至全部输出

void CountPrint(node*& head, node*& tail, int m)

{

node* cur = head;

node* pre = tail;



int cnt = m-1;

while(cur && cur!=cur->next)

{

if(cnt)

{

cnt--;

pre = cur;

cur = cur->next;

}

else

{

pre->next = cur->next;

printf("%d ", cur->data);

delete cur;

cur = pre->next;

cnt = m-1;

}

}



if(cur)

{

printf("%d ", cur->data);

delete cur;

head = tail = NULL;

}

printf("\n");

}



int main()

{

node* head;

node* tail;

int m;

int n;

scanf("%d", &n);

scanf("%d", &m);

createList(head, tail, n);

Print(head);

CountPrint(head, tail, m);

system("pause");

return 0;

}



约瑟夫环问题算法

已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编

号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报

数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全

部出列。

  例如:n = 9, k = 1, m = 5

 【解答】

  出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。



链表方法

  这个就是约瑟夫环问题的实际场景,有一种是要通过输入n,m,k三

个正整数,来求出列的序列。这个问题采用的是典型的循环链表的数据

结构,就是将一个链表的尾元素指针指向队首元素。 p->link=head

  解决问题的核心步骤:

  1.建立一个具有n个链结点,无头结点的循环链表

  2.确定第1个报数人的位置

  3.不断地从链表中删除链结点,直到链表为空



/*约瑟夫环*/

[cpp] view
plaincopy

#include <stdlib.h>

#include <stdio.h>

typedef struct node

{

int data;

struct node *next;

}LNode;



main()

{

LNode* Create(int,int);

LNode* GetNode(LNode *);

int Print(LNode *,int);

LNode *p;

int n,k,m;

do

{

printf ( "输入总人数 ");

scanf ( "%d ",&n);

}

while (n <=0);

do

{

printf ( "输入开始人的序号(1~%d) ",n);

scanf ( "%d ",&k);

}

while (k <=0 || k> n);

do

{

printf ( "输入间隔数字 ");

scanf ( "%d ",&m);

}

while(m <=0);



p=Create(n,k);

Print(p,m);

return 0;

};



LNode* Create(int n,int k)/*创建循环链表*/

{

int start=k-1;

LNode *s,*p,*L=0,*t;

if (start==0) start=n;

while (n!=0)

{

s=(LNode *)malloc(sizeof(LNode));

if (L==0) p=s;

if (n==start) t=s;

s-> data=n;

s-> next=L;

L=s;

n--;

}

p-> next=L;

return t;

}



LNode* GetNode(LNode *p)/*出队函数*/

{

LNode *q;

for (q=p;q-> next!=p;q=q-> next);

q-> next=p-> next;

free (p);

return (q);

}



Print(LNode *p,int m)/*输出函数*/

{

int i;

printf ( "出队编号:\n ");

while (p-> next!=p)

{

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

p=p-> next;

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

p=GetNode(p);

}

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

return 0;

}



参考:http://apps.hi.baidu.com/share/detail/695107

http://wenku.baidu.com/view/9d77eb0a763231126edb11b9.html

http://hi.baidu.com/zhoushenglong/blog/item/9328a1074cae08633912bb91.html

http://hi.baidu.com/%CC%EC%B5%D8%D3%D0%C7%E9%CC%EC%D2%E0%C0%CF/blog/item/4e19d1cf05a18b0e93457e34.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: