前言

杨辉三角,是二项式系数在三角形中的一种几何排列。如下图所示,
在这里插入图片描述
杨辉三角是中国古代数学的杰出研究成果之一,它把二项式系数图形化,把组合数内在的一些代数性质直观地从图形中体现出来,是一种离散型的数与形的结合。
本文将通过以下几个方面来实现杨辉三角:
1.用二维数组实现杨辉三角;
2.用一维数组实现杨辉三角;
2.1用两个一维数组实现杨辉三角;
2.2用一个一维数组实现杨辉三角;
3.不使用数组实现杨辉三角(使用for循环实现)


一、用二维数组实现杨辉三角

使用二维数组实现杨辉三角,也就是说,将杨辉三角看成是二维数组,有对应的行数和列数,例如,第1行第1列代表数1,第5行第2列代表4,如下图所示。
在这里插入图片描述
这里我们使用动态内存去申请二维数组,而二维数组可以看作是竖向的指针数组去指向横向的一维数组:
在这里插入图片描述
具体的实现过程如下代码所示:

void YangHui2(const int n) //利用二维数组去实现杨辉三角
{
	//二维数组可以看作是竖向的指针数组去指向横向的一维数组
	int** p = (int**)malloc(n * sizeof(int*));  //先申请竖的指针
	for (int i = 0; i < n; i++) //再用竖的指针去指向横向的数组
	{
		p[i] = (int*)malloc(n * sizeof(int));
	}
	assert(p != NULL);  //断言
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j <= i; j++)
		{
			//特殊处理,防止数组越界
			if (j == 0 || i == j)  //每一行的第一个值和最后一个值均为1
			{
				p[i][j] = 1;
			}
			else  //其他的均是公式:当前值 = 上一行本列的值 + 上一行上一列的值
			{
				p[i][j] = p[i - 1][j] + p[i - 1][j - 1];  //此处不需要考虑数组越界问题,因为越界问题已经特殊处理
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j <= i; j++)
		{
			printf("%-5d", p[i][j]);  //打印杨辉三角
		}
		printf("\n");
	}
	for (int i = 0; i < n; i++)
	{
		free(p[i]);//用malloc,一定要释放
	}
	free(p); //利用malloc后,释放指针p
}

这里打印10行杨辉三角,运行结果如下:(如果想要打印等腰三角形形式的,可自行细调输出格式,这里对格式不作要求)
在这里插入图片描述

二、用一维数组实现杨辉三角

1.用两个一维数组实现杨辉三角

此过程利用两个一维数组arr[]和brr[],利用一个数组arr[]按照杨辉三角的规律进行下一行的计算,计算的值保存在另一个数组brr[]中,最后再将brr[]的值赋给数组arr[],打印arr[]即可。
注意一点的就是初始将数组arr[]和brr[]的值全部赋值为1,这样方便计算。

具体的实现过程如下代码所示:

void YangHui1_2(const int n)  //一维数组实现杨辉三角(用两个一维数组)
{
	int* arr = (int*)malloc(n * sizeof(int));
	int* brr = (int*)malloc(n * sizeof(int));  //申请brr是为了存放arr中计算的值,最后再将值赋给arr即可
	assert(arr != NULL && brr != NULL); //断言指针不为空
	for (int i = 0; i < n; i++)  //将arr和brr的值全部赋值为1
	{
		arr[i] = 1;  //将数组arr的值全部赋为1,是为了便于对数组进行操作
		brr[i] = 1;  //将数组brr的值全部赋为1,是为了便于对数组进行操作
	}
	for (int i = 0; i < n; i++)  //外层循环处理第i行的数据
	{
		//这里内层j是从1开始,也就是第一列(j==0)不需要处理,因为都是1
		for (int j = 1; j < i; j++)  //内部循环处理每一层的数据
		{
			//这里不需要考虑数组越界问题,由于列数j是从第2列开始的,所以不存在越界问题
			//利用公式不会超出第一列,最多到第一列,也就是brr[1] = arr[1] + arr[0];
			brr[j] = arr[j] + arr[j - 1]; //利用公式处理完每一层的数据,存放在brr中
		}
		//以下利用for循环将brr的值重新赋给arr,并打印arr
		for (int k = 0; k <= i; k++)
		{
			arr[k] = brr[k];  //将计算的值再重新赋给arr
			printf("%-5d", arr[k]);  //打印arr
		}
		printf("\n");
	}
	free(arr);  //利用malloc后,要进行释放
	free(brr);
}

这里打印10行杨辉三角,运行结果如下:
在这里插入图片描述

2.用一个一维数组实现杨辉三角

利用一个一维数组,此方法是一维数组的第一个值赋值为1,剩余赋值为0,然后从后向前按照杨辉三角的规律推断前面的值。
这里需要注意边界、特殊值的处理,防止数组越界。

具体的实现过程如下代码所示:

void YangHui1_1(const int n)  //一维数组实现杨辉三角(只用一个一维数组)
{
	//int* arr = (int*)malloc(n * sizeof(int));  //动态申请一个一维数组arr
	//利用calloc动态申请n*sizeof(int)大小空间之后,会将里面的值全部初始化为0
	int* arr = (int*)calloc(n, sizeof(int));  //注意此处为什么要用calloc,而不用malloc
	/*
		【注】此处用calloc,注意calloc和malloc的区别
		calloc:在内存的动态存储区中分配n个长度为sizeof(int)的连续空间,
		不同点:calloc在动态分配完内存后,自动初始化该内存空间为【零】,而malloc不初始化,里边数据是随机的垃圾数据
	*/
	assert(arr != NULL);  //断言
	arr[0] = 1;  //将数组的第一个值赋值为1
	for (int i = 0; i < n; i++)  //此层循环是处理第i行的数据,也就是控制层数
	{
		//此方法是一维数组的第一个值赋值为1,剩余赋值为0,然后从后向前推
		for (int j = i; j >= 1; j--)
		{
			//若从后向前处理,当i=0时,不需要处理(循环进不去),当i=1时,也就是第2行,只需处理一个值
			/*
			1  0  0  0  0  0  0  0  0
			1  1  0  0  0  0  0  0  0
			1  2  1  0  0  0  0  0  0
			1  3  3  1  0  0  0  0  0
			*/
			//第一列不需要处理,从后向前,也即j>=1是退出条件
			arr[j] = arr[j] + arr[j - 1];  //当前值 == 当前值(初始均为0)+ 上一个位置的值
		}
		for (int k = 0; k <= i; k++)  //小于等于i是因为第i行只需要打印i个值
		{
			printf("%-5d", arr[k]);
		}
		printf("\n");
	}
	free(arr);  //利用malloc后,要释放指针arr
}

这里打印10行杨辉三角,运行结果如下:
在这里插入图片描述

三、不用数组实现杨辉三角

不用数组实现杨辉三角,这里利用for循环实现:
第一个数是1;
第二个数是:1*(n - 1)/1;
第三个数是:1*(n - 1)/1 * (n - 2 )/2;
第四个数是:1*(n - 1)/1 * (n - 2 )/2 * (n - 3)/3
根据规律得到计算公式:tmp = tmp * (i - (j - 1))/(j - 1); //用到上一个值*(i - (j - 1))/(j - 1)

具体的实现过程如下代码所示:

int YangHui(const int n)  //不用数组实现杨辉三角,利用for循环直接实现杨辉三角
{
	//第n行:第一个数是1;第二个数是:1*(n - 1)/1;第三个数是:1*(n - 1)/1 * (n - 2 )/2;
	//		 第四个数是:1*(n - 1)/1 * (n - 2 )/2 * (n - 3)/3
	//tmp = tmp * (i - (j - 1))/(j - 1); //用到上一个值*(i - (j - 1))/(j - 1)
	if (n < 0)
	{
		return -1;
	}
	int tmp = 0;  //先申请一个变量tmp
	for (int i = 1; i <= n; i++)  //此处是从第一行开始,处理每一层的数据
	{
		for (int j = 1; j <= i; j++)  //注意此处是从下标1开始的,也就是第一列的列下标均为1
		{
			if (j == 1)  //每一行的第一个值特殊处理,其它的值均用公式,从后向前推导
			{
				tmp = 1;  //第一列的值均为1,第一列作为特殊列处理
			}
			else
			{
				tmp = tmp * (i - (j - 1)) / (j - 1);  //公式
			}
			printf("%-5d", tmp);
		}
		printf("\n");
	}
}

这里打印10行杨辉三角,运行结果如下:
在这里插入图片描述


总结

以上就是利用4种方法实现杨辉三角,杨辉三角在编程中较为容易实现。
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐