• 用循环链表实现Josephus问题


      Josephus问题:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列。如此反复直到所有的人全部出列为止。

      思路:构建一个没有头结点的循环链表,实现自己的删除函数,数到第几个结点就把这个结点从链表中删除,然后重新数。

      难点在于写删除函数。

      代码如下:

     

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct student * PNode;
    
    typedef struct student{
        int data;
        PNode next;    
    }Node;
    
    PNode create(int n)
    {
        PNode head=(PNode)malloc(sizeof(Node));
        PNode p;
        int data=0;
        p=head;
        printf("请输入结点的值
    ");
        scanf("%d",&data);
        p->data=data;
        while(--n)
        {
            p->next=(PNode)malloc(sizeof(Node));
            p=p->next;
            printf("请继续输入结点的值
    ");
            scanf("%d",&data);
            p->data=data;
        }
        p->next=head;
        return head;
    }
    void print(PNode link)
    {
        PNode head,p;
        if(link==NULL) return;
        head=link;
        p=link;
        while(p->next!=head)
        {
            printf("%d ",p->data);
            p=p->next;
        }
        printf("%d
    ",p->data);
    }
    
    
    
    PNode del(PNode link,int num)
    {
        PNode head=link;
        PNode p=link;
        PNode temp;
        if(link==NULL)
        {
        //       printf("链表为空");
            return NULL;
        }     
        //      printf("要删除结点的值为%d
    ",num);
        //删除头结点    
        if(p->data==num)
        {
            if(p->next==head)   //只剩下一个结点的情况
            {
        //            printf("链表删除完毕。
    ");
                free(link); 
                return NULL;
            }
            while(p->next!=head)
                p=p->next;
            temp=p->next;
            p->next=p->next->next;
            head=p->next;
            free(temp);
            return head;
        }    
        //删除非头结点
        while(p->next->data!=num && p->next!=head)
        {
            p=p->next;
        }
        if(p->next==head)
        {
       //        printf("没有找到这样的结点。
    ");
            return head;
        }    
        temp=p->next;
        p->next=p->next->next;
        free(temp);
        return head;
    }
    
    void Josepus(PNode link,int n,int k,int m)
    {
        if(link==NULL)
        {
            printf("链表为空
    ");
            return;
        }    
        printf("打印出列的顺序:");
        PNode p=link;
        int r=k+m-2;  //r为链表要移动的次数,根据图示来进行r大小的确认
        while(r--)
        {
            p=p->next;
        }
        printf("%d ",p->data);
        p=del(p,p->data);
        while(p!=NULL)
        {        
            r=m-1;
            while(r--)
            {    
                p=p->next;
            }
            printf("%d ",p->data);
            p=del(p,p->data);
        }
        printf("
    ");
    }
    
    int main(void)
    {
            int n,num;
            int s,m;
            printf("请输入要创建多少个结点
    ");
            scanf("%d",&n);
            PNode link=create(n);
            printf("打印初始链表
    ");
            print(link);
            printf("请输入要从第几个人开始报数
    ");
            scanf("%d",&s);
            printf("请输入要报多少个人
    ");
            scanf("%d",&m);
            Josepus(link,n,s,m);/*      测试删除函数用地
             while(1)
        {
            printf("请输入要删除的结点的值
    ");
            scanf("%d",&num);
            link=del(link,num);
            if(link==NULL)
                break;
            printf("打印删除后的链表
    ");
            print(link);
        }
    */
        return 0;
    }

     程序猿必读

  • 相关阅读:
    SAP ABAP dialog 获取屏幕字段值 F4搜索帮助
    IDEA快捷键大全
    其他21$nextTick
    其他18nvm安装
    vue基础16组件间传递
    其他22scoped、>>>、/deep/、::vdeep
    其他17解决onmouseover多次触发问题
    其他19实现vuex与表单数据动态改变
    其他20持久化存储
    VS 提示找不到某个类
  • 原文地址:https://www.cnblogs.com/longzhongren/p/4417904.html
Copyright © 2020-2023  润新知