数据结构 - 单循环链表:选首领(C)

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程

/*
 * ChiefElection.c - by FreeMan
 *
 * 选首领。
 * N个游戏者围成一圈,从第一个人开始顺序报数1,2,3。凡报到3者退出圈子,最后留在圈子里的人为首领。
 */

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {

    // 游戏者的编号。
    int code;
    struct Node *next;
} Node, *LinkList;

/**
 * 创建一个结点数为n的单循环链表,返回值为游戏编号为1的结点的指针。
 * @param n The size of list.
 * @return The head pointer.
 */
LinkList CreateList(int n) {
    LinkList head, p;
    int i;

    // 创建循环链表的第一个结点。
    head = (Node *)malloc(sizeof(Node));
    if (!head) {
        printf("Memory allocation error!\n");
        return NULL;
    }
    head->code = 1;
    head->next = head;

    // 尾插法创建循环链表的其余n-1个结点。
    for (i = n; i > 1; --i) {
        p = (Node *)malloc(sizeof(Node));
        if (!p) {
            printf("Memory allocation error!\n");
            return NULL;
        }
        p->code = i;
        p->next = head->next;
        head->next = p;
    }
    return head;
}

/**
 * 输出链表中结点的数据。
 * @param head The head pointer.
 */
void Output(LinkList head) {
    LinkList p;
    p = head;
    do {
        printf("%-4d", p->code);
        p = p->next;
    } while (p != head);
}

/**
 * 选首领。
 * @param head The head pointer.
 * @param n The size.
 */
void Play(LinkList head, int n) {
    LinkList p, q;
    int c = 0, k;
    p = head;
    c = 1;
    k = n;
    while (k > 1) {

        // 当c等于2时,p指向的结点的后继即为将被删除的结点。
        if (c == 2) {
            q = p->next;
            p->next = q->next;
            printf("%-4d", q->code);
            free(q);
            c = 0;
            k--;
        }
        c++;
        p = p->next;
    }

    // 输出最后留在圈子里的人的编号。
    printf("\nThe winner is [%-d].\n", p->code);
}

int main(void) {
    LinkList head;
    int n;
    printf("Input the number of players: ");
    scanf_s("%d", &n);

    // 创建单循环链表。
    head = CreateList(n);
    if (head) {

        // 输出单循环链表中结点的信息。
        printf("The link list is:\r\n");
        Output(head);
        printf("\r\nThe chief election process is:\r\n");
        Play(head, n);
    }
    return 0;
}

// Output:
/*
Input the number of players: 100
100
The link list is:
1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20
21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40
41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60
61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80
81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99  100
The chief election process is:
3   6   9   12  15  18  21  24  27  30  33  36  39  42  45  48  51  54  57  60
63  66  69  72  75  78  81  84  87  90  93  96  99  2   7   11  16  20  25  29
34  38  43  47  52  56  61  65  70  74  79  83  88  92  97  1   8   14  22  28
35  41  49  55  62  68  76  82  89  95  4   13  23  32  44  53  64  73  85  94
5   19  37  50  67  80  98  17  40  59  86  10  46  77  26  71  31  100 58
The winner is [91].

*/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值