这个程序刚开始写完的时候爆出了一堆bug。
有几点要说一下,作为初学者,应该是会不经意间就范的。
1.对循环链表的空判断。
当循环链表为空的时候,自身的下一指针指向自身。
2.释放链表后忘记对最后的指针进行循环设置。
#if 0
程序名称:poker
作用:模拟魔术师发牌
描述:第一张牌为1,第二张牌就要从第二张重新数,为2.第三张就要从四张重新数。
以此类推,大致如下,括号内的值表示位置:
1(1) -> ?(2) -> 2(3) -> ?(4) -> ?(5) -> 3(6).....
#endif
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}Node, *LinkList;
#if 0
这是注释,用宏来写注释不会出现嵌套注释出现的错误。比如 /*/**/*/ 就会出现错误。
名称:CreateList[初始化链表]
调用:CreateList(LinkList L)
作用:生成并初始化13个节点的循环链表
参数:LinkList L,头结点
#endif
void CreateList(LinkList L)
{
LinkList p, r;
int PokerNum = 12; //牌数。每个花的牌总数为13张
//由于在调用前申请了一个节点所以这里设置为12张
L->data = 0;
r = L;
while (PokerNum)
{
p = (LinkList)malloc(sizeof(Node));
if(!p)
{
printf("申请内存错误!");
exit(1);
}
p->data = 0;
r->next = p;
r = p; //尾插法
PokerNum--;
}
r->next = L; //将尾部的下一个指针指向头,形成循环链表
}
#if 0
名称:CreatePork[设置牌序]
调用:CreatePoker(LinkList L)
作用:设置牌序,娱乐大众
#endif
void CreatePoker(LinkList L)
{
LinkList p;
int i;
int CountNum = 2; //每张牌计数
p = L;
p->data = 1;
while(1)
{
for(i = 0; i<CountNum; ++i)
{
p = p->next;
while(p->data != 0) //当当前的节点有值时,越过。
{
p = p->next;
}
}
if(p->data == 0) //当当前节点无值时可以写入数据
{
p->data = CountNum;
CountNum++;
if(CountNum == 14) //牌数够了就退出
{
break;
}
}
}
}
void FreeList(LinkList L)
{
LinkList p,l;
p = l = L;
printf("free:");
while (l->next!=L &&l!=NULL) //循环释放
{
l=l->next;
printf("%d ",p->data);
free(p);
p = l;
}
L->next=L; //设置头尾相连,为空表
}
void printlist(LinkList L)
{
LinkList p;
int i = 1;
p = L;
if(p == p->next)
{
printf("这是空表!");
exit(1);
}
while (p->next != L) //头尾相等时,为空表
{
printf("第 %d 张牌是 %d \n", i, p->data);
p = p->next;
i++;
}
printf("第 %d 张牌是 %d \n", i, p->data);
}
int main()
{
LinkList L = (LinkList)malloc(sizeof(Node));
if(!(L))
{
printf("申请内存错误!");
exit(1);
}
printf("初始化链表\n");
CreateList(L);
printlist(L);
printf("\n\n排序后:\n");
CreatePoker(L);
printlist(L);
printf("释放后:\n");
FreeList(L);
return 0;
}