本题考查
AVL树
分析
AVL树详细解析
直接实现一个AVL树,插入所有节点后,读取根节点key值。
四种错误情况
LL: 左子树深度大于右子树,且左子树的左子树大于左子树的右子树
RR: 右子树深度大于左子树,且右子树的右子树大于右子树的左子树
LR: 左子树深度大于右子树,且左子树的右子树大于左子树的左子树
RL: 右子树深度大于左子树,且右子树的左子树大于右子树的右子树
通俗理解这两个字母分别代表子树中哪个深度更大。
四种解决方法
LL: 对根节点使用一次右旋即可解决
RR: 对根节点使用一次左旋即可解决
LR: 先对根节点的左子树使用一次左旋。在对根节点使用一次右旋
RL: 先对根节点的右子树使用一次右旋。在对根节点使用一次左旋
左旋
左旋就是将根节点的右孩子转化成新的根节点,如图也就是将k2代替k1成为根节点,需要将k2的左孩子置于k1右孩子上,k2的右孩子保留,然后进行旋转,使k2成为新的根节点
右旋
右旋就是将根节点的左孩子转化成新的根节点,如图也就是将k2代替k3成为根节点,需要将k2的右孩子置于k3左孩子上,k2的左孩子保留,然后进行旋转,使k2成为新的根节点
PS:提醒一下自己,递归函数返回值是第一层函数的返回值,而不是下面几层。
AC代码
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
static class Node{
private int key;
private Node leftChild;
private Node rightChild;
public Node(int key) {
this.key = key;
this.leftChild = null;
this.rightChild = null;
}
}
static class AVLTree{
Node root;
public AVLTree() {
root = null;
}
public void insert(int i) {
this.root = _insert(this.root, i);
}
public Node rebalance(Node root) {
int factor = getBalanceFactor(root);
if(factor > 1 && getBalanceFactor(root.leftChild) > 0) // LL
root = R(root);
else if(factor > 1 && getBalanceFactor(root.leftChild) <= 0) { //LR
root.leftChild = L(root.leftChild);
root = R(root);
}
else if(factor < -1 && getBalanceFactor(root.rightChild) <= 0) // RR
root = L(root);
else if(factor < -1 && getBalanceFactor(root.rightChild) > 0) { // RL
root.rightChild = R(root.rightChild);
root = L(root);
}
else;// 除以上情形外啥也不做
return root;
}
//此函数用于层序遍历,不是题目要求的函数
public void level(Node root ,int level) {
Node temp = root;
if(al.size() - 1 < level) {
String temp1 = String.valueOf(temp.key);
al.add(temp1);
}
else {
String temp1 = al.get(level) + " " + String.valueOf(temp.key);
al.set(level, temp1);
}
if(root.leftChild != null)
level(root.leftChild,level+1);
if(root.rightChild != null)
level(root.rightChild,level+1);
}
private Node R(Node root) {
Node temp = root.leftChild;
root.leftChild = temp.rightChild;
temp.rightChild=root;
root = temp;
return root;
}
private Node L(Node root) {
Node temp = root.rightChild;
root.rightChild = temp.leftChild;
temp.leftChild = root;
root = temp;
return root;
}
private Node _insert(Node root , int i) {
if(root == null)
root = new Node(i);
else {
if(i > root.key)
root.rightChild = _insert(root.rightChild,i);
else if(i < root.key)
root.leftChild = _insert(root.leftChild,i);
else;
}
root = rebalance(root);
return root;
}
private int getBalanceFactor(Node n) {
if(n.leftChild != null && n.rightChild != null)
return getHeight(n.leftChild) - getHeight(n.rightChild);
else if(n.leftChild != null && n.rightChild == null)
return getHeight(n.leftChild);
else if(n.leftChild == null && n.rightChild != null)
return 0 - getHeight(n.rightChild);
else
return 0;
}
private int getHeight(Node n) {
return height(n,1);
}
private int height(Node n, int level) {
if (n.leftChild == null && n.rightChild == null)
return level;
else if (n.leftChild != null && n.rightChild != null)
return Math.max(height(n.leftChild, level + 1), height(n.rightChild, level + 1));
else if (n.leftChild != null)
return height(n.leftChild, level + 1);
else
return height(n.rightChild, level + 1);
}
}
public static void main(String[] args) {
Scanner scaner = new Scanner(System.in);
int round = scaner.nextInt();
AVLTree avlTree = new AVLTree();
for(int i = 0 ; i< round ; i++) {
avlTree.insert(scaner.nextInt());
}
scaner.close();
System.out.println(avlTree.root.key);
}
}