先看程序运行结果
可以看出第i行的元素是由上一行的元素得来的,下面是我写的算法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; #define max 10 //写的递归函数 int calculate(int *pretemp,int row) { //跳出条件 if (row > max) { delete pretemp; return 0; } //刚开始第一行的时候指针为空 if (pretemp == NULL) { for(int i = 1;i <= (int)((2*max+1)/2)-row;i++) cout<<" "; pretemp = new int[1]; pretemp[0] = 1; cout<<pretemp[0]<<endl; calculate(pretemp,row+1); } else { for(int i = 1;i <= (int)((2*max+1)/2)-row;i++) cout<<" "; //分配第row行需要的数据空间并且根据上一行的数据空间计算出当前行的数值 int *temp = new int[row]; temp[0] = 1; temp[row-1] = 1; for (i = 1;i < row-1;i++) { temp[i] = pretemp[i-1] + pretemp[i]; } //输出当前行 for (i = 0;i <= row-1;i++) { cout<<temp[i]<<" "; } cout<<endl; //删除上一次调用存储数据的临时空间 delete pretemp; //开始输出下一行 calculate(temp,row+1); } } int main() { int count = 0; calculate(NULL,1); return 0; }
主要思想是通过递归,传递的参数有两个,一个是上一行的数据所在的动态分配的内存地址,另一个是行号,在新的一行中,通过分配适当的内存空间,并一句上一行的数据计算出当前行的数据.然后动态释放前一行的内存,然后将行号加1和本行分配的内存地址传递到下一次递归中.还要注意设置好递归的初始值和跳出条件.
下面是另一个写法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #defineN12 longcombi(intn,intr){ inti; longp=1; for(i=1;i<=r;i++) p=p*(n-i+1)/i; returnp; } voidpaint(){ intn,r,t; for(n=0;n<=N;n++){ for(r=0;r<=n;r++){ inti;/* 排版设定开始*/ if(r==0){ for(i=0;i<=(N-n);i++) printf(" "); }else{ printf(" "); }/* 排版设定结束*/ printf("%3d",combi(n,r)); } printf(" "); } }
这个没有通过递归来计算,主要是发现了三角形的计算规律
可以知道,无论是时间复杂度还是空间复杂度,都是下面的算法比较好点,所以,以后再写的时候注意先分析,在思路上进行优化,提高程序效率