數據結構 —— 約瑟夫環


今日一言:
謝謝你,成為我前進的理由。
——《言葉之庭》

數據結構 —— 約瑟夫環

這是用鏈表實現的,
約瑟夫環的規則是:
總數為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("沒能完成任務!!!\n");
    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("沒能完成任務!!!\n");
    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("游戲開始......\n");
    count = 0;
    while(list.size>1){
        count = (count+k-1)%list.size;
        printf("%d號同學被淘汰.\n",getElem(&list,count)->value);
        removeIndexL(&list,count);
    }
    printf("最后的贏家是 --> %d號同學!\n",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
請按任意鍵繼續. . .


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM