二叉树有中序前序求后序
前序遍历和后续遍历

首先明确:一颗二叉树的前序遍历=根节点+左子树前序遍历+右子树前序遍历
一颗二叉树的中序遍历=左子树中序遍历+根节点+右子树中序遍历
那么从前序遍历中取第一个点,就是根节点,知道了根节点,就可以找到中序遍历中跟节点的位置,那么就可以在中序遍历中找到左子树和右子树。
首先,我们看看前序、中序、后序遍历的特性:
前序遍历:
1.访问根节点
2.前序遍历左子树
3.前序遍历右子树
中序遍历:
1.中序遍历左子树
2.访问根节点
3.中序遍历右子树
后序遍历:
1.后序遍历左子树
2.后序遍历右子树
3.访问根节点
好了,先说说用前序遍历和中序遍历求后序遍历
假设前序遍历为adbgcefh, 中序遍历为dgbaechf
前序遍历是先访问根节点,然后再访问子树的,而中序遍历则先访问左子树再访问根节点
那么把前序的a 取出来,然后查找a 在中序遍历中的位置就得到dgb a echf
那么我们就知道dgb 是左子树echf 是右子树,因为数量要吻合
所以前序中相应的dbg 是左子树cefh 是右子树
然后就变成了一个递归的过程,具体代码如下:
而已知后序遍历和中序遍历求前序遍历的过程差不多,但由于后序遍历是最后才访问根节点的所以要从后开始搜索,例如上面的例子,后序遍历为gbdehfca,中序遍历为dgbaechf
后序遍历中的最后一个元素是根节点,a,然后查找中序中a的位置
把中序遍历分成dgb a echf,而因为节点个数要对应
后序遍历分为gbd ehfc a,gbd为左子树,ehfc为右子树,这样又可以递归计算了
其他一些附带的代码上面已经有,这里就不重复贴了,具体代码如下:。
二叉树的建立与先序中序后序遍历 求叶子节点个数 求分支节点个数 求二叉树的高度

/*一下总结一些二叉树的常见操作:包括建立二叉树先/中/后序遍历二叉树求二叉树的叶子节点个数求二叉树的单分支节点个数计算二叉树双分支节点个数计算二叉树的高度计算二叉树的所有叶子节点数*/#include<stdio.h> //c语言的头文件#include<stdlib.h>//c语言的头文件stdlib.h千万别写错了#define Maxsize 100/*创建二叉树的节点*/typedef struct BTNode //结构体struct 是关键字不能省略结构体名字可以省略(为无名结构体)//成员类型可以是基本型或者构造形,最后的为结构体变量。
{char data;struct BTNode *lchild,*rchild;}*Bitree;/*使用先序建立二叉树*/Bitree Createtree() //树的建立{char ch;Bitree T;ch=getchar(); //输入一个二叉树数据if(ch==' ') //' '中间有一个空格的。
T=NULL;else{ T=(Bitree)malloc(sizeof(Bitree)); //生成二叉树(分配类型*)malloc(分配元素个数*sizeof(分配类型))T->data=ch;T->lchild=Createtree(); //递归创建左子树T->rchild=Createtree(); //地柜创建右子树}return T;//返回根节点}/*下面先序遍历二叉树*//*void preorder(Bitree T) //先序遍历{if(T){printf("%c-",T->data);preorder(T->lchild);preorder(T->rchild);}} *//*下面先序遍历二叉树非递归算法设计*/void preorder(Bitree T) //先序遍历非递归算法设计{Bitree st[Maxsize];//定义循环队列存放节点的指针Bitree p;int top=-1; //栈置空if(T){top++;st[top]=T; //根节点进栈while(top>-1) //栈不空时循环{p=st[top]; //栈顶指针出栈top--;printf("%c-",p->data );if(p->rchild !=NULL) //右孩子存在进栈{top++;st[top]=p->rchild ;}if(p->lchild !=NULL) //左孩子存在进栈{top++;st[top]=p->lchild ;}}printf("\n");}}/*下面中序遍历二叉树*//*void inorder(Bitree T) //中序遍历{if(T){inorder(T->lchild);printf("%c-",T->data);inorder(T->rchild);}}*//*下面中序遍历二叉树非递归算法设计*/void inorder(Bitree T) //中序遍历{Bitree st[Maxsize]; //定义循环队列,存放节点的指针Bitree p;int top=-1;if(T){p=T;while (top>-1||p!=NULL) //栈不空或者*不空是循环{while(p!=NULL) //扫描*p的所有左孩子并进栈{top++;st[top]=p;p=p->lchild ;}if(top>-1){p=st[top]; //出栈*p节点,它没有右孩子或右孩子已被访问。
二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

⼆叉树遍历算法——包含递归前、中、后序和层次,⾮递归前、中、后序和层次遍历共⼋种⾸先,要感谢⽹上的参考资料。
1. /876134/1178079(作者:BlackAlpha)2. /fzh1900/article/details/14056735(作者:_云淡风轻)3. /stpeace/article/details/8138458(作者:stpeace)⼆叉树是使⽤的⽐较⼴泛的⼀种数据结构,这⾥我写了⼆叉树的相关操作,包括初始化、新建、以及遍历。
这⾥主要是为了学习⼆叉树的遍历算法,我总结后,写了⼋种⼆叉树的遍历算法,分别是:1.递归先序遍历2.递归中序遍历3.递归后序遍历4.⾮递归先序遍历(单栈辅助)5.⾮递归中序遍历(单栈辅助)6.⾮递归后序遍历(单栈辅助)7.递归层次遍历8.⾮递归层次遍历(队列辅助)当然,这⾥还要⽤到栈和队列,博客中以前有提到过(链式的栈和链式队列),其实还可以⽤顺序栈和顺序队列的(博客中后⾯将补上这块)。
下⾯直接上代码:LinkStack.h 链式栈头⽂件[cpp]1. #ifndef _LINK_STACK_H_H2. #define _LINK_STACK_H_H3.4. #include "BiTree.h"5.6. typedef pBiTree LStackEle;7.8. typedef struct LSNODE9. {10. LStackEle ele;11. struct LSNODE *pnext;12. }LSNode, *pLSNode;13.14. typedef struct LSTACK15. {16. pLSNode top;17. }LStack, *pLStack;18.19. //栈初始化20. void InitLinkStack(LStack &s);21.22. //⼊栈23. void PushLinkStack(LStack &s, LStackEle ele);24.26. void PopLinkStack(LStack &s, LStackEle &ele);27.28. //判断栈是否为空29. bool IsemptyLinkStack(LStack s);30.31. //获得栈顶值32. LStackEle GetTopLinkStack(LStack s);33.34. #endifLinkQueue.h 链式队列头⽂件[html]1. #ifndef _LINK_QUEUE_H_H2. #define _LINK_QUEUE_H_H3.4. #include "BiTree.h"5.6. typedef pBiTree LQueueEle;7.8. typedef struct LQNODE9. {10. LQueueEle ele;11. struct LQNODE *pnext;12. }LQNode, *pLQNode;13.14. typedef struct LQUEUE15. {16. pLQNode rear;17. pLQNode front;18. }LQueue, *pLQueue;19.20. //初始化队列21. void InitLinkQueue(LQueue &q);22.23. //⼊队24. void EnLinkQueue(LQueue &q, LQueueEle ele);25.26. //出队27. void DeLinkQueue(LQueue &q, LQueueEle &ele);28.29. //判断队列是否为空30. bool IsemptyLinkQueue(LQueue q);31.32. //获得队头元素值33. LQueueEle GetFrontLinkQueue(LQueue q);34.35. #endifBiTree.h ⼆叉树头⽂件[cpp]1. #ifndef _BITREE_H_H2. #define _BITREE_H_H3.4. typedef struct BINODE5. {7. struct BINODE *plchild;8. struct BINODE *prchild;9. }BiNode, *pBiTree;10.11. //初始化⼆叉树(含根节点)12. void InitBiTree(pBiTree &bt, int ele);13.14. //创建⼆叉树节点15. BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele);16.17. //插⼊左⼦⼆叉树18. void InsertLChild(pBiTree parent, pBiTree lchild);19.20. //插⼊右⼦⼆叉树21. void InsertRChild(pBiTree parent, pBiTree rchild);22.23. //计算⼆叉树的深度24. int DeepBiTree(pBiTree bt);25.26. //递归先序遍历27. void RePreOrderTraverse(pBiTree bt);28.29. //递归中序遍历30. void ReInOrderTraverse(pBiTree bt);31.32. //递归后序遍历33. void RePostOrderTraverse(pBiTree bt);34.35. //⾮递归先序遍历⼆36. void NonRePreOrderTraverse(pBiTree bt);37.38. //⾮递归中序遍历39. void NonReInOrderTraverse(pBiTree bt);40.41. //⾮递归后序遍历42. void NonRePostOrderTraverse(pBiTree bt);43.44. //⾮递归层次遍历45. void NonReLevelOrderTraverse(pBiTree bt);46.47. //递归层次遍历48. void ReLevelOrderTraverse(pBiTree bt);49.50. void PrintLevelNode(pBiTree bt, int level);51.52. #endifLinkStack.cpp 链式栈源⽂件[html]1. #include "LinkStack.h"2. #include <stdlib.h>3. #include <stdio.h>4.5. //栈初始化6. void InitLinkStack(LStack &s)7. {8. s.top= NULL;9. }10.11. //⼊栈12. void PushLinkStack(LStack &s, LStackEle ele)13. {14. pLSNode pnew = (pLSNode)malloc(sizeof(LSNode));15. if (pnew == NULL)16. {17. printf("内存分配失败!\n");18. exit(EXIT_FAILURE);19. }20.21. pnew->ele = ele;22. pnew->pnext = s.top;23. s.top = pnew;24. }25.26. //出栈27. void PopLinkStack(LStack &s, LStackEle &ele)28. {29. pLSNode pt = NULL;30. if (IsemptyLinkStack(s))31. {32. printf("栈为空,不能出栈操作!\n");33. exit(EXIT_FAILURE);34. }35. else36. {37. ele = s.top->ele;38. pt = s.top;39. s.top = pt->pnext;40. free(pt);41. pt = NULL;42. }43.44. }45.46. //判断栈是否为空47. bool IsemptyLinkStack(LStack s)48. {49. if (s.top == NULL)50. return true;51. else52. return false;53. }54.55. //获得栈顶元素56. LStackEle GetTop(LStack s)57. {58. if (IsemptyLinkStack(s))59. {60. printf("栈为空,不能获得栈顶元素值!\n");61. exit(EXIT_FAILURE);62. }63. else64. return s.top->ele;65. }LinkQueue.cpp 链式队列源⽂件[cpp]1. #include <stdlib.h>2. #include <stdio.h>3. #include "LinkQueue.h"4.5. //初始化队列6. void InitLinkQueue(LQueue &q)7. {8. q.front = (pLQNode)malloc(sizeof(LQNode));9. if (q.front == NULL)10. {11. printf("内存分配失败!\n");12. exit(EXIT_FAILURE);13. }14.15. q.rear = q.front;16. }17.18. //⼊队19. void EnLinkQueue(LQueue &q, LQueueEle ele)20. {21. pLQNode pnew = (pLQNode)malloc(sizeof(LQNODE));22. if (pnew == NULL)23. {24. printf("内存分配失败!\n");25. exit(EXIT_FAILURE);26. }27.28. pnew->ele = ele;29. pnew->pnext = NULL;30. q.rear->pnext = pnew;31. q.rear = pnew;32. }33.34. //出队35. void DeLinkQueue(LQueue &q, LQueueEle &ele)36. {37. pLQNode pt = NULL;38.39. if (IsemptyLinkQueue(q))40. {41. printf("队列为空,不能出队操作!\n");42. exit(EXIT_FAILURE);43. }44.45. ele = q.front->pnext->ele;46. pt = q.front->pnext;47. q.front->pnext = pt->pnext;48. free(pt);49. /*50. pt是最后⼀个节点时,释放完了以后,尾指针指向的51. 是随机内存,所以让它和头指针指向同⼀个地址。
已知一棵二叉树的前序序列为bacdeghf,中序序列为cadbhgef,则后序序列为

已知一棵二叉树的前序序列为bacdeghf,中序序列为cadbhgef,则后序序列为根据二叉树的前序序列bacdeghf和中序序列cadbhgef,可以确定该二叉树的结构。
二叉树是一种特殊的树,它只有左右两个子树,每个节点最多只有两个子节点。
二叉树的前序序列,可以从根节点开始,按照从上到下,从左到右的顺序依次访问每个节点,以根节点b开头的前序序列bacdeghf中,b为根节点,a和c为b的左右子节点,d为a的左子节点,e为a的右子节点,g为c的左子节点,h为c的右子节点。
二叉树的中序序列,可以从左到右依次访问每个节点,从根节点开始,先遍历左子树,再遍历右子树,以根节点b开头的中序序列cadbhgef中,c为b的左子节点,a为c的左子节点,d为a的左子节点,b为d的右子节点,h为b的右子节点,g为h的左子节点,e为g的右子节点。
根据前序序列和中序序列,可以绘制出该二叉树的结构。
其根节点为b,左子节点为c,右子节点为e,c的左子节点为a,a的左子节点为d,d的右子节点为b,e的左子节点为g,g的右子节点为h。
由此可知,该二叉树的后序序列为cdebhgfe,从右向左,从下到上的顺序依次访问每个节点,以根节点b结尾。
由前序序列和中序序列可以直接确定二叉树的结构,而后序序列可以帮助我们更好地理解二叉树的结构。
在许多算法中,后序序列的结构也是非常重要的。
二叉树的前序序列、中序序列和后序序列都是树的一种遍历方式,它们都可以用来确定一棵树的结构,而且这三种遍历方式之间互相转换也是非常方便的。
在计算机科学中,二叉树是一种重要的数据结构,它在图形处理、数据检索等方面有着广泛的应用。
本文综上所述,已知一棵二叉树的前序序列为bacdeghf,中序序列为cadbhgef,根据二叉树的前序序列和中序序列,可以确定该二叉树的结构,其后序序列为cdebhgfe。
二叉树的前序序列、中序序列和后序序列都是树的一种遍历方式,它们都可以用来确定一棵树的结构,而且这三种遍历方式之间互相转换也是非常方便的。
二叉树遍历(前序、中序、后序、层次、广度优先、深度优先遍历)

⼆叉树遍历(前序、中序、后序、层次、⼴度优先、深度优先遍历)⽬录转载:⼆叉树概念⼆叉树是⼀种⾮常重要的数据结构,⾮常多其他数据结构都是基于⼆叉树的基础演变⽽来的。
对于⼆叉树,有深度遍历和⼴度遍历,深度遍历有前序、中序以及后序三种遍历⽅法,⼴度遍历即我们寻常所说的层次遍历。
由于树的定义本⾝就是递归定义,因此採⽤递归的⽅法去实现树的三种遍历不仅easy理解并且代码⾮常简洁,⽽对于⼴度遍历来说,须要其他数据结构的⽀撑。
⽐⽅堆了。
所以。
对于⼀段代码来说,可读性有时候要⽐代码本⾝的效率要重要的多。
四种基本的遍历思想前序遍历:根结点 ---> 左⼦树 ---> 右⼦树中序遍历:左⼦树---> 根结点 ---> 右⼦树后序遍历:左⼦树 ---> 右⼦树 ---> 根结点层次遍历:仅仅需按层次遍历就可以⽐如。
求以下⼆叉树的各种遍历前序遍历:1 2 4 5 7 8 3 6中序遍历:4 2 7 5 8 1 3 6后序遍历:4 7 8 5 2 6 3 1层次遍历:1 2 3 4 5 6 7 8⼀、前序遍历1)依据上⽂提到的遍历思路:根结点 ---> 左⼦树 ---> 右⼦树,⾮常easy写出递归版本号:public void preOrderTraverse1(TreeNode root) {if (root != null) {System.out.print(root.val+" ");preOrderTraverse1(root.left);preOrderTraverse1(root.right);}}2)如今讨论⾮递归的版本号:依据前序遍历的顺序,优先訪问根结点。
然后在訪问左⼦树和右⼦树。
所以。
对于随意结点node。
第⼀部分即直接訪问之,之后在推断左⼦树是否为空,不为空时即反复上⾯的步骤,直到其为空。
若为空。
则须要訪问右⼦树。
注意。
在訪问过左孩⼦之后。
已知二叉树的先序遍历和中序遍历画出该二叉树

已知⼆叉树的先序遍历和中序遍历画出该⼆叉树对⼀棵⼆叉树进⾏遍历,我们可以采取3中顺序进⾏遍历,分别是前序遍历、中序遍历和后序遍历。
这三种⽅式是以访问⽗节点的顺序来进⾏命名的。
假设⽗节点是N,左节点是L,右节点是R,那么对应的访问遍历顺序如下:前序遍历 N->L->R中序遍历 L->N->R后序遍历 L->R->N所以,对于以下这棵树,三种遍历⽅式的结果是前序遍历 ABCDEF中序遍历 CBDAEF后序遍历 CDBFEA已知⼆叉树的前序遍历和中序遍历,如何得到它的后序遍历其实,只要知道其中任意两种遍历的顺序,我们就可以推断出剩下的⼀种遍历⽅式的顺序,这⾥我们只是以:知道前序遍历和中序遍历,推断后序遍历作为例⼦,其他组合⽅式原理是⼀样的。
要完成这个任务,我们⾸先要利⽤以下⼏个特性:特性A,对于前序遍历,第⼀个肯定是根节点;特性B,对于后序遍历,最后⼀个肯定是根节点;特性C,利⽤前序或后序遍历,确定根节点,在中序遍历中,根节点的两边就可以分出左⼦树和右⼦树;特性D,对左⼦树和右⼦树分别做前⾯3点的分析和拆分,相当于做递归,我们就可以重建出完整的⼆叉树;我们以⼀个例⼦做⼀下这个过程,假设:前序遍历的顺序是: CABGHEDF中序遍历的顺序是: GHBACDEF第⼀步,我们根据特性A,可以得知根节点是C,然后,根据特性C,我们知道左⼦树是:GHBA,右⼦树是:DEF。
C/ \GHBA DEF第⼆步,取出左⼦树,左⼦树的前序遍历是:ABGH,中序遍历是:GHBA,根据特性A和C,得出左⼦树的⽗节点是A,并且A没有右⼦树。
C/ \A DEF/GBH第三步,使⽤同样的⽅法,前序是BGH,中序是GHB,得出⽗节点是B,GH是左⼦树,没有右⼦树。
C/ \A DEF/B/GH第四步,前序是GH, 中序是GH, 所以 G是⽗节点, H是右⼦树, 没有左⼦树.C/ \A DEF/B/G\H第四步,回到右⼦树,它的前序是EDF,中序是DEF,依然根据特性A和C,得出⽗节点是E,左右节点是D和F。
已知一棵二叉树的前序遍历结果为abcdefg,中序遍历结果为bcaedgf,则后序遍历的结果

已知一棵二叉树的前序遍历结果为abcdefg,中序遍历结果为bcaedgf,则后序遍历的结果前序遍历结果为 abcdefg,中序遍历结果为 bcaedgf,则后序遍历的结果为 axial degree,则集合中每个边所对应的树是一个树。
因此,其树前序遍历过程中每一个步骤都是错误的。
这是在给定一个树后序遍历(abcdefg)后得到的结果。
所以,对于任意一点 A与 B均为2次遍历结果之差。
这是一个中序遍历的例子。
但是对于已经遍历x,则树前序和中序都是先遍历出来,在这个节点为x且是奇数,则表示该树为 abcdefg树是1个二叉树。
因此后序遍历的结果与本节无关。
由于其仅有数行且没有边,所以一般只需要将前序遍历结果保存在一个指定的位置即可。
但是如果不考虑遍历过程中出现一个参数,就会出现以下问题:若该参数为负数怎么办?如何解决:首先如果这个变量不存在,那么所有状态变量都是0,则该根因函数;如果该参数为“0”则对数据进行唯一遍历即可得到全部结果。
若我们有两个以上的二叉树同时生长且不影响其结果的话,那么这样两个数据都要全部遍历一遍之后得到一个概率为100%的集合。
为了达到这个目的需要构造两个不同的序列:一个序列可以是非0;另一个序列也是1或者是2种不同形式。
(如果存在一种序列)这种算法可以用于处理二次概率论中常用的一些问题。
1.树的基本结构根据概率论,每个元素有 n种状态变量,包括状态变量(比如:“状态变量”的含义为状态变量与状态值之间的关系),可以用如下公式描述:其中 b是状态变量中的1, n是一个随机数; b为状态变量的值为 k; k为一个整数。
其中 N是 n维树体的数列; N是每个边所对应的集合; n 是在一个集合中所对应的边数目。
每个边都是固定的值;所以,每个边代表树2中所有边都是1。
因此每一个节点对任意 b都是唯一的。
由于 k是1个实数,所以在给定条件下该集合是2×2倍数,也就是说从 b开始计算,每一个元素是其前序遍历得到的结果是所有 b中都是1。
二叉树遍历(前中后序遍历,三种方式)

⼆叉树遍历(前中后序遍历,三种⽅式)⽬录刷题中碰到⼆叉树的遍历,就查找了⼆叉树遍历的⼏种思路,在此做个总结。
对应的LeetCode题⽬如下:,,,接下来以前序遍历来说明三种解法的思想,后⾯中序和后续直接给出代码。
⾸先定义⼆叉树的数据结构如下://Definition for a binary tree node.struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}};前序遍历,顺序是“根-左-右”。
使⽤递归实现:递归的思想很简单就是我们每次访问根节点后就递归访问其左节点,左节点访问结束后再递归的访问右节点。
代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;helper(root,res);return res;}void helper(TreeNode *root, vector<int> &res){res.push_back(root->val);if(root->left) helper(root->left, res);if(root->right) helper(root->right, res);}};使⽤辅助栈迭代实现:算法为:先把根节点push到辅助栈中,然后循环检测栈是否为空,若不空,则取出栈顶元素,保存值到vector中,之后由于需要想访问左⼦节点,所以我们在将根节点的⼦节点⼊栈时要先经右节点⼊栈,再将左节点⼊栈,这样出栈时就会先判断左⼦节点。
代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;stack<TreeNode*> st;st.push(root);while(!st.empty()){//将根节点出栈放⼊结果集中TreeNode *t = st.top();st.pop();res.push_back(t->val);//先⼊栈右节点,后左节点if(t->right) st.push(t->right);if(t->left) st.push(t->left);}return res;}};Morris Traversal⽅法具体的详细解释可以参考如下链接:这种解法可以实现O(N)的时间复杂度和O(1)的空间复杂度。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
已知二叉树的前序/后序遍历和中序遍历,求后序/前序遍历
博客分类:
•算法与数据结构
首先,我们看看前序、中序、后序遍历的特性:
前序遍历:
1.访问根节点
2.前序遍历左子树
3.前序遍历右子树
中序遍历:
1.中序遍历左子树
2.访问根节点
3.中序遍历右子树
后序遍历:
1.后序遍历左子树
2.后序遍历右子树
3.访问根节点
好了,先说说用前序遍历和中序遍历求后序遍历
假设前序遍历为adbgcefh, 中序遍历为dgbaechf
前序遍历是先访问根节点,然后再访问子树的,而中序遍历则先访问左子树再访问根节点那么把前序的a 取出来,然后查找a 在中序遍历中的位置就得到dgb a echf
那么我们就知道dgb 是左子树echf 是右子树,因为数量要吻合
所以前序中相应的dbg 是左子树cefh 是右子树
然后就变成了一个递归的过程,具体代码如下:
C++代码
而已知后序遍历和中序遍历求前序遍历的过程差不多,但由于后序遍历是最后才访问根节点的
所以要从后开始搜索,例如上面的例子,后序遍历为gbdehfca,中序遍历为dgbaechf 后序遍历中的最后一个元素是根节点,a,然后查找中序中a的位置
把中序遍历分成dgb a echf,而因为节点个数要对应
后序遍历分为gbd ehfc a,gbd为左子树,ehfc为右子树,这样又可以递归计算了其他一些附带的代码上面已经有,这里就不重复贴了,具体代码如下:
C++代码。