用队列实现杨辉三角

打印杨辉三角是一个经典问题,也是小白非常头疼的一个问题,其实掌握好诀窍也并不难,杨辉三角第一二行不用做什么处理,到了第三行及以后才需要处理,最简单的实现方式就是先找到规律,即首尾元素为1,中间元素是该位置上一行同列的元素及其前一个元素和(第三行开始,不包括首尾元素),用二维数组实现是最简便便捷的方法
此处不仅给出了杨辉三角的普通实现方式,也给出了杨辉三角的队列实现(PS:队列是一种数据结构,第二张实现方式需要有数据结构基础才能理解)

#include<stdio.h>
#define MAX 100
#include<stdlib.h>
int main() {
	int arr[MAX][MAX] = { 0 };
	int a = 0;
	int i = 0;
	int j = 0;
	printf("输入杨辉三角的范围:");
	scanf("%d", &a);
	for (i = 0; i < a; i++) {
		//第二重for循环条件为j<=i  控制个数  易错点
		for (j = 0; j <= i; j++) {
			if (j == 0) {
				arr[i][j] = 1;
				printf("%5d ", arr[i][j]);
				if (i == 0) {
					printf("\n");
				}
			}
			if ((i == j) && (i!=0)) {
				arr[i][j] = 1;
				printf("%5d\n", arr[i][j]);
			}
			if ((j != 0) && (i != j)) {
				arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
				printf("%5d ", arr[i][j]);
			}
		}
	}
	system("pause");
	return 0;
}

看完了杨辉三角的朴素实现方式,接下来简析队列实现方式,杨辉三角的行列数最大值相同,每一行比上一行多一个元素,有一定规律,这就为二维的存储结构转变为一维的结构提供可能性,以下为具体的实现过程:

#include<stdio.h>
#include<stdlib.h>	//malloc函数需要用到该头文件
#define MAXQSIZE 200	//此程序用到循环队列
typedef int QElemType;
typedef struct {
    QElemType  *next;	//int 类型指针 *base
    int front;			//队头指针
    int rear;			//队尾指针
}SqQueue;				//	结构体名称为SqQueue 包含三个子元素
void InitQueue(SqQueue *Q){
    //构造一个空队列Q
    Q->next=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));	//创建足够大的循环队列
    if(!Q->next)
		exit(1);	//若初始化队列不为空  则退出
    Q->front=Q->rear=0;	//队列初始化条件
}

void EnQueue(SqQueue *Q,QElemType e){
    //插入的元素e为Q的新的队尾元素
    if((Q->rear+1)%MAXQSIZE ==Q->front) exit(1);		//判满 满则退出
    Q->next[Q->rear]=e;
    Q->rear=(Q->rear+1)%MAXQSIZE;	//关键代码
}

void DeQueue(SqQueue *Q){
    //若队列不空,则删除Q的队头元素,用e返回其值
    if(Q->front==Q->rear)
        exit(1);
    QElemType e = Q->next[Q->front];
    Q->front=(Q->front+1)%MAXQSIZE;
}

QElemType GetHead(SqQueue *Q){
    //返回队头元素
    return Q->next[Q->front];
}

int main(){
    int N,n,c;
    QElemType t,x;	//t,x用于存储第三行及以后计算产生的临时值 
    SqQueue f,*Q;
    Q=&f;
    InitQueue(Q);
    printf("请输入杨辉三角规模N:");
    scanf("%d",&N);
    EnQueue(Q,1);	//第一行的1 
    for(n=2;n<=N;n++){	//处理第二行及之后的元素 
        EnQueue(Q,1);			//队列插入首元素1
        //以下for循环处理第3行及之后行的中间元素 
        for(c=1;c<=n-2;c++){
            t=GetHead(Q);		//c从1号位开始 逐一获取节点
            DeQueue(Q);			//获取完节点后队头指针往后移1
            printf("%4d",t);	//输出当前节点值  t用于存储当前节点值
            x=GetHead(Q);		//x用于获取下一个节点的节点值(前一个元素已出队 用t保存)
            t=t+x;				//计算两值之和 
            EnQueue(Q,t);   	//更新后的t值入队 
        }
        EnQueue(Q,1);			//插入每一行最后一个元素1
        printf("%4d",GetHead(Q));
        DeQueue(Q);			
        printf("\n");			//打印完当前行的上一行 需要换行
    }
    
    while(Q->front!=Q->rear){	//打印剩下未出队的元素(最后一行元素) 
            printf("%4d",GetHead(Q));
            DeQueue(Q);	
        }
    return 0;
}

在这里插入图片描述
最后再附上一种只用一维实现的方式:

#include <stdio.h>
int main(){
	long i,j,n,k;
	printf("请输入杨辉三角行数:");
	scanf("%ld",&n);
	for( i= 1;i <= n;i++){
		k=1;
		for(j = 1;j < i;j++){ 
			printf("%ld\t",k);  
			k=k*(i - j)/j; 
		}
	printf("1\n");//这个用于打印每行最后一列的1
	}
	return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值