@[TOC](洛谷P1996 约瑟夫问题(C语言)) 数据结构有点累,学学简单的算法缓解以下,今天做做约瑟夫,虽然大一上已经做过,但现在有了数据结构的知识,做这些肯定有更进一步的体会与感悟了吧。
题目
1.单链表模拟
很久之前用数组进行模拟,现在换一种方法,让我们看看用链表模拟如何:
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
} Node;
void CreatFromTail(Node *head,int length)
{
Node *p; //尾插法
int flag=1;
p=head;
int i;
for(i=1;i<=length;i++)
{
p->next=(Node*)malloc(sizeof(Node));
p->next->data=i;
p=p->next;
}
p->next=head->next;//注意这里,和往常一样第一个结点head不用的
}
void Josephus(Node *head,int m)
{
Node *p,*q,*s;
p=head->next;
int i,j=1;
while(p->next!=p)
{
while(j<m)
{
q=p;
p=p->next;
j++;
}
//删除结点
s=p;
p=p->next;
q->next=p;
printf("%d ",s->data);
free(s);
j=1;
}
printf("%d ",p->data);
}
int main()
{
Node *head=(Node*)malloc(sizeof(Node));//这里必须要分配空间,都分配吧,免得出错
int length,m;
scanf("%d %d",&length,&m);
CreatFromTail(head,length);
Josephus(head,m);
return 0;
}
结果正确如图:
其实思路就在明面上了,用链表进行模拟,到第m个删除并输出即可。
2.队列模拟
感觉现在用队列解决这个真的是小题大做呀,队列函数写的比主体还多。 思路就是队头出一个元素,看到没到m个,没有就放到队尾,到了就出队。 代码如下:
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef struct queue{
int Qnum[MAXSIZE];//注意此处为关键。我们用的队列要与我们的ADT类型相同!!
int front;
int rear;
}Queue;//在这里我选择用数组来操作
void initilize(Queue *Q) { //初始化队列
Q->front = 0;
Q->rear = 0;
}
int Pop(Queue *Q)//出队
{
Q->front++;
return Q->Qnum[Q->front];
}
void Push(Queue *Q,int i)//入队
{
Q->rear++;
Q->Qnum[Q->rear]=i;
}
int Isempty(Queue *Q)//判空
{
return Q->front==Q->rear;
}
void Setup(Queue *Q,int length)//建立题意队列
{
initilize(Q);
for(int i=1;i<=length;i++)
{
Push(Q,i);
}
}
void Josephus(Queue *Q,int m)
{
int i,j=1,move,remove;
while(!Isempty(Q))
{
while(j<m)
{
move=Pop(Q);
Push(Q,move);
j++;
}
remove=Pop(Q);
printf("%d ",remove);
j=1;
}
}
int main()
{
Queue Q;
int length,m;
scanf("%d %d",&length,&m);
Setup(&Q,length);
Josephus(&Q,m);
return 0;
}
3.数组模拟
#include<stdio.h>
int ML=105;
int n,m;
int a[105];
int main()
{
scanf("%d%d",&n,&m);
int num=n,last=1;
while(num)
{
int cnt=0;
for(int i=last;cnt!=m;i++)
{
if(i>n) i%=n;
if(a[i]==-1) continue;
cnt++;
if(cnt==m)
{
a[i]=-1;
num--;
last=i+1;
printf("%d ",i);
break;
}
}
}
return 0;
}
这个思路和上述一致,就不多赘述了。