1.算出全部节点
先是判断root是不是空,要是不是空就先进入左树B后进D,因为右节点是空,所以左节点返回0后加一(返回0,是因为左右节点都空了,然后+1,把这个节点算上),然后返回B,B的右节点为空,B算成一个,返回A此时A的左树是两个,右树的C的左树E与右树F,两个最后都是空,各自返回1,然后一共返回两个给了C,C是属于右节点给了A, 所以最后是左边的树加上右边的树,最后再加上一个1是根节点
int BinaryTreeSize(BTNode*root) { return root==NULL?0:BinaryTreeSize(root->left)+BinaryTreeSize(root->right)+1; //左树加右树加一个根 }
全部节点是6个。
2.算出叶子结点(叶子结点也就是没有左右节点的节点)
从A开始进入,因为A有左右节点B和C,再进入左树的B然后B的左树是D从而再进入D,D没有子节点,所以他是一个叶节点返回1给B,后看B的右树,右树为空返回0,B给A返回的是1,然后进入A的右树,也就是C,进C的右树E,因为E没有左右节点了,所以E是一个叶子节点,然后返回C进入C的右节点F,F没有子节点,所以F也是一个叶节点,返回C,C返回给A,最后左树一个,右树两个,一共三个叶子结点
int BinaryTreeLeafSize(BTNode*root){ if(root==NULL){ return 0;} if(root->left==NULL&&root->right->right==NULL) { return 1; } return BinaryTreeLeafSize(root->left)+BinaryTreeLeafSize(root->right);//多次递归从而求出叶子结点 }
3.求第K层节点
增加点结点,方便更好的去解释,之后的代码解释都换成这个图了
其实核心思想是找层(A的第三层,也就是B的第二层,也就是D的第一层,所以到了他的第一层就返回一个1。)
假如是求第三层,那也就是说需要先进A,然后进入B的2(K-1后变为2),然后进入D的(K变为1),返回1,然后到A的右节点C(K这个时候也是2),进入E后(K变为1)返回1,F相同路径也返回1,
//求第K层节点 int BinaryTreeLevelKSize(BTNode*root,int k){ assert(k>=1); if(root==NULL){ return 0;} if(k==1){ return 1;} //root不等于空,k也不等于1,说明root这棵树的第K节点在子树里面 //转换成求子树的k-1的节点数量 return BinaryTreeLevelKSize(root->left, k-1)+BinaryTreeLevelKSize(root->right, k-1); }
4.查看二叉树的深度(高度)
科普一个很重要的知识点
a>b?a:b此时如果a与b相等则会返回后面的B
先说思想,再说其他问题,主要思想是左树的深和右树的深来进行比较,看看谁更深,再加上第一个结点也就是根节点。从最开始的A进入 ,入到最底下G,G的左右都是空,也就是返回0+1
,也就是1,1返回D,D只有右边,所以右边大,右边再加一,返回2给B,B只有左边的D,所以f返3给A,在看A的右子树,进C进E进H,H返回1,E返回了2,E比F大,所以E返回2给C,C返回3 ,左右都是三,执行后面的那个,所以3+1=4
一共树高4层
int BinaryTreeDepth(BTNode*root){ if(root==NULL){ return 0; } return BinaryTreeDepth(root->left)>BinaryTreeDepth(root->right)?BinaryTreeDepth(root->left)+1:BinaryTreeDepth(root->right)+1; }
再来说说上面代码的缺点
重复的去递归,在比较完谁大谁小后,还要再次重头递归一下,也就是没有别的变量来保存这个结果。
修正:
int BinaryTreeDepth(BTNode*root){ if(root==NULL){ return 0; } int leftDepth=BinaryTreeDepth(root->left); int rightDepth=BinaryTreeDepth(root->right); return leftDepth>rightDepth?leftDepth+1:rightDepth+1; }
5.寻找树中某个节点(要是找到,就返回他的地址)
假如是要找H
先是进入A,然后A的左节点B,发现B不是进入B的左也就是D,D也不是,D的左子树为空,返回一个空,去D的右树是G,G的左树右树为空所以返回是没找到,然后到A的右树C,C进左树是E,E的左树找到了 直接返回H
BTNode* BinaryTreeFind(BTNode*root,int x){ if(root==NULL){ return NULL; } if(root->data==x){ return root; } BTNode*leftRet=BinaryTreeFind(root->left,x); if(leftRet){ return leftRet; //是为了存结果:因为他的返回root是返回上一个的, } BTNode*rightRet=BinaryTreeFind(root->right, x); if(rightRet){ //如果right不等于空,,要是等于空就推出 return rightRet; } return NULL; }