PAT甲级1066 Root of AVL Tree(JAVA版)

31 篇文章 0 订阅

本题考查

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);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值