Josephu问题链表方法

来源:互联网 发布:js object对象 编辑:程序博客网 时间:2024/06/05 08:29

Josephu问题:编号为0到N-1的N个人围成一圈,然后从1开始报数,报到M的那个人被杀掉,剩下的人接着从1开始报数,求最后的幸存者编号。

前面给出了该问题的数学解法,下面贴上链表方法,直接模拟整个过程。

#include <stdio.h>#include <stdlib.h>struct node {    int num;    struct node *next;};typedef struct node *node_t;node_t create_circular_list(int n);int josephu(int n, int m);int main(int argc, char **argv){    int N, M;    printf("input N and M:");    scanf("%d%d", &N, &M);    printf("result: %d\n", josephu(N, M));    return 0;}node_t create_circular_list(int n){    if (n <= 0)        return NULL;    node_t head, tmp;    head = (node_t)malloc(sizeof(*head));    if (NULL == head) {        printf("malloc erro, line: %d\n", __LINE__);        return NULL;    }    head->num = 0;    head->next = head;    int i;    tmp = head;    for (i = 1; i < n; i ++) {        tmp = (tmp->next = (node_t)malloc(sizeof(*tmp)));        if (NULL == tmp) {            printf("malloc erro, line: %d\n", __LINE__);            return NULL;        }        tmp->num = i;        tmp->next = head;    }    return head;}int josephu(int n, int m){    node_t head = create_circular_list(n);    if (NULL == head) {        printf("create list erro\n");        return -1;    }    node_t *curr = &head;//此处仅仅是为了练习二级指针在单向链表中的删除操作,可以换别的简单易懂的方法实现    while (--n) {        node_t entry = *curr;        int i;        for (i = 1; i < m; i ++) {            curr = &entry->next;            entry = entry->next;        }        *curr = entry->next;//kill        free(entry);    }    int ret = (*curr)->num;    free(*curr);    return ret;}


0 0