队列的简单应用-杨辉三角和约瑟夫环

来源:互联网 发布:软件咨询服务 单位 编辑:程序博客网 时间:2024/05/21 10:19

接上一篇,由于队列的内容相对比较简单,所以这次举两个实际的问题—杨辉三角和约瑟夫环。(不知道这两个问题的童鞋可以自行百度。)

先看杨辉三角。使用队列解决这个问题有1个小的技巧:第一就是在两个1的两边增加两个0,通过0来标记这一层的结束。先看程序吧:

//遍历循环链表并打印void printQueue(Queue *q){for(int i = 0; i < Qlength(q);++i)printf("%d ",q->data[(q->front+i+q->Qsize)%q->Qsize]);printf("\n");}//输出杨辉三角的第n行的元素void YangHuiTriangle(int n){int level = n;//printf("请输入");Queue myQueue;initQueue(&myQueue,level);//初始化第一行:使用0作为一行结束的标记enQueue(&myQueue,0);enQueue(&myQueue,1);enQueue(&myQueue,1);enQueue(&myQueue,0);int x,y;for(int m = 1;m < level;++m){do{//将整个队列的前两个求和放入队尾,并删除队首元素deQueue(&myQueue,&x);getHead(&myQueue,&y);enQueue(&myQueue,x+y);}while(y!=0);//填充队尾标记enQueue(&myQueue,0);}printQueue(&myQueue);}


 

这个做法很巧妙:先让元素出队,再获得后面的那个元素,然后再将二者相加以后入队,重复这个工作,直到遇见0为止。这个0既是上一层队列结束的0,又是这一层队列开始的0.

下面是约瑟夫环的程序:(我承认我写的很丑陋,但是貌似可以用)

//输入size-1个数,每隔interval个数将它去掉,输出最后的结果void Josephus(int size,int interval){Queue JQueue;initQueue(&JQueue,size);//给原先的队列赋出值for(int l = 0; l < size-1; ++l){enQueue(&JQueue,l);}//先打印赋值结果printQueue(&JQueue);int sum = size-1;//计数器:用来计算隔了多个数int counter = 0;int  i = 0;//每隔interval个数(包含这个数)去掉一个数,最后会剩下interval-1个数while(sum != interval-1){//printf("i = %d\n",i);//int j = i%(JQueue.Qsize-1);//int k = JQueue.data[(JQueue.front+i+JQueue.Qsize-1)%(JQueue.Qsize-1)];//printf("第%d个元素,值为%d\n",j,k);//如果这个元素之前已经被去掉过,那么跳过它if(JQueue.data[(JQueue.front+i+JQueue.Qsize-1)%(JQueue.Qsize-1)] == -1){//printf("跳过第%d个元素\n",i%JQueue.Qsize);++i;continue;}if((counter+1)%interval == 0){//如果需要被去掉,则标记为-1JQueue.data[(JQueue.front+i+JQueue.Qsize-1)%(JQueue.Qsize-1)] = -1;//printf("第%d个元素被置为-1\n",i%(JQueue.Qsize-1));--sum;counter = 0;}else++counter;++i;}for(int i = 0; i < Qlength(&JQueue);++i){if(JQueue.data[JQueue.front+i] != -1)printf("%d ",JQueue.data[(JQueue.front+i+JQueue.Qsize)%JQueue.Qsize]);}printf("\n");destroyQueue(&JQueue);}


 

可以通过打开调试语句来看到他是如何一步一步执行的。

这个问题貌似有更简单的解法,这里就不深入讨论了。

原创粉丝点击