约瑟夫环(链表实现、指针实现)

 
#include <stdio.h>
#include <malloc.h>
#define LEN sizeof(struct node)
 
struct node
{
    int data;
    struct node *next;
} ;
 
int n;//全局变量,即在main也会存在n,不能再设局部变量n,否则会覆盖
 
struct node *creat()
{
    struct node *p,*q,*head;
    int i;
    p = (struct node *)malloc(LEN);
    head = p;
    p->data = 1;
 
    for(i = 2;i<=n;i++)
    {
        q = (struct node *)malloc(LEN);
        q->data = i;
        p->next = q;
        p = q;
    }
    p->next = head;//最后一个节点指向头部形成循环
    return head;
}
 
 
void Josephus(struct node *head,int m)
{
    int i=0;
    struct node *p = head,*tmp1;
    while(p->data != 1)//先找到开始的数的那个位置
        p = p->next;
    while(p->next != p)//指向自己
    {
        for(i=0;i<m-1;i++)//数到第m个
        {
            tmp1 = p;//tmp1在这里用于记录出局人的前一个人
            p = p->next;
        }
        printf("%d ",p->data);//输出出局的人的编号
        tmp1->next = p->next;//只需改变指针指向的数据元素,就可以去掉出局的那个人,从他下一个位置的人开始数
        free(p);//释放p指向的内存空间把出局人的位置都清空
        p = tmp1->next;//下一轮开始的位置
 
    }
    printf("\nThe last people is %d\n",p->data);
    free(p);//释放p指向的内存空间
}
 
int main()
{
    struct node *head;
    int m;
    scanf("%d %d",&n,&m);
    head = creat();
    Josephus(head,m);
    return 0;
 
 
 
来自 <https://www.cnblogs.com/mch5201314/p/9750102.html> 
#include <stdio.h>//
链表实现:
typedef struct node//节点存放一个数据和指向下一个节点的指针
{
    int data;//数据域
    struct node *pnext;//指针域,而且必须指向下一个同类型的节点的指针变量 struct node这个类型
} Node;
 
Node *create(int n)//创建n个节点的循环链表,函数名前加*表示返回Node类型的指针
{
    //先创建第1个节点
    Node *p,*q,*head;//p,q,head为指向struct node类型的指针变量,可以为其赋值
    int i;
    p = (Node *)malloc(sizeof(Node));//malloc函数为p动态分配内存空间
    head = p;//头部也就是第一个节点
    p->data = 1;
 
    for(i = 2;i<=n;i++)//再创建剩余节点
    {
        q = (Node *)malloc(sizeof(Node));//添加新节点所以重新分配内存空间,动态分配
        q->data = i;
        p->pnext = q;//p在q前面所以p指向q
        p = q;//这个时候p就得是q了,因为要往后创建 ,也就是说q就变成下一个节点的前驱
    }
    p->pnext = head;//最后一个节点指向头部,形成循环链表
    return head;
}
 
void Josephus(Node *head,int k,int m)//从编号为k(1<=k<=n)的人开始报数,数到m的那个人出列;
{
    int i;
    Node *p = head,*tmp1;
    while(p->data != k)//p指向的节点data为k,先找到开始的数的那个位置
        p = p->pnext;
 
    while(p->pnext != p)//模拟报数的过过程直到剩下自己一个人的时候,这时只有一个他指向自己
    {
        for(i=1;i<m;i++)//数到第m个
        {
            tmp1 = p;//tmp1在这里用于记录出局人的前一个人
            p = p->pnext;
        }
        printf("%d ",p->data);//输出出局的人的编号
        //链表的精髓在下面这个部分,看我发的图片,比数组好多了
        tmp1->pnext= p->pnext;//只需改变指针指向的数据元素,就可以去掉出局的那个人,从他下一个位置的人开始数
        free(p);//释放p指向的内存空间,彻底地把出局人的位置都清空他就不存在了
        p = tmp1->pnext;//下一轮开始的位置
 
    }
    printf("\nThe lucky people is %d\n",p->data);//最后的赢家
    free(p);//释放p指向的内存空间
}
 
int main()
{
    int n,m,s;
    scanf("%d %d %d",&n,&m,&s);
    Node *head = create(n);//调用函数创建含n个节点的循环链表
    Josephus(head,s,m);//调用模拟Josephus的函数
    return 0;
}
 
 
 
 
 
 
 
约瑟夫环指针实现
 
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    int i=0;
    int k=0;//报号数
    int m=0;//退出的人
    int n;//输入的号码
    int *p;
    int num[100];
    printf("please input a number:n=");
    scanf("%d",&n);
    p=num;
    for(i=0;i<n;i++)
        *(p+i)=i+1;
    i=0;
    while(m<n-1)
    {
        if(*(p+i)!=0)
            k++;
        if(k==3)
        {
            *(p+i)=0;
            k=0;
            m++;
        }
        i++;//此步是p+i=0且k!=3的时候,向后移,直到p+i!=0
        if(i==n)
            i=0;
    }
    while(*p==0)
        p++;//这一步也是一个循环,此时只剩下一个数字不是0,当p等于零的时候指针向后走,直到*p!=0,循环结束,输出p
    printf("the last one is %d",*p);
    return 0;
}
 
 
 
 
 
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值