n 个小朋友围成一个圈玩游戏,依次报号,报到指定的号码时出列,从出列的小朋友下一个继续之前的游戏,问最后一个出现的 小朋友编号,编码实现(单循环链表实现)
#include <stdio.h>
#include<stdlib.h>
//类型重命名
typedef int DATA;
//定义一个单循环链表结构
typedef struct node
{
DATA data;
struct node *next;
}NODE;
//创建结点并插入
int sclist_insert(NODE** head,DATA data)
{
NODE* pNew = (NODE*)malloc(sizeof(NODE));
if(!pNew)
{
puts("error!");
return -1;
}
pNew -> data = data;
pNew -> next = pNew;
if(*head == NULL)
{
*head = pNew;
return 0;
}
NODE* p = *head, *q = NULL;
while(p)
{
q = p;
p = p -> next;
if(p == *head)
break;
}
pNew -> next = *head;
q -> next = pNew;
//*head = pNew; //头插法
return 0;
}
//遍历节点并打印
void sclist_print(const NODE* head)
{
const NODE* p = head;
while(p)
{
printf("%d\t",p -> data);
p = p -> next;
if(p == head)
break;
}
}
//释放创建的链表,防止内存泄漏
void sclist_free(NODE** head)
{
NODE* p = *head,*q = NULL;
while(p)
{
q = p;
p = p -> next;
free(q);
}
*head = NULL;
}
//删除指定数的结点
int sclist_delete(NODE** head,DATA data)
{
if(*head == NULL)
return -1;
NODE* p = *head, *q = NULL;
int i = 0;
while(1)
{
if(p -> next == p)
{
return (p -> data);
}
for(i = 0; i < data - 1; i++)
{
q = p;
p = p ->next;
}
q ->next = p -> next;
printf("%d\t", p -> data); //查看删除的是否正确
free(p);
p = q->next;
}
}
int main()
{
int a[] = {1,2,3,4};
NODE* head = NULL;
int n = sizeof a / sizeof a[0] ;
register int i = 0;
for(; i < n ; i++)
sclist_insert(&head, a[i]);
sclist_print(head);
printf("\n");
int data = sclist_delete(&head,4);
printf("\n");
printf("%d\n", data);
sclist_free(&head);
return 0;
}