user-0 提问: 求助，约瑟夫环问题，删除函数中有逻辑错误导致运行结果不对

回复:
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: 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  百度搜相关关键字。

user: user-3
content: #include <stdio.h> #include <string.h> #include <stdlib.h>  typedef struct list //定义链表类型 { 	int number, code; 	struct list *next; } LIST, *ZLIST;  //计算环形链表元素个数 int count(ZLIST p_head) { 	if(p_head == NULL) 	{ 		return 0; 	} 	int i = 1; 	ZLIST p_tmp = p_head; 	while(p_tmp->next != p_head) 	{ 		p_tmp = p_tmp ->next; 		++i; 		// printf(" %d  ",i); 	} 	return i; }  void deletelist(ZLIST p_head, int n, int m) //找出每轮出列的人并删除，t为尾指针，n为总人数，m为初始报数上线 { 	// int i, k = m; 	// ZLIST p, pre; 	// pre = t; 	// while (pre->next != pre)				--》结束条件有问题 	// { 	// 	for (i = 0; i < k; i++) 	// 		pre = pre->next; 	// 	p = pre->next; //找到要删除元素 	// 	printf("%4d", p->number); 	// 	k = p->code;		 //记录密码 	// 	pre->next = p->next; //链接				 	// 	free(p); 	// } 	int k = m; 	ZLIST p_node ; 	ZLIST p_mid = p_head; 	ZLIST p_end; 	while(1) 	{ 		for(int i = 0; i < k -1 ; ++i) 		{ 			p_node = p_mid; 			p_mid = p_mid ->next; 		} 		p_end = p_mid -> next;			//这里要把链表连起来不能断了 		p_node->next = p_end; 		printf("%-4d",p_mid->number); 		k = p_mid->code; 		free(p_mid); 		p_mid = p_end; 		if ( count(p_mid) == 2) 		{ 			break; 		} 	} 	printf("p_mid :[%d], p_mid->next:[%d]", p_mid->number, p_mid->next->number); }  ZLIST CreateList(int num) { 	ZLIST p_head = NULL, p_tmp = NULL; 	for (int i = 0; i < num; ++i) 	{ 		ZLIST newNode = (ZLIST)malloc(sizeof(LIST)); 		if (newNode == NULL) 		{ 			printf("分配内存失败 "); 			return NULL; 		} 		newNode->number = i + 1; 		newNode->code = 3; 		newNode->next = NULL; 		if ( p_head != NULL) 		{ 			p_tmp->next = newNode; 			p_tmp = p_tmp->next; 		} 		else 		{ 			p_head = newNode; 			p_tmp = p_head; 		} 	} 	p_tmp -> next = p_head; 	return p_head; }  void print(ZLIST p_head) { 	ZLIST p_tmp = p_head; 	do 	{ 		printf("number:[%d],code:[%d]\n",p_tmp->number, p_tmp->code); 	}while(p_head != (p_tmp = p_tmp->next)); }  int main() { 	ZLIST p_list; 	print(p_list = CreateList(41)); 	deletelist(p_list, 41, 3); 	return 0; }

user: user-3
content: #include <stdio.h> #include <string.h> #include <stdlib.h>  typedef struct list //定义链表类型 { 	int number, code; 	struct list *next; } LIST, *ZLIST;  //计算环形链表元素个数 int count(ZLIST p_head) { 	if(p_head == NULL) 	{ 		return 0; 	} 	int i = 1; 	ZLIST p_tmp = p_head; 	while(p_tmp->next != p_head) 	{ 		p_tmp = p_tmp ->next; 		++i; 		// printf(" %d  ",i); 	} 	return i; }  void deletelist(ZLIST p_head, int n, int m) //找出每轮出列的人并删除，t为尾指针，n为总人数，m为初始报数上线 { 	// int i, k = m; 	// ZLIST p, pre; 	// pre = t; 	// while (pre->next != pre)				--》结束条件有问题 	// { 	// 	for (i = 0; i < k; i++) 	// 		pre = pre->next; 	// 	p = pre->next; //找到要删除元素 	// 	printf("%4d", p->number); 	// 	k = p->code;		 //记录密码 	// 	pre->next = p->next; //链接				 	// 	free(p); 	// } 	int k = m; 	ZLIST p_node ; 	ZLIST p_mid = p_head; 	ZLIST p_end; 	while(1) 	{ 		for(int i = 0; i < k -1 ; ++i) 		{ 			p_node = p_mid; 			p_mid = p_mid ->next; 		} 		p_end = p_mid -> next;			//这里要把链表连起来不能断了 		p_node->next = p_end; 		printf("%-4d",p_mid->number); 		k = p_mid->code; 		free(p_mid); 		p_mid = p_end; 		if ( count(p_mid) == 2) 		{ 			break; 		} 	} 	printf("p_mid :[%d], p_mid->next:[%d]", p_mid->number, p_mid->next->number); }  ZLIST CreateList(int num) { 	ZLIST p_head = NULL, p_tmp = NULL; 	for (int i = 0; i < num; ++i) 	{ 		ZLIST newNode = (ZLIST)malloc(sizeof(LIST)); 		if (newNode == NULL) 		{ 			printf("分配内存失败 "); 			return NULL; 		} 		newNode->number = i + 1; 		newNode->code = 3; 		newNode->next = NULL; 		if ( p_head != NULL) 		{ 			p_tmp->next = newNode; 			p_tmp = p_tmp->next; 		} 		else 		{ 			p_head = newNode; 			p_tmp = p_head; 		} 	} 	p_tmp -> next = p_head; 	return p_head; }  void print(ZLIST p_head) { 	ZLIST p_tmp = p_head; 	do 	{ 		printf("number:[%d],code:[%d]\n",p_tmp->number, p_tmp->code); 	}while(p_head != (p_tmp = p_tmp->next)); }  int main() { 	ZLIST p_list; 	print(p_list = CreateList(41)); 	deletelist(p_list, 41, 3); 	return 0; }