循环队列应用之杨辉三角(C语言)

杨辉三角是什么不多赘述。直接上代码。

只用到四个函数:init、inset、delete、get。这一部分是老套路。

#include<stdio.h>
#include<stdlib.h>

#define MAXQSIZE 100

typedef int elemtype;

typedef struct Queue{
	elemtype Queue[MAXQSIZE];
	elemtype front, rear;
}Q;

void init_Q(Q*q)
{
	if (!q)
	{
		exit(0);
	}
	for (int i = 0; i < MAXQSIZE; i++)
	{
		q->Queue[i] = 0;
	}
	q->front = 0;
	q->rear = 0;
}

void delete_Q(Q*q, elemtype*s)
{
    if (q->front == q->rear)
	{
		return;
	}
	*s = q->Queue[q->front];
	q->front = (q->front + 1) % MAXQSIZE;
}

void insert_Q(Q*q, elemtype x)
{
	if ((q->rear + 1) % MAXQSIZE == q->front)
	{
		exit(0);
	}
	q->Queue[q->rear] = x;
	q->rear = (q->rear + 1) % MAXQSIZE;
}

void get_Q(Q*q, elemtype*e)
{
	*e = q->Queue[q->front];
}

                                                                     主要说说思路,如何生成杨辉三角?

1、先生成第一行,第一行就一个1,直接入队。

2、第二行以后就有规律了,第二行除两边的1,没有其他数值,第三行除1有1个数值,第四行除1有2个数值...所以对于下面n-1行的生成要用到循环。

3、循环包括什么呢?循环可以理解为用来生成每一行,那么首先生成的就是1,然后是由上一行得到的和,然后是1。

4、由上一行得到的和,这是多个数值,每一行个数不同,于是生成这一部分还得用到循环。

5、走一遍循环发现,在生成第二行时,多行首一个1,所以在循环的最后将这个多余的1删除。并且打印出来,既然是在函数进行的最后进行打印,那么应该是打印每一行最后的1,仔细思索一下发现打印出来正好合适。

那么现在就有大致的结构:

int x = 1;
insert_Q(q, x);//先写出第一行
for (int i = 2; i < n; i++)//其余n-1行
	{
		insert_Q(q, x);//一行中的第一个1
		for (j = 0; j < i - 2; j++)//一行中除首尾的1以外的数字,一行有j-2个
		{
			
		}
		insert_Q(q, x);//一行中最后一个1

		delete_Q(q, &s);//删除一行中第一个1并打印
		printf("%5d\n", s);
	}

6、按照循环走一遍,队列中数值的变化是这样的1,11,111,11。到此该处理生成第三行,但是只打印了第一行的一个1。那么处理第三行时要考虑将第二行打印出来。此处是个难点,因为需要考虑到其他行的普遍情况。

7、生成第三行前队列为11,开始生成i第三行进入循环变为111,将行首的1删除并打印,这就成了每一行的第一个1,然后将队列中删除的1和删除后的行首数值相加得到2。将2插入队列。此时队列为112,继续下面的插入变为1121,最后的删除将队列第一个1删除并打印,此时队列为121,且打印了11,第二行打印完毕,生成了第三行。

int x = 1;
insert_Q(q, x);//先写出第一行
for (int i = 2; i < n; i++)//其余n-1行
	{
		insert_Q(q, x);//一行中的第一个1
		for (j = 0; j < i - 2; j++)//一行中除首尾的1以外的数字,一行有j-2个
		{
			delete_Q(q, &s);
			printf("%5d", s);
			get_Q(q, &e);
			insert_Q(q, s + e);
		}
		insert_Q(q, x);//一行中最后一个1

		delete_Q(q, &s);//删除一行中第一个1并打印
		printf("%5d\n", s);
	}

8、这里非常巧妙的就是,打印一行,同时队列里也生成了接下来的一行。因此当for循环结束,还有一行存在于队列,需要遍历队列印。

int x = 1;
insert_Q(q, x);//先写出第一行
for (int i = 2; i < n; i++)//其余n-1行
	{
		insert_Q(q, x);//一行中的第一个1
		for (j = 0; j < i - 2; j++)//一行中除首尾的1以外的数字,一行有j-2个
		{
			delete_Q(q, &s);
			printf("%5d", s);
			get_Q(q, &e);
			insert_Q(q, s + e);
		}
		insert_Q(q, x);//一行中最后一个1

		delete_Q(q, &s);//删除一行中最后一个1并打印
		printf("%5d\n", s);
	}
	while (q->front != q->rear)
	{
		delete_Q(q, &s);
		printf("%5d", s);
	}

 

整个main函数:

int main()
{
	Q*q = (Q*)malloc(sizeof(Q));
	init_Q(q);
	
	int n, j;
	int x = 1;
	elemtype e, s;

	printf("您想要的杨辉三角规模是:");
	scanf("%d", &n);

	insert_Q(q, x);//先写出第一行
	for (int i = 2; i < n; i++)//其余n-1行
	{
		insert_Q(q, x);//一行中的第一个1
		for (j = 0; j < i - 2; j++)//一行中除首尾的1以外的数字,一行有j-2个
		{
			delete_Q(q, &s);
			printf("%5d", s);
			get_Q(q, &e);
			insert_Q(q, s + e);
		}
		insert_Q(q, x);//一行中最后一个1

		delete_Q(q, &s);//删除一行中最后一个1并打印
		printf("%5d\n", s);
	}
	while (q->front != q->rear)
	{
		delete_Q(q, &s);
		printf("%5d", s);
	}
	getchar();
}

ps:这个循环设计真心巧妙,需要亲自一步步分析循环,多加理解。

                                                                                          End...

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值