数据结构 —— 约瑟夫环

Posted rcklos

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 —— 约瑟夫环相关的知识,希望对你有一定的参考价值。

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

数据结构 —— 约瑟夫环

这是用链表实现的,
约瑟夫环的规则是:
总数为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
请按任意键继续. . .

以上是关于数据结构 —— 约瑟夫环的主要内容,如果未能解决你的问题,请参考以下文章

循环链表实现约瑟夫环

数据结构线性表循环链表之约瑟夫环

约瑟夫环(超好的代码存档)--19--约瑟夫环--LeetCode面试题62(圆圈最后剩下的数字)

约瑟夫环(超好的代码存档)--19--约瑟夫环--LeetCode面试题62(圆圈最后剩下的数字)

约瑟夫环 代码

约瑟夫环