我在旋转树和返回旋转树时遇到问题。几乎在将新树插入我的 AVL 后,我检查平衡是否为 <-1 并且父高度为 <0,它是右右情况,我需要实现左旋转。我需要帮助来理解为什么我的左旋转不起作用,如果它有效,为什么我没有返回旋转的树。
public class AVLTree < T extends Comparable < T >> extends BinaryTree < T>
{
private int balance ;
private AVLTree < T> parent;
public AVLTree(T item){
this(item,null);
}
public AVLTree(T item, AVLTree<T> parent){
super(item);
this.balance = 0;
this.parent = parent;
}
public AVLTree<T> insert(T item){
updateHeight(this);
if(this.item.compareTo(item) < 0){
if(this.left != null){
this.left.insert(item);
}
else{
this.left= new AVLTree<T>(item, this);
}
return rotations((AVLTree<T>)this.left);
}
else{
if(this.right != null){
this.right.insert(item);
}
else{
this.right = new AVLTree<T>(item, this);
}
return rotations((AVLTree<T>)this.right);
}
}
private AVLTree<T> rotateLeft(AVLTree<T> x){
AVLTree<T> temp = (AVLTree<T>)x.parent;
AVLTree<T> an = (AVLTree<T>)temp.left;
//rotation
temp.left = x;
temp.right = x.parent.right;
x.right = an;
//update heights
updateHeight(x);
updateHeight(temp);
//return new root
return temp;
}
public AVLTree<T> rotations(AVLTree<T> input){
int balance = getBalance(input);
//Right Right
if (balance < -1 && ph() < 0){
return input =rotateLeft(input);
}
return input;
}
public void updateHeight(AVLTree<T> current){
current.height = Math.max(height((AVLTree<T>)current.left),
height((AVLTree<T>)current.right)) + 1;
}
public int getBalance(){
return getBalance(this);
}
public int getBalance(AVLTree<T> current){
return (current == null)? 0 : height((AVLTree<T>)current.right) -
height((AVLTree<T>)current.left);
}
public int ph(){
return lbal()-rbal();
}
int lbal(){
if(this.right== null){
return 0;
}
return (height(this.right));
}
int rbal(){
if(this.left == null){
return 0;
}
return height(this.left);
}
///这是BST类
import java.util.*;
public class BinaryTree <T extends Comparable<T>> extends Tree<Comparable<T>>{
public BinaryTree<T> left;
public BinaryTree<T> right;
int size;
int height;
public BinaryTree(T item){
super(item);
this.item = item;
this.left = null;
this.right= null;
}
public BinaryTree<T> find(T item){
if(this.item.compareTo(item)==0){
return this;
}
if(this.item.compareTo(item)<0){
if(this.left != null){
if(this.left.item.compareTo(item) == 0){
return this.left;
}
else{
return this.left.find(item);
}
}
}
else{
if(this.right != null){
if(this.right.item.compareTo(item) == 0){
return this.right;
}
else{
return this.right.find(item);
}
}
}
return null;
}
public BinaryTree<T> insert(T item){
if(this.item.compareTo(item) < 0){
if(this.left != null){
this.left.insert(item);
}
else{
this.left = new BinaryTree<T>(item);
}
return this.left;
}
else{
if(this.right != null){
this.right.insert(item);
}
else{
this.right = new BinaryTree<T>(item);
}
return this.right;
}
}
第4部分 测量
public int size(){
return size(this);
}
public int size(BinaryTree<T> point){
if(point == null){
return 0;
}
else{
return (size(point.left)+1+size(point.right));
}
}
/*
*public int height() {
height = 1;
if (left != null) {
height += left.height;
}
if (right != null) {
height += right.height;
}
return height;
}
*
* */
public int height(){
return height(this);
}
public int height(BinaryTree<T> point) {
if(point == null){
return 0;
}
return (Math.max(height(point.right), height(point.left))+1);
}
//Part 3
public ArrayList<T> nlr(){
return nlr(this);
}
private ArrayList<T> nlr(BinaryTree<T> point){
ArrayList arr = new ArrayList();
if (point == null){
return arr;
}
arr.add(point.item);
arr.addAll(nlr(point.left));
arr.addAll(nlr(point.right));
return arr;
}
public ArrayList<T> lnr(){
return lnr(this);
}
private ArrayList<T> lnr(BinaryTree<T> point){
ArrayList arr = new ArrayList();
if (point == null){
return arr;
}
arr.addAll(lnr(point.left));
arr.add(point.item);
arr.addAll(lnr(point.right));
return arr;
}
public ArrayList<T> lrn(){
return lrn(this);
}
private ArrayList<T> lrn(BinaryTree<T> point){
ArrayList arr = new ArrayList();
if (point == null){
return arr;
}
arr.addAll(lrn(point.left));
arr.addAll(lrn(point.right));
arr.add(point.item);
return arr;
}
public ArrayList<T> bfs(){
return bfs(this);
}
private ArrayList<T> bfs(BinaryTree<T> input){
Queue<BinaryTree> queue = new LinkedList<BinaryTree>();
ArrayList arr = new ArrayList();
queue.add(input);
while(!queue.isEmpty()){
input = queue.remove();
arr.add(input.item);
if(input.left != null){
queue.add(input.left);
}
if(input.right != null){
queue.add(input.right);
}
}
return arr;
}
public BinaryTree<T> rotateLeft(){
return null;
}
public BinaryTree<T> rotateRight(){
return null;
}
}
我注意到这次旋转的一件事。 对于向左旋转,您向上旋转右子树以获得正确的旋转
//rotation
temp.left = x;
//this is making the right child now the left child of the parent.
temp.right = x.parent.right;
//this is making the same right sub tree copied to the left
//which needs to be rotated the child of the right side as well which it
//should already be.(does nothing)
x.right = an;
//making this a right child(without check if there is a node) of the right
//subtree.
//So this is in actuality not doing a correct rotation for an AVL tree.
请将上面的代码替换为:
AVLTree<T> temp1 = (AVLTree<T>)x.parent;
temp1.right = x.left;
//make the left node of the right subtree the new right node of the parent
x.left = temp1;
//make the current parent the left child of the right subtree(rotation).
x.parent = temp1.parent;
//make the parent of the right subtree point to the parent of the parent
//keeping tree integrity.
temp1.parent = x;
//make the parent pointer to what used to be the right child.
//this completes a single left rotation for an AVL tree.
return x;
//the node that is now the parent node of the rotated subtree
//or the new root node. if the rotation happened at the top.
请检查 https://en.wikipedia.org/wiki/AVL_tree 以获取完整说明以及 AVL 树如何与所有旋转配合使用单次和双次旋转的代码片段的旋转。
问题是搜索功能BinaryTree<T> find(T item)
是在父类BinaryTree
中实现的,而这个类,因为它应该对子类AVLTree
没有任何了解。
find()
方法返回一个BinaryTree
,所以即使你构造了一个AVLTree
的实例,当你调用find()
时,你也会得到一个BinaryTree
。
假设AVLTree<T> insert(T item)
实现正确,树节点正在正确组装,因此您可以简单地将调用find()
的结果类型转换为AVLTree