第1个回答 2008-09-17
刚刚也有人问了,真是巧。我昨天自己还在做数据结构时候也碰到了。所以两个都给你吧
#include<stdio.h>
#define N 13
struct person
{
int number;
int nextp;
}link[N+1];
void main()
{
int i,count,h;
for(i=0;i<=N;i++)
{
if(i==N)
link[i].nextp=1;
else
link[i].nextp=i+1;
link[i].number=i;
}
printf("\n");
count=0;
h=N;
printf("sequence that persons leave the circle:\n");
while (count<N-1)
{
i=0;
while(i!=3)
{
h=link[h].nextp;
if(link[h].number)
i++;
}
printf("%4d",link[h].number);
link[h].number=0;
count++;
}
printf("\nThe last one is");
for(i=1;i<=N;i++)
if(link[i].number)
printf("%3d",link[i].number);
printf("\n");
}
数据结构的思路:
void Josephus(int n,int m,int s)
//使用带表头附加节点的循环单链表为空
{
//生成表头附加结点,此时循环单链表为空
LNode* HL=new LNode;
HL->next=HL;
int i;
//生成含n个结点的,结点值依次为1-n的带表头附加结点的循环表
for(i=n;i>=1;i--)
//生成新结点
LNode* newptr=new LNode;
newptr->data=i;
//新结点插入到表头
newptr->next=HL->next;
HL->next=newptr;
}
//从表头开始顺序查找出第s个结点,对应第1个开始报数的人
LNode *ap=HL,*cp=HL->next;
for(i=1;i<s;i++){
//ap和cp指针后移一个位置
ap=cp;
cp=cp->nextl
//若cp指向了表头附加的结点,则仍需后移指针,使之指向表头结点
if(cp==HL){ap=HL;cp=HL->next;}
}
//依次使n-1个人出列
for(i=1;i<n;i++)
//顺序查找出待出列的人,即为循环结束后cp所指向的结点
for(int j=1;j<m;j++)
{
ap=cp;
cp=cp->next;
if(cp==HL){ap=HL;cp=HL->next;}
}
//输出cp结点的值,即出列的人
cout<<cp->data<<" ";
//从单链表中删除结点的后继结点
cp=ap->next;
//若cp指向了表头附加结点,则后移ap和cp指针
if(cp==HL){ap=HL;cp=HL->next;}
}
//使最后一个人出列
cout<<HL->next->data<<endl;
//删除表头结点和表头附加结点
delete HL->next;
delete HL;
}
第2个回答 2008-09-20
/*计算机071 冯**编写的约瑟夫环
单项循环链表实现 原创程序
在结构体中定义了一个序号,使得空间变大,但是程序简单易懂
*/
#include <stdio.h>
#include <malloc.h>
struct node
{
int num;//为方便表达,每个节点拥有一个序号
int password;//密码
struct node *next;
};
node * creatlist(int people)//构造链表
{
int i=1;//序号
int _password;
node *r,*s;
node *L=(node *)malloc(sizeof(node));//创造头结点
r=L;
while(i<=people)
{
printf("请输入第%d个人的密码:",i);
scanf("%d",&_password);
s=(node *)malloc(sizeof(node));
s->num=i;
s->password=_password;
r->next=s;
r=s;
i++;
}
r->next=L;//循环链表
return L;
}
void getoutseq(node *L,int firstp)//计算出列顺序并输出的函数
{
int _password=firstp;
node *p=L;
node *r=L;//r为p的前驱节点
int i=1;
while(L->next!=L)//当L为非空表时一直循环,空表表示所有人已经出列,则退出循环
{
while (i<=_password)//根据密码移动指针
{
if (p->next!=L)//当p的下一个节点非头结点,直接向下移
{
r=p;//p移动前先备份
p=p->next;
}
else//当p的下一个节点是头节点,则令p指向一号节点
{
r=L;
p=L->next;
}
i++;
}
printf("%d号出列\n",p->num);
_password=p->password;//获取节点中的密码
r->next=p->next;//删除并释放p
free(p);
i=1;
p=r;
}
printf("结束!\n");
}
/*
void print(node *L)//该函数用于打印每个节点的信息,方便测试
{
node *p=L->next;
while(p!=L)
{
printf("序号%d密码%d\n",p->num,p->password);
p=p->next;
}
}
*/
int main()
{
node *list;
int people;
int firstp;
printf("请输入人数:");
scanf("%d",&people);
putchar('\n');
printf("请输入初始密码:");
scanf("%d",&firstp);
putchar('\n');
list=creatlist(people);
/* print(list); //该语句用于测试
*/
getoutseq(list,firstp);
printf("按确定键退出。。。");
getchar();
getchar();
return 0;
}
第3个回答 2008-09-18
我刚做啊!!!!!!!!!!
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
int date;
int number;
struct node *next;
}ListNode;
ListNode *createlist(int n,int a[])
{
int j;
ListNode *head=(ListNode *)malloc(sizeof(ListNode));
ListNode *s,*r=head;
for(j=1;j<=n;j++)
{
s=(ListNode *)malloc(sizeof(ListNode));
s->date=a[j];
s->number=j;
r->next=s;
r=s;
}
r->next=head->next;
free(head);
return r;
}
void getnode(ListNode *head)
{
int m,k,i;
ListNode *p,*r;
p=head;
printf("输入上限值的初值 :");
scanf("%d",&m);
printf("出列顺序 :");
if(m>0)
{
while(p->next!=p)
{
for(k=1;k<m;k++)
p=p->next;
printf("%d ",p->next->number);
m=p->next->date;
r=p->next;
p->next=r->next;
free(r);
}
printf("%d",p->number);
free(p);
printf("\n");
}
}
void main()
{
ListNode *ha;
int a[100],n,i;
printf("输入人数 :");
scanf("%d",&n);
printf("输入密码 :");
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
ha=createlist(n,a);
getnode(ha);
printf("\n");
}
第4个回答 2008-09-18
我用的双向循环链表写的 因为这样比较容易解决一些特殊情况
随机数的上线我设置的是小于起始时的人数 大了也没有什么意义 无非多转几圈 反而不好验证
以前就打算写这个程序 一直没时间
这段时间正好复习一下数据结构
顺便写一些这方面的程序
#include"stdio.h"
#include"windows.h"
#include"malloc.h"
#include"time.h"
#define N 10
typedef struct node
{
int num ;
int sec ;
struct node *pre;
struct node *next;
}body;
void Initiate(body *x);
void Delect(int x,body *head);
void main()
{
int m;
body *first;
first=(body *)malloc(sizeof(body));
first->next=first;
first->pre=first;
Initiate(first);
m=rand()%(N-1);
m=m+1;
printf("\n任意数m=%d\n",m);
Delect(m,first);
}
void Initiate(body *head)
{
int xx[N],yy[N];
int i;
body *p,*q;
for(i=0;i<N;i++) yy[i]=i+1;
srand( time(NULL) );
for(i=0;i<N;i++) xx[i]=yy[rand()%N];
head->num=yy[0];
head->sec=xx[0];
for(i=1;i<N;i++)
{
p=head;
q=(body *)malloc(sizeof(body));
q->num=yy[i];
q->sec=xx[i];
while(p->next!=head) p=p->next;
p->next=q;
q->pre=p;
q->next=head;
head->pre=q;
}
printf("序号:");
for(i=0;i<N;i++) printf("%2d ",i+1);
printf("\n密码:");
for(i=0;i<N;i++) printf("%2d ",xx[i]);
}
void Delect(int x,body *head)
{
body *p;
p=head;
int i=1,sec;
while(i<x && p->next!=p) {p=p->next;i++;}
if(p->next!=p)
{
sec=p->sec;
printf("序号: %2d 密码: %2d \n",p->num,p->sec);
p=p->pre;
p->next=p->next->next;
p->next->pre=p;
head=p->next;
Delect(sec,head);
}
else
{
printf("序号: %2d 密码: %2d \n",p->num,p->sec);
printf("\n问题结束!\n");
}
}