大二我们开始学数据结构了,幸好暑假在家好好看了下,现在学的不是特别吃力,一份耕耘,一份收获。呵呵。
约瑟夫问题大家都清楚吧,数据结构书本后面有道题目就是讲它。在下一看,兴趣来了,就思考了一会儿。然后就敲程序。
#include <stdio.h>
#include <alloc.h>
#include <time.h>
我先包含三个头文件,前两个就不用说了吧,后面一个time后文件,我是想让它自动生成密码,省得自己输入了。呵呵,偷下懒~
typedef struct cycle
{
int key;
int node;
struct cycle *next;
}*Cycle;
定义数据类型,key——密码,node——每个人的编号。
然后下面就是创建二十个结点,带头结点21个。密码范围0~20.
Cycle Create()
{
Cycle head;
Cycle p, last;
short int flag = 1, NodeAdder = 0;
if(NULL == (head = (Cycle)malloc(sizeof(struct cycle))))
{
printf("Error, sufficient memory!/n");
exit(0);
}
head->key = -1;
head->node = -1;
head->next = NULL;
last = head;
while(flag)
{
if(NULL == (p = (Cycle)malloc(sizeof(struct cycle))))
{
printf("Error, insufficient memory!/n");
exit(0);
}
p->node = ++NodeAdder;
p->key = rand() % 21;
p->next = NULL;
if(NULL != head->next)
{
last->next = p;
}
else
{
head->next = p;
}
last = p;
last->next = head;
if(NodeAdder >= 20)
{
flag = 0;
}
}
return head;
}
输出循环单链表,其实这个函数对程序并没有多大作用,只是当时为了检测循环单链表的生成情况。
void Output(Cycle head)
{
Cycle p = head->next;
while(-1 != p->node)
{
printf("%d : %d/n", p->node, p->key);
p = p->next;
}
}
从循环单链表中输出每个结点的密码,这个函数里先确定报数的最大上限,我这里输入20.
然后输出结果:
Please input the MaxNum: 20
node : key
20 : 1
1 : 0
3 : 12
6 : 19
10 : 15
15 : 16
4 : 2
13 : 9
7 : 4
19 : 6
18 : 7
5 : 9
12 : 10
9 : 5
14 : 17
11 : 12
8 : 16
17 : 13
16 : 7
2 : 2
Press any key to continue . . .
void OutFromQueue(Cycle head)
{
Cycle p = head;
Cycle pre = p;
short int MaxNum = 0, count = 0, ListLength = 20;
//count 计数而用,当count ++到了20时输出当时结点密码,并将count重新置0
//ListLength为链表的长度20
printf("Please input the MaxNum: ");
scanf("%d", &MaxNum);
getchar();
printf("node : key/n");
while((pre = p) && ((p = p->next) != NULL))
{
if(ListLength <= 0) //当链表20个结点都出列时,将头结点的next置空,则推出循环
{
head->next = NULL;
}
if(p == head) //如果p和头结点指针相等,则不运行
{
continue;
}
count++;
if(MaxNum == count)
{
printf("%2d : %2d/n", p->node, p->key);
pre->next = p->next;
free(p);
p = pre; /*这个地方我本来写的p = pre->next,后来几经调试,才发现是错误的!改成p=pre后结果才正确,呜呜,走 了很多弯路*/
ListLength--;
count = 0;
}
}
}
int main()
{
Cycle head;
srand((unsigned int)time(NULL));
clrscr();
head = Create();
Output(head); //检测链表生成情况
OutFromQueue(head);
system("PAUSE");
return 0;
}