1. 下面这个东西就叫做二叉树
class TreeNode{
int key;
TreeNode left;
TreeNode right;
TreeNode parent;
public TreeNode(int key){
this.key = key;
left = null;
right = null;
parent = null;
}
}
- 递归求二叉树的高度(即根节点到叶子节点的最长的长度)
public static int getHeight(TreeNode root){
if(root == null) return 0;
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
2. 前序遍历、中序遍历、后序遍历
2.1 前序遍历(中左右)
public static void preOrder(TreeNode root){
if(root != null){
System.out.println(root.key);
preOrder(root.left);
preOrder(root.right);
}
}
2.2 中序遍历(左中右)
public static void inOrder(TreeNode root){
if(root != null){
preOrder(root.left);
System.out.println(root.key);
preOrder(root.right);
}
}
2.3 后序遍历(左右中)
public static void postOrder(TreeNode root){
if(root != null){
preOrder(root.left);
preOrder(root.right);
System.out.println(root.key);
}
}
2.4 关于遍历的小知识
- 前序遍历和中序遍历能唯一确定一棵树;同理,后序遍历和中序遍历也可以;但是前序遍历和后续遍历却不行,下图就是一个反例。
3. 二叉搜索树
3.1 定义
- 不等式:左孩子节点的值 ≤ 节点的值 ≤ 右孩子节点的值
3.2 二叉搜索树的判定
- 大致思想:自顶向下遍历各个节点,一旦发现某个节点不符合搜索树的不等式,则该树不是搜索树,返回false。如果到达叶子节点依然没有返回false,则返回true。
- 时间复杂度:O(n) (不是O(nlgn),PPT上的不对。不过无关紧要,这不是很重要。)
public static boolean isBST(TreeNode root){
if(root == null) return true;
if (root.left != null && root.left.max() > root.key) return false;
if (root.right != null && root.right.min() < root.key) return false;
return isBST(root.left) && isBST(root.right);
}
3.3 如何将二叉搜索树中的值按从小到大顺序输出?
- 使用中序遍历(左中右):例如上面的二叉搜索树,中序遍历的输出为2,3,4,6,7,9,13,15,17,18,20。
3.4 在BST中查找某个元素
TreeNode search(int key) {
TreeNode cur = root;
while (cur != null && cur.key != key)
cur = cur.key > key ? cur.left:cur.right;
return cur;
}
3.4.2 使用递归
TreeNode search(TreeNode root, int key){
if (root == null || root.key == key)
return root;
return root.key > key ? search(root.left, key):search(root.right, key);
}
3.5 查找BST中的最大最小值
public TreeNode maximum (TreeNode node) {
while (node != null && node.right != null) {
node = node.right;
}
return node;
}
public TreeNode minimum (TreeNode node) {
while (node != null && node.left !=null) {
node = node.left;
}
return node;
}
3.6 前驱后继
3.6.1 后继
- 后继:比x大的最小的数,称为x的后继。例如,下图中,6的后继是7。
TreeNode successor(TreeNode node) {
if (node.right != null) {
return minimum(node.right);
}
TreeNode y = node.parent;
while (y != null && node == y.right) {
node = y;
y = y.parent;
}
return y;
}
3.6.2 前驱
- 前驱:比x小的最大的数,称为x的前驱。例如,下图中,6的前驱是3。
TreeNode predecessor(TreeNode node) {
if (node.left != null) {
return maximum(node.left);
}
TreeNode y = node.parent;
while (y != null && node == y.left) {
node = y;
y = y.parent;
}
return y;
}
3.7 插入元素
public void insert(TreeNode node) {
TreeNode y = null;
TreeNode x = this.root;
while (x != null) {
y = x;
x = node.key < x.key ? x.left:x.right;
}
node.parent = y;
if (y == null)
this.root = node;
else if (node.key < y.key)
y.left = node;
else
y.right = node;
}
3.8 删除元素
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (key < root.key) {
root.left = deleteNode(root.left, key);
return root;
} else if (key > root.key) {
root.right = deleteNode(root.right, key);
return root;
} else {
if (root.left == null) {
return root.right;
} else if (root.right == null) {
return root.left;
} else {
TreeNode successor = successor(root);
successor.right = predecessor(root.right);
successor.left = root.left;
return successor;
}
}
}