zoukankan      html  css  js  c++  java
  • 数据结构 —— 约瑟夫环

    今日一言:
    谢谢你,成为我前进的理由。
    ——《言叶之庭》

    数据结构 —— 约瑟夫环

    这是用链表实现的,
    约瑟夫环的规则是:
    总数为N的同学围成一个圆环,并将这些同学从1开始编号,
    游戏开始时,约定好一个数字K,从1号同学开始轮着叫号,
    当叫到K号时,该同学淘汰,下一位同学从1开始重新叫号,
    只要叫到K号即淘汰,留下来的最后一位同学赢得游戏。


    C语言实现

    /*********************************************************************************
     *
     * 约瑟夫环
     * create: 2020年5月24日 22点22分 
     * author: LOS(小鱼) 
     *
     * *******************************************************************************/
     
    #include<stdio.h>
    #include<stdlib.h>

    /*********************************************************************************
     * 链表需要 
     ********************************************************************************/
     

    typedef struct Elem{
        int value; 
        struct Elem *prev,*next;
    }Elem; 

    struct{
        Elem elems[200];
        int size;
    } Elems; // 全部的链表数据存储在这里 ( 不销毁, 但会覆盖 ) 

    // 定义链表结构
    typedef struct {
        struct Elem *first;
        struct Elem *last;
        int size;
    } LinkList; 

    // 初始化链表
    void initLinkList( LinkList *list ){
        list->size = 0;


    // 获取表长 
    int getSizeL(LinkList *list){
        return list->size;
    }

    void addFirst(LinkList *list,Elem *elem){
        if( !getSizeL(list) ){
            list->first = elem;
            list->last = elem;
        }
        else {
            elem->prev = list->last;
            elem->next = list->first;
            list->last->next = elem;
            list->first->prev = elem;
            list->first = elem;
        }
        list->size++;
    }

    // 添加元素 
    void addLast(LinkList *list,Elem *elem){
        if( !getSizeL(list) ){
            list->first = elem;
            list->last = elem;
        } else {
            elem->prev = list->last;
            elem->next = list->first;
            list->last->next = elem;
            list->first->prev = elem;
            list->last = elem;
        }
        list->size++;
    }

    Elem * getElem(LinkList *listint index){
        int i ;
        Elem *elem;
        // 逐项访问 
        if ( index > list->size/2 ){
            elem = list->last;
            for ( i = list->size-1 ; i >= index ; i-- ){
                if( i == index ){
                    return elem;
                }
                elem = elem->prev;
            }
        } else {
            elem = list->first;
            for ( i = 0 ; i <= index ; i++ ){
                if( i == index ){
                    return elem;
                }
                elem = elem->next;
            }
        }
    }

    // 移除元素 
    void removeIndexL(LinkList *listint index){
        int i;
        Elem *elem = list->first;
        int flag = 0;
        for ( i = 0 ; i <= index ; i++ ){
            if( i == index ){
                elem->prev->next = elem->next;
                elem->next->prev = elem->prev;
                iflist->first == elem ){
                    list->first = elem->next;
                }
                iflist->last == elem ){
                    list->last = elem->prev;
                }
                flag = 1;
            }
            elem = elem->next;
        }
        if(!flag) printf("没能完成任务!!! ");
        list->size--;
    }

    void removeElemL(LinkList *list, Elem *e){
        int i;
        Elem *elem = list->first;
        int flag = 0;
        for ( i = 0 ; i < list->size ; i++ ){
            if( elem == e ){
                elem->prev->next = elem->next;
                elem->next->prev = elem->prev;
                iflist->first == elem ){
                    list->first = elem->next;
                }
                iflist->last == elem ){
                    list->last = elem->prev;
                }
                flag = 1;
            }
            elem = elem->next;
        }
        if(!flag) printf("没能完成任务!!! ");
        list->size--;
    }

    /*********************************************************************************
     * 链表需要 
     ********************************************************************************/
     

    Elem *createElemint value ){
        Elem *p = Elems.elems+Elems.size;
        p->value = value;
        Elems.size++;
        if( Elems.size == 200 ) Elems.size = 0// 注意不能超过200,否则数据错误
        return p; 
    }

    void main(){
        LinkList list;
        int n,k,i,count;
        printf("请输入参与游戏的总人数:");
        scanf("%d",&n);
        fflush(stdin);
        printf("请输入淘汰的间隔数:");
        scanf("%d",&k);
        fflush(stdin);
        initLinkList(&list);
        for ( i = 0 ; i < n ; i++ ){
            Elem *elem = createElem(i+1);
            addLast(&list,elem);
        }
        printf("游戏开始...... ");
        count = 0;
        while(list.size>1){
            count = (count+k-1)%list.size;
            printf("%d号同学被淘汰. ",getElem(&list,count)->value);
            removeIndexL(&list,count);
        }
        printf("最后的赢家是 --> %d号同学! ",list.last->value);
    }

    运行结果

    请输入参与游戏的总人数:10
    请输入淘汰的间隔数:3
    游戏开始......
    3号同学被淘汰.
    6号同学被淘汰.
    9号同学被淘汰.
    2号同学被淘汰.
    7号同学被淘汰.
    1号同学被淘汰.
    8号同学被淘汰.
    5号同学被淘汰.
    10号同学被淘汰.
    最后的赢家是 --> 4号同学!

    --------------------------------
    Process exited after 2.205 seconds with return value 27
    请按任意键继续. . .

  • 相关阅读:
    网页中添加下划线的方法汇总及优缺点
    git备注
    微信小程序封装年月日时分组件
    微信小程序底部弹窗动画
    微信小程序返回上一页的方法并传参
    微信小程序组件封装
    taro中子父传值
    taro初识一
    reactjs中使用高德地图计算两个经纬度之间的距离
    vue中使用scss
  • 原文地址:https://www.cnblogs.com/rcklos/p/12953250.html
Copyright © 2011-2022 走看看