public class BinartTree {public class Node { // 节点的定义public int data;public Node left;public Node right;}private Node root = null;
}
用数组来存储所有的节点。根节点存储在下标为1的位置
节点之间的父子关系,通过数组下表计算得到:如果节点x的下标是i
——下标为 i*2 的位置存储左子节点
——下标为 2*i+1 的位置存储右子节点
——下标为 i / 2 的位置存储就是父节点
这种存储方式基本只适用于完全二叉树,因为非完全二叉树会产生很多的空洞。
先打印根节点,然后再先序遍历左子树,最后先序遍历右子树
public void preOrder(Node root) {if (root == null) return;System.out.println(root.data);preOrder(root.left);preOrder(root.right);
}
先中序遍历左子树,再打印根节点,最后中序遍历右子树
public void inOrder(Node root) {if (root == null) return;inOrder(root.left);System.out.println(root.data);inOrder(root.right);
}
先后序遍历左子树,再后序遍历右子树,最后打印根节点
public void postOrder(Node root) {if (root == null) return;postOrder(root.left);postOrder(root.right);System.out.println(root.data);
}
二叉查找树是一种特殊的二叉树,支持快速查找、插入、删除数据
对于二叉查找树中任意一个节点,其左子树中每个节点的值,都小于这个节点的值。其右子树每个节点的值,都大于这个节点的值
public class Node {private int data;private Node left;private Node right;public Node(int data) {this.data = data;}
}private Node root = null;public Node find_r(Node root, int data) {if (root == null) return null;if (root.data == data) return root;if (data < root.data) {return find_r(root.left, data);} else {return find_r(root.right, data);}
}
public Node find(Node root, int data) {Node p = root;while (p != null) {if (data < p.data) {p = p.left;} else if (data > p.data) {p = p.right;} else {return p;}}return null;
}
如果要插入的数比当前节点的值小,且当前节点的左子树为空,则将新数据插入到左子节点的位置,如果左子树不为空,再递归遍历左子树,找到插入位置
如果要插入的数比当前节点的值大,且当前节点的右子树为空,则将新数据插入到右子节点的位置,如果右子树不为空,再递归遍历右子树,找到插入位置
if (root == null) {root = new Node(data);return;
}public void insert_r(Node root, int data) {if (data > root.data) {if (root.right == null) {root.right = new Node(data);} else {insert_r(root.right, data);}} else {if (root.left == null) {root.left = new Node(data);} else {insert_r(root.left, data);}}
}
public void insert(int data) {if (root == null) {root = new Node(data);return;}Node p = root;while(p != null) {if(data > p.data) {if (p.right == null) {p.right = new Node(data);return;}p = p.right;} else {if (p.left == null) {p.left = new Node(data);return;}p = p.left;}}
}
针对待删除的节点的子节点的个数不同,分三种情况处理
public void delete(int data) {Node p = root; // p指向要删除的节点,初始化指向根节点Node pp = null; // pp指向的是p的父节点while(p != null && p.data != data) { // 查找要删除的节点及其父节点pp = p;if (data > p.data) p = p.right;else p = p.left;}if (p == null) return; // 没找到// 要删除的节点有两个子节点if(p.left != null && p.right != null) { // 查找右子树的最小节点Node minP = p.right;Node minPP = p; // minPP表示minP的父节点while (minP.left != null) {minPP = minP;minP = minP.left;}p.data = minP.data;p = minP;pp = minPP;}// 删除节点是叶子节点或者只有一个子节点Node child = null;if (p.left != null) child = p.left;else if (p.right != null) child = p.right;if (pp == null) root = child; // 删除的是根节点else if (pp.left == p) pp.left = child;else pp.right = child;
}
链接:https://leetcode.cn/problems/n-ary-tree-preorder-traversal
给定一个 n 叉树的根节点 root ,返回 其节点值的 前序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6]
输出:[1,3,5,6,2,4]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
输出:[1,2,3,6,7,11,14,4,8,12,5,9,13,10]
提示:
节点总数在范围 [0, 104]内
0 <= Node.val <= 104
n 叉树的高度小于或等于 1000
进阶:递归法很简单,你可以使用迭代法完成此题吗?
/*
// Definition for a Node.
class Node {public int val;public List children;public Node() {}public Node(int _val) {val = _val;}public Node(int _val, List _children) {val = _val;children = _children;}
};
*/class Solution {List result = new ArrayList<>();public List preorder(Node root) {preorder_r(root);return result;}public void preorder_r(Node root) {if (root == null) return;result.add(root.val);for (int i = 0; i < root.children.size(); i++) {preorder_r(root.children.get(i));}}
}
链接:https://leetcode.cn/problems/n-ary-tree-postorder-traversal
给定一个 n 叉树的根节点 root ,返回 其节点值的 后序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6]
输出:[5,6,3,2,4,1]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
输出:[2,6,14,11,7,3,12,8,4,13,9,10,5,1]
提示:
节点总数在范围 [0, 104] 内
0 <= Node.val <= 104
n 叉树的高度小于或等于 1000
进阶:递归法很简单,你可以使用迭代法完成此题吗?
/*
// Definition for a Node.
class Node {public int val;public List children;public Node() {}public Node(int _val) {val = _val;}public Node(int _val, List _children) {val = _val;children = _children;}
};
*/class Solution {List result = new ArrayList<>();public List postorder(Node root) {postorder_r(root);return result;}public void postorder_r(Node root) {if (root == null) return;for (int i = 0; i < root.children.size(); i++) {postorder_r(root.children.get(i));}result.add(root.val);}
}
链接:https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3/ \9 20/ \15 7
返回:
[3,9,20,15,7]
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val = x; }* }*/
class Solution {public int[] levelOrder(TreeNode root) {if (root == null) return new int[0];List result = new ArrayList<>();Queue queue = new LinkedList<>();queue.add(root);while (!queue.isEmpty()) {TreeNode node = queue.poll();result.add(node.val);if (node.left != null) {queue.add(node.left);}if (node.right != null) {queue.add(node.right);}}int[] resultArray = new int[result.size()];for (int i = 0; i < result.size(); i++) {resultArray[i] = result.get(i);}return resultArray;}
}
链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3/ \9 20/ \15 7
返回它的最大深度 3 。
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public int maxDepth(TreeNode root) {if (root == null) {return 0;}return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;}
}
链接:https://leetcode.cn/problems/ping-heng-er-cha-shu-lcof
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3/ \9 20/ \15 7
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1/ \2 2/ \3 3/ \4 4
返回 false 。
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val = x; }* }*/
class Solution {private boolean balanced = true;public boolean isBalanced(TreeNode root) {height(root);return balanced;}private int height(TreeNode root) {if (root == null) return 0;if (balanced == false) return 0;int leftHeight = height(root.left);int rightHeight = height(root.right);if (Math.abs(leftHeight - rightHeight) > 1) {balanced = false;}return Math.max(leftHeight, rightHeight) + 1;}
}
链接:https://leetcode.cn/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/
1 4
2
输出: 4
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/
3 6
/
2 4
/
1
输出: 4
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val = x; }* }*/
class Solution {int count = 0;int result;public int kthLargest(TreeNode root, int k) {inorder(root, k);return result;}private void inorder(TreeNode root, int k) {if (count >= k) return;if (root == null) return;inorder(root.right, k);count++;if (count == k) {result = root.val;return;}inorder(root.left, k);}
}