user-0 提问: 约瑟夫环（C语言单循环链表实现）

回复:
user: user-1
content: #include<stdio.h> #include<stdlib.h> #include<string.h>  struct node {     int num;     char name[20];     struct node *next; };  struct node *create_singly_link(int num) {     struct node *head, *prev, *cur;     int i;      head = NULL;     for(i = 0; i < num; i++) {         cur = (struct node *)malloc(sizeof(struct node));         if (!cur) {             printf("Malloc error!");             return NULL;         }         cur->next = NULL;         cur->num = i+1;         snprintf(cur->name, 20-1, "%c", 'A'+i);         if (!head) {             head = cur;             prev = cur;         } else {             prev->next = cur;             prev = prev->next;         }     }     prev->next = head;     return head; }  static void test_print(struct node *phead) {     struct node *pcur = phead->next;      printf("num = %d\t name = %s\n", phead->num, phead->name);     while (pcur != phead) {         printf("num = %2d\t name = %s\n", pcur->num, pcur->name);         pcur = pcur->next;     } }  int output( struct node *head, int start, int step, int total) {     struct node *p, *q;     int count = 0;     int num = 0, i;      q = head;      for(i = 0; i < start; i++)         q = q->next;      while(count < total-1) {         p = q->next;         num++;         if(!(num % step)) {             q->next = p->next;             printf("%s\n", p->name);             free(p);             count++;         } else {             q = p;         }     }     printf("num = %d\t, name = %s\n", q->num, q->name);     free(q);      return 0; } int main(int argc, const char *argv[]) {     int total, step, start;     struct node *head;      printf("Please input total test number: ");     scanf("%d", &total);     head = create_singly_link(total);     test_print(head);      printf("Please input start position and steps: ");     scanf("%d%d", &start, &step);      output(head, start, step, total);      return 0; } 供参考～

user: user-2
content: 使用链表的话，不适合用带有空表头的实现。因为表尾要指向第一个有意义的数据，而且第一个位置也有可能被删除。 表头不含实际数据的话，就有两个指针指向第一个数据，容易操作不方便实现。   主体程序大抵如此：   #include <stdio.h> #include <stdlib.h>  typedef struct Node {     int data;     struct Node *next; } Node;  static void debug_print_list(struct Node *l);  Node* Init(int n) {     int i;     Node *node, *head = NULL, *prev = NULL;      for(i = 0; i < n; i++) {         node = (Node*) malloc(sizeof(Node));         node->data = i;         node->next = NULL;          if (head == NULL) {             head = node;         }          if (prev != NULL) {             prev->next = node;         }         prev = node;     }     prev->next = head;      return head; }  Node *Order(Node *L, int n, int m) {     Node *p = NULL, *q = L;  // p points to previous node, q points to current node     int counter = 0;      while (1) {         if (q->next == q)             break;          counter += 1;         printf("[DBEUG]: node %d reports %d\n", q->data, counter);         if (counter == m) {             // assert(p != NULL); corner case need to be considered             printf("[DEBUG]: Removing node %d\n", q->data);             p->next = q->next;             free(q);             q = p->next;              counter = 0;             debug_print_list(q);             continue;         }          p = q;         q = q->next;     }      return q; }  int main() {     Node* L, *result;     int n,m;     n = 9;     m = 3;      L=Init(n);     debug_print_list(L);      result = Order(L, n, m);     printf("n=%d, m=%d, final-node=%d\n", n, m, result->data);     return 0; }  void debug_print_list(Node *l) {     Node *p = l;      while (1) {         printf("%d", p->data);         if (p->next != l)             printf(" --> ");         p = p->next;          if (p == l)             break;     };      printf("\n"); }

user: user-3
content: typedef的一般用法是兩個不同的名字，比如typedef _Node { ... } Node; malloc分配内存後，應該判斷返回是否NULL，否則對其操作可能出錯 Init函數中對首節點的處理也有問題，當n為1時，p->next=q會導致鏈表不是以NULL結尾