3.10队列应用

3.10队列应用

队列的应用举例:

1.打印杨辉三角

在这里插入图片描述
算法思想
由上图可看出杨辉三角形的特点:即每一行的第一个元素和最后一个元素均为 1,其他位置上的数字是其上一行中与之相邻的两个整数之和。

所以第 i 行上的元素要由第 i-1 行中的元素来生成。可以利用循环队列实现打印杨辉三角形的过程:在循环队列中依次 存放第 i-1 行上的元素,然后逐个出队并打印,同时生成第 i 行元素并入队。

在整个过程中, 杨辉三角形中元素的入队顺序如下图所示。
在这里插入图片描述
下面以用第 6 行元素生成第 7 行元素为例说明具体过程。

  • ⑴ 第 7 行的第一个元素 1 入队。 element[rear]=1; rear=(rear +1 )% MAXSIZE;
  • ⑵ 循环做以下操作,产生第 7 行的中间 5 个元素并入队。 element[rear]=element[front]+element[(front+1) %MAXSIZE]; rear=(rear +1 )% MAXSIZE; front=(front+1)%MAXSIZE;
  • ⑶ 第 6 行的最后一个元素 1 出队。 front=(front+1)%MAXSIZE;
  • ⑷ 第 7 行的最后一个元素 1 入队。 element[rear]=1; rear=(rear +1 )% MAXSIZE;

下面给出打印杨辉三角形的前 N 行元素的具体算法。

void YangHuiTriangle( ) 
{ 
	SeqQueue  Q; 
	InitQueue (&Q); 
	EnterQueue (&Q,1);  /* 第一行元素入队*/ 
	for(n=2;n<=N;n++)   /* 产生第 n 行元素并入队,同时打印第 n-1 行的元素*/ 
	{ 
		EnterQueue (&Q,1);   /* 第 n 行的第一个元素入队*/ 
		for(i=1;i<=n-2;i++)  /* 利用队中第 n-1 行元素产生第 n 行的中间 n-2 个元素 并入队*/ 
		{ 
			DeleteQueue (&Q,&temp); 
			Printf(%d”,temp);     /* 打印第 n-1 行的元素*/ 
			GetHead(Q,&x); temp=temp+x;      /*利用队中第 n-1 行元素产生第 n 行元素*/ 
			EnterQueue (&Q,temp);   
		} 
		DeleteQueue (&Q, &x);   
		printf(%d”, x);    /* 打印第 n-1 行的最后一个元素 */ 
		EnterQueue (&Q, 1)   /* 第 n 行的最后一个元素入队 */ 
	} 
	while(!IsEmpty(Q))     /* 打印最后一行元素 */  
	{ 
		DeleteQueue (&Q, &x);   
		print(%d”, x);        
	} 
}

上面的算法只是逐个打印出了杨辉三角形前 N 层中的数据元素,并没有按三角形的形式输 出,读者可以自己加入坐标数据,然后在屏幕上打印出杨辉三角形。

2.键盘输入循环缓冲区问题

在操作系统中,循环队列经常用于实时应用程序。

例如,当程序正在执行其他任务时,用户可以从键盘上不断键入所要输入的内容。系统在利用这种分时处理方法时,用户键入的内容不能在屏幕上立刻显示出来,直到当前正在工作的那个进程结束为止。

但在这个进程执行时, 系统是在不断地检查键盘状态,如果检测到用户键入了一个新的字符,就立刻把它存到系统缓冲区中,然后继续运行原来的进程。

当当前工作的进程结束后,系统就从缓冲区中取出键 入的字符,并按要求进行处理。

这里的键盘输入缓冲区采用了循环队列。

队列的特性保证了 输入字符先键入、先保存、先处理的要求,循环结构又有效地限制了缓冲区的大小,并避免 了假溢出问题。

问题描述

有两个进程同时存在于一个程序中。其中第一个进程在屏幕上连续显示字符“A”,与此同时,程序不断检测键盘是否有输入,如果有的话,就读入用户键入的字符并保存到输入缓冲区中。在用户输入时,键入的字符并不立即回显在屏幕上。当用户键入一个逗号(,)或分号(;)时,表示第一个进程结束,第二个进程从缓冲区中读取那些已键入的字符并显示在屏幕上。第二个进程结束后,程序又进入第一个进程,重新显示字符“A”,同时用户又可以继续键入字符,直到用户输入一个分号(;)键,才结束第一个进程,同时也 结束整个程序。

#include “stdio.h” 
#include “conio.h” 
#include “queue.h” 
main() 
{/*模拟键盘输入循环缓冲区*/   
	char ch1, ch2; 
	SeqQueue  Q; 
	int f; 
	InitQueue (&Q);      /* 队列初始化 */ 
	for(;;) 
	{   
		for(;;)   /*第一个进程*/   
		{     
			printf(“A”);        
			if(kbhit())    
			{        
				ch1= getch( );     /* 读取键入的字符,但屏幕上不显示 */        
				if(ch1==;||ch1==,)  
					break;   /* 第一个进程正常中断 */        
				f= EnterQueue (&Q, ch1);        
				if(f==FALSE)        
				{           
					printf(“循环队列已满\n”);           
						break;      /* 循环队列满时,强制中断第一个进程*/           
				}     
			}   
		}              
		while (!IsEmpty(Q))          /*第二个进程*/   
		{      
			DeleteQueue (&Q, &ch2);      
			putchar(ch2);            /*显示输入缓冲区的内容*/   
		}       
		if(ch1==.)  
			break;         /*整个程序结束*/ 
	} 
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值