删除二叉树叶子节点的问题
问题描述:请你来设计一个算法,采用递归的方式,将二叉树的叶子结点都删掉。
以此图为例,要求便是删除9,15,7三个节点
解题:
- 我们需要实现以下步骤
- 二叉树的定义
class TreeNode {
public Integer val;
public TreeNode left;
public TreeNode right;
public TreeNode(Integer val) {
this.val = val;
}
- 根据数组构建二叉树
- 在二叉树构建的过程中,树的根节点是下标为0的元素节点
- 左右节点分别是 2index+1,2index+2
- 依据以上规则,我们编写递归函数,构建二叉树,代码如下:
private static TreeNode init(Integer[] nums, int index) {
if (index >= nums.length || nums[index] == null) {
return null;
}
TreeNode root = new TreeNode(nums[index]);
root.left = init(nums, 2 * index + 1);
root.right = init(nums, 2 * index + 2);
return root;
}
- 编写输出二叉树路径的函数
- 采用深度优先遍历,找出从根节点到子节点的路径
public static void getdfs(TreeNode root, String path, List<String> pathList) {
if (root == null) {
return;
}
path += root.val;
if (root.left == null && root.right == null) {
pathList.add(path);
}
path += "->";
getdfs(root.left, path, pathList);
getdfs(root.right, path, pathList);
}
- 删除叶子结点的方法、
- 思路:
- 判断一个节点的左节点的左右节点是否是null,如果是,说明该节点的左节点是叶子结点,则将该节点的左节点变为null,例如在上述的案例中,我们判断3的左节点9的左右节点为空,则需要将9删除,即root.left=null
- 同理我们判断一个节点的右节点的左右节点是否为null,执行相同的操作
- 采用递归的方式,判断左右子树
public static void delete(TreeNode root) {
if (root == null) {
return;
}
// 如果是叶子结点直接返回
if (root.left == null && root.right == null) {
return;
}
// 要找到叶子结点的上一个节点的父节点记性判断
if (root.left != null) {
if (root.left.left == null && root.left.right == null) {
root.left = null;
}
}
// 判断右子树的节点是否是
if (root.right != null) {
if (root.right.right == null && root.right.left == null) {
root.right = null;
}
}
delete(root.left);
delete(root.right);
}
- 全部代码如下:
package com.lmx.project.eight;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Challenge {
/**
* 返回层次遍历的结果
*/
public static List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
// 遍历条件
while (queue.size() > 0) {
int size = queue.size();
final ArrayList<Integer> temp = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode peek = queue.poll();
temp.add(peek.val);
if (peek.left != null) {
queue.add(peek.left);
}
if (peek.right != null) {
queue.add(peek.right);
}
}
result.add(temp);
}
return result;
}
/**
* 实现获取二叉树路径
* @param root
* @param path
* @param pathList
*/
public static void getdfs(TreeNode root, String path, List<String> pathList) {
if (root == null) {
return;
}
path += root.val;
if (root.left == null && root.right == null) {
pathList.add(path);
}
path += "->";
getdfs(root.left, path, pathList);
getdfs(root.right, path, pathList);
}
/**
* 根据数组构建二叉树
*
* @param nums
* @param index
* @return
*/
private static TreeNode init(Integer[] nums, int index) {
if (index >= nums.length || nums[index] == null) {
return null;
}
TreeNode root = new TreeNode(nums[index]);
root.left = init(nums, 2 * index + 1);
root.right = init(nums, 2 * index + 2);
return root;
}
public static void delete(TreeNode root) {
if (root == null) {
return;
}
// 如果是叶子结点直接返回
if (root.left == null && root.right == null) {
return;
}
// 要找到叶子结点的上一个节点的父节点记性判断
if (root.left != null) {
if (root.left.left == null && root.left.right == null) {
root.left = null;
}
}
// 判断右子树的节点是否是
if (root.right != null) {
if (root.right.right == null && root.right.left == null) {
root.right = null;
}
}
delete(root.left);
delete(root.right);
}
// 构建一个数
public static void main(String[] args) {
TreeNode root;
Integer[] nums = new Integer[]{3, 9, 20, null, null, 15, 7};
root = init(nums, 0);
final ArrayList<String> pathList = new ArrayList<>();
getdfs(root,"", pathList);
System.out.println("pathList = " + pathList);
delete(root);
pathList.clear();
getdfs(root,"",pathList);
System.out.println("pathList = " + pathList);
// System.out.println("rightSideView(treeNode) = " + leftSideView(root));
}
}
/**
* 二叉树的定义
*/
class TreeNode {
public Integer val;
public TreeNode left;
public TreeNode right;
public TreeNode(Integer val) {
this.val = val;
}
}