洛谷P1996 约瑟夫问题(C语言)

681 阅读2分钟

@[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;
    }

这个思路和上述一致,就不多赘述了。