约瑟夫问题的几种实现

最近开始复习数据结构,下面是自己写得约瑟夫环的3中实现方式,代码简陋,重要的是理解思想

为了图方便,我把n,s,m位设为常数了,这个自己读取也可以的,试验过了

n:总共有n个人

s:从第s个人开始数1

m:到第m个人出列,然后继续从出列的下一个人开始算1

1: 顺序表的实现

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct{
int data[100];
int length;
}SeqList,*PSeqList;

void deletefrom(PSeqList p,int pos)
{
int j;
if(pos<1 || pos>p->length)
{
printf("error");
return;
}
for(j=pos;j<p->length;j++)
p->data[j-1]=p->data[j];
p->length--;
return;
}
int main()
{
int n,s,m;
scanf("%d",&n);getchar();
scanf("%d",&s);getchar();
scanf("%d",&m);getchar();

PSeqList p;
p=(PSeqList)malloc(sizeof(SeqList));
if(!p)
{
printf("error!");
return 1;
}

//初始化
int i,w;
for(p->length=n,i=0;i<p->length;++i)
p->data[i]=i+1;

int s1=s-1;
for(i=p->length;i>0;i--)
{
s1=(s1+m-1)%i;
w=p->data[s1];
printf("%d ",w);
deletefrom(p,s1+1);
}
return 0;
}

2:静态链表的实现

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

typedef struct{
int data;
int next;
}SNode;
typedef struct{
SNode sp[100];
int SL;
}Slite,*PSlite;
int main()
{
int n=5,s=1,m=2;

PSlite p=(PSlite)malloc(sizeof(Slite));
if(!p)
exit(1);
int i;
p->SL=0;
for(i=0;i<n;i++)
{
p->sp[i].data=i+1;
p->sp[i].next=(i+1)%n;
}

int begin=p->SL;
for(int s_count=0;s_count<s-1;s_count++)
begin=p->sp[begin].next;

int pre,pos;
for(i=0;i<n;i++)
{
int count=0;
while(count++<m-1)
{
pre=begin;
begin=p->sp[begin].next;
}
printf("%d ",p->sp[begin].data);
pos=p->sp[begin].next;
p->sp[pre].next=pos;
p->sp[begin].next=-1;
begin=pos;
}
free(p);
return 0;
}

这个实现的思想是:

1我首先找出来第一个人

2;然后循环n次,找到第m个人,把第m个人的下级赋给它的上级,将它的next=-1,意味着将它抹掉

3:循环单链表的实现,带表头

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct node{
int data;
struct node* next;
}Link,*PLink;

PLink Init(void)
{
PLink head;
head=(PLink)malloc(sizeof(Link));
if(!head)
{
printf("error");
exit(1);
}
head->next=NULL;
return head;

}
int main()
{
PLink head;
head=Init();
int n=5,s=1,m=2;

int i;
PLink q=head;
for(i=0;i<n;++i)
{
PLink p;
p=(PLink)malloc(sizeof(Link));
p->data=i+1;
p->next=NULL;
q->next=p;
q=p;
}

q->next=head->next;
//以上建立了带头结点的循环链表

/*
printf("%d ",head->next->data);
for(PLink p=head->next->next;p!=head->next;p=p->next)
printf("%d ",p->data);
*/

PLink pre,begin;
begin=head->next;
for(i=0;i<n;++i)
{
int count=0;
while(count++<m-1)
{
pre=begin;
begin=begin->next; //现在该删除begin
}
printf("%d ",begin->data);
PLink pos=begin->next;
pre->next=begin->next;
free(begin);
begin=pos;
}
return 0;
}

代码简陋。

原文地址:https://www.cnblogs.com/buxianghe/p/2225692.html