日升时奋斗,日落时自省
目录
二、二叉树
2.8二叉树代码实现
2.8.1树节点个数(直接遍历)
public int size(TreeNode root){
if(root==null){
return 0;
}
count++;
size(root.left);
size(root.right);
return count;
}
自我理解:递归是一次到底,条件在前加,每次遍历都会经过的地方,当前代码不难理解,对于递归可能有点点难理解,按正常的步骤走,return在最后,我们就拿这个简单的解释一下
(红色箭头表示向下递推,蓝色箭头表示向上回退)
2.8.2二叉树节点(子问题解法)
通过子问题思想解决问题
(1)左子树节点个数
(2)右子树节点个数
(3)根节点(个数为1)
代码衍生出,节点总个数==左子树节点个数+右子树节点个数+1
public int size2(TreeNode root) {
if (root == null) {
return 0;
}
return size2(root.left) + size2(root.right) + 1;
}
2.8.3二叉树子叶节点个数(子问题思想)
(1)空树判断
(2)子叶节点的特点 判断
(3)左子树叶子节点+右子树叶子节点
public int getLeafNodeCount(TreeNode root) { //获得叶子节点个数
if (root == null) { //递归先立条件
return 0;
}
if (root.left == null && root.right == null) { //叶子节点的特点就是左右树都是空
return 1;
}
int tmp=getLeafNodeCount(root.left) + getLeafNodeCount(root.right); //子问题解决,左树叶子节点+右树节点
return tmp;
}
2.8.4获取第K层节点的个数(子问题思想)
(1)判断空树
(2)判断第k层可以实现的条件(图解)
(3)左子树第k层节点数+右子树第k层节点数
public int getKLevelNodeCount(TreeNode root,int k){
if(root==null){
return 0;
}
if(k==1){
return 1;
}
return getKLevelNodeCount(root.left,k-1)+getKLevelNodeCount(root.right,k-1);//子问题思想 因为是递归所以会递推过去可以采取层数递减的方式
}
2.8.5获取二叉树的高度(子问题思想)
(1)判断空树
(2)高度分为左树和右树
(3)根节点也1个高度
高度=左子树高度+右子树高度+1
public int getHeight(TreeNode root){
if(root==null){
return 0;
}
int leftHeight=getHeight(root.left);
int rightHeight=getHeight(root.right);
return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
}
2.8.6检测值为val的元素是否存在
(1)判断空值
(2)判断条件 查找值为val的元素相等的
(3)遍历 如果找到的话就返回到根节点结束
public TreeNode find(TreeNode root, int val){ //理解 递归先下好条件,递归中途是不会有值出现的直到满足条件才会出现值,在遍历之后进行判断
if(root==null){
return null;
}
if(root.val==val){
return root;
}
TreeNode fag1=find(root.left,val);
if(fag1!=null){
return fag1;
}
TreeNode fag2=find(root.right,val);
if(fag2!=null){
return fag2;
}
return null;
}
2.8.7层序遍历(图解)
(1)判断空树
(2)建立一个队来装载二叉树的每个节点
(3)判断队不空才能接收
public void levelOrder(TreeNode root) {
if(root == null) {
return;
}
Queue<TreeNode> qu = new LinkedList<>();
qu.offer(root); //先将根节点给入队
while (!qu.isEmpty()) { //判断队列不空
TreeNode cur = qu.poll(); //出队 为了接收当前根节点的子节点
System.out.print(cur.val+" "); //当前根节点就可以打印了
if(cur.left != null) { //左子树不为空,入队
qu.offer(cur.left);
}
if(cur.right != null) { //右子树不为空,入队
qu.offer(cur.right);
}
}
}
2.8.8判断一棵树是不是完全二叉树
(1)判断空树
(2)建立队列存放根节点
(3)队列里不为空用cur临时接收队列出队的跟节点
(4)这里是层序遍历 以空为判断遍历结束
(5)队列的剩余如果全部为空就是真
图一:判断为空之前的图解
2、图解:出队图解
public boolean isCompleteTree(TreeNode root){ //完全二叉树与层序遍历有相类似
if(root==null){
return true;
}
Queue<TreeNode> qu=new LinkedList<>(); //建立队入队
qu.offer(root); //根节点入队
while(!qu.isEmpty()){
TreeNode cur=qu.poll();
if(cur!=null){ //特殊在这里
qu.offer(cur.left);
qu.offer(cur.right);
}else{ //用空来判断是否已经结束
break;
}
}
while(!qu.isEmpty()){ //当前入队的不仅仅是树的节点还有null
TreeNode cur=qu.poll();
int size=qu.size();
if(size==0&&cur!=null){ //判断如果最后一个是子节点的前面都是null的特殊位置
return false;
}
if(cur!=null){ //其他情况都可以跳出
break;
}
}
if(qu.isEmpty()){ //最后遍历完了,整个队列都是空的,只有判断整个队列的都空则是完全二叉树
return true;
}
return false;
}