求个约瑟夫循环链表的C++程序

求个约瑟夫循环链表的C++程序,第1张

#include<iostream>

using namespace std

//链表结点类number为这个人的编号,key为密码

struct person

{

unsigned int number

unsigned int key

person *next

}

//约瑟夫环类,此类包含多个person类,并控制输入输出.

class joseph_ring

{

private:

unsigned int n//用于存放人数

unsigned int m//用于存放初始密码

person *head//链表的头结点

public:

joseph_ring(){m=0n=0head=NULL}//构造函数,把成员变量赋初值

void create()//建立环的成员函数

void show()//运算并输出的成员函数

}

void joseph_ring::create()

{

cout<<"请输入人数:"

cin>>n

cout<<"请输入m的初值:"

cin>>m

//定义2个临时指针

person *p1,*p2

//for循环中用于初始化环

for(int i=1i<=ni++)

{

p1=new person//新实例化一个"人"的对象

p1->number=i//给这个"人"编个号

cout<<"请输入第 "<<i<<"个人对应密码:"

cin>>p1->key//给这个"人"一密码

//如果当前链表为空,头结点指向第一个"人"

if(i==1)

{

head=p1

p2=p1

}

//否则,p2永远指向尾结点,新建的结点都接到p2之后

else

{

p2->next=p1

p2=p1

}

}

p2->next=head//把链表连成一个循环链表(就是一个环)

}

void joseph_ring::show()

{

person *p1,*p2,*p

p1=head

//有n个人,所以执行n次循环

for(int i=1i<=ni++)

{

int count=1

//用count定位到第m个出圈人,循环后,p1指向这个出圈人,p2指向这个出圈人的上一个人

while(count++<m)

{

p2=p1

p1=p1->next

}

cout<<p1->number<<"\t"//输入当前出圈人的编号

m=p1->key//把当前出圈人的密码作为指向下一个出圈人所要经过的人数

p=p1//p指向当前这个出圈人

p2->next=p1->next//把出圈人前的人和出圈人后的人连上.

p1=p1->next//下次从当前出圈人的下一个人开始数

delete p//把出圈人毙掉(就是释放这块内存)

}

cout<<endl

cin>>m

}

int main()

{

joseph_ring j

j.create()

j.show()

return 0

}

这没啥高手的,人称入门题目,也就是说,会做这个基本就可以用C做一些东西了。这是我以前写的,从博客上面搞下来的,你试试看能不能运行,我当时似乎是运行过了的。不过这个不是用链表做的,用数组做的,你结合链表的语法把他改一下就行了,很简单的,就一个结构体而已么,反正基本思路这样就对了。另外对了,当时水平有限还不懂动态分配内存,你去查一下malloc函数的用法,觉得合适可以加进去,你用new命令也可以动态分配内存,具体的可以去看看MSDN,MSDN好东西啊。

#include<stdio.h>

#include<stdlib.h>

void main()

{

int a[100]/*用来放环里的每个人的,人口上限(好像在打魔兽争霸)100,当然可以再改大*/

int n,r,ctor,u/*n是用来循环赋值的,给r个人循环赋1~u,一共r个人,ctor计数器,到了u再重新归1*/

int call(int a[],int real,int u)/*报数函数*/

for(n=0n<=99n++)a[n]=0/*给所有元素赋值为0,这样以后没赋值1~u的就都为0,可以当作不存在*/

printf("/约瑟夫环 JOSEPHUS/\n\n")

printf("输入参与报数的人数\n")

scanf("%d",&r)

printf("输入报数上限\n")

scanf("%d",&u)

ctor=1

for(n=0n<rn++) /*这个循环里给输入的人数都赋值,从1到u,相当于报的数*/

{

*(a+n)=ctor

ctor++

if(ctor>u)ctor=1

}

call(a,r,u)system("pause")/*调用点名函数*/

}

int call(int a[],int real,int u)

{

int n1,i

int *p

p=(a+u-1)

n1=0i=u

for(n1<real-1p++)

{

if(p>(a+real-1))p=a/*如果点名点过了,就接着队伍没有出列的第一个人继续*/

if(*(p)!=0) /*如果扫描的数字不为零,说明这个人还在队列中,那么看下面*/

{

if(i>u)i=1/*由于是剩下的人继续报数,所以当报到u这个上限时,还是要从新归1*/

if(i==u) /*当到达上限,说明这个人该出列啦,它的位置就填充为0*/

{

*(p)=0n1++/*n1计算着一共多少人出列,通过n1<real-1,可以留下最后一个人,这是最终目的*/

}

i++

}

}

for(i=0i<reali++) /*从新扫描数组,发现不是0的就输出,到这时候肯定只剩一个数不是0了*/

if(*(a+i)!=0)printf("所剩最后一位原来的呼号是%d\n\n",i+1)

}

写完了

正好之前写过基础的约瑟夫环,稍作修改就可以满足你的题目

#include <stdio.h>

#include <stdlib.h>

typedef struct _node {

    int id

    int key

    struct _node *next

} Linklist

int main() {

int n, m

scanf("%d %d", &n, &m)

int i, count = 0

Linklist *head = (Linklist*)malloc(sizeof(Linklist)), *tail = head

head->id = 1

scanf("%d", &head->key)

head->next = head

for(i = 2 i <= n i++) {

Linklist *p = (Linklist*)malloc(sizeof(Linklist))

p->id = i

scanf("%d", &p->key)

p->next = head

tail->next = p

tail = p

}

while(head != tail) {

if(++count % m) {

tail = head

} else {

    m = head->key

    count = 0

printf("%d ", head->id)

tail->next = head->next

free(head)

}

head = tail->next

}

printf("%d\n", head->id)

free(head)

return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11756638.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存