杨辉三角除第一行为两个1以外,从第二行开始,每一行的首尾都为1,中间位置的数为上一行其左右两侧数之和,形状如下:
1 1
1 2 1
1 3 3 1
1 4 6 4 1
试编写函数,利用循环队列实现任意行杨辉三角的输出。

如果要求计算并输出杨辉三角前 n 行的值,则队列的最大空间应为 n + 2。(进进出出的)

假设队列中已存有第 k 行的计算结果,并为了计算方便,在两行之间添加一个“0”作为行界值,
则在计算第 k + 1 行之前,头指针正指向第 k 行的“0”,而尾元素为第 k + 1 行的“0”。

由此从左到右依次输出第 k 行的值,并将计算所得的第 k + 1 行的值插入队列

#define  MAXLEN 100 
#define EMPTY_QUEUE_ERROR -9999999
typedef int ElemType;
typedef struct {
int elem[MAXLEN]; // 用来存队列数据元素的数组
int front; // 指示队首在数组中位置的标识量
int rear; // 指示队尾在数组中位置的标识量adj.后面的,背面的,后方的
}intQueue;
/*初始化(调整两个位置标识量)*/
void InitQueue(intQueue* pQueue) // 指针类型作为形参,某个队列实例的地址
{
/**********************************************************
将该队列实例的队首和队尾标识量置零
*********************************************************/
pQueue->front = 0;
pQueue->rear = 0;
}
/*利用循环队列实现任意行杨辉三角的输出?*/
void YangHuiTiangle(int n)
{
int s, e; // s保存 上一行 左侧数据,e保存右侧数据
intQueue q; // 定义一个队列实例变量q

InitQueue(&q); // 使用之前需要初始化该队列q

{ // 预先放入第一行的两个1
EnQueue(&q,1);
EnQueue(&q, 1);
}
/*后续的行*/
// 循环: 逐行处理,
/*将第i行 出队 并输出,
生成第i+1行 入队;
在出队输出第i行前要先把下一行(即第i+1行)算好并插入队列后才输出,否则下一行的计算就没有输入了) (注意是从从头(q->front)出队(保存到e),先进先出);*/
for (int i = 1; i <= n; i++)//i是要输出的行,i+1是要填充的行
{
/*生成第i+1行*/
EnQueue(&q, 0);// 两行之间增加一个0作为标记
// 处理第i行的(要生成的)i+2个数据(第i行有i+1个数,额外有一个0作为分隔行的标记数.
s = 0;/*计算第i行开始前,将保存上一行左边的值的变量初始化为0*/

for (int j = 1; j <= i + 2; j++)
{
// 读取上一行的第一个数据1,存到e中//q.elem[q.front]
e = DeQueue(&q);//出队一个

// 计算i行的第j个数据,并入队
EnQueue(&q, s + e);//入队一个(第i行的第j个数据)

s = e; // 这是为何?(在计算同一行的下一个元素时,当前的元素使用的e就是下一个元素的s;

// 如果j非第i+2个数据,输出s
/*(e和s是独立于队列之外的两个变量)
如果j是的i+2个元素,那么刚好是该行的结束标志数0,(与此同时,可以将生成边缘的"1" 也用e+s计算统一起来(边缘值:0+1 = 1或者1+0 = 1 )
第一行的元素在队列中不是0,但可以在队列之外单独将s初始化为0*/
{
/*输出第i行,第i行有i+1个需要输出的元素,(不包括0)*/
//your multiple lines code
if (j < i + 2)
{
printf("%d ", s);
}
}
}//for(j)
printf("\n"); // 结束i行,输出换行符
}//for(i)
}

//测试, 使用实际例子测试上述函数是否正常工作
/*入队列
将某数据元素x入队列,成功返回1,失败返回0。*/
int EnQueue(intQueue* pQueue, ElemType x)
{
// 1、若该队列已满,则入队列失败
if (IsFull(pQueue)) return 0;

// 2、若该队列没满,将x写入队尾,然后队尾位置后移
else
{
pQueue->elem[pQueue->rear] = x;// x入队列
pQueue->rear = (pQueue->rear + 1) % MAXLEN;// 队尾后移
}


return 1;
}
/*对头元素出队列*/
int DeQueue(intQueue* pQueue)
{
if (!IsEmpty(pQueue))
{
/*移动对头元素前保存该值*/
ElemType temp = pQueue->elem[pQueue->front];

/*向前移动front有讲究:
如果是:pQueue->front++,那么front可能会溢出数组,
所以必须利用循环队列的周期性质(除以周期取余数),保证不溢出*/
pQueue->front = (pQueue->front + 1) % MAXLEN;
return temp;/*删除成功的出口*/
}
return EMPTY_QUEUE_ERROR;
}

void main()
{
int n;
printf("\n\n\t\tYangHui Triangle:\n\nplease input the lines you want!(1~98, 0 to quit)");
scanf("%d", &n);
while (n)
{
system("cls");/*cls是清屏的,但是它清除的是上一个回车的内容*/
printf("测试杨辉三角YangHui():\n");
if (n > 0 && n < 99)
YangHuiTiangle(n);
/*准备接收下一个请求:*/
printf("\n\n\t\tYangHui Triangle:\n\nplease input the lines you want!(1~98, 0 to quit)");
scanf("%d", &n);
}
}