Я пытаюсь сбалансировать двоичное дерево поиска.
Я балансирую дерево после метода вставки. Я надеюсь, что кто-нибудь из присутствующих может помочь мне в этом.
Метод - balanceTheTree (...). Я использовал рекурсивный метод, я не знаю, лучшее ли это решение
public class BinaryTreeTable<E extends Comparable<E>, T> implements Table<E, T> {
private Node root;
public BinaryTreeTable() {
this.root = new Node(null, null, null);
}
@Override
public boolean insert(E key, T data) {
boolean ret;
if (this.root.key == null) {
Node toInsert = new Node(null, key, data);
this.root = toInsert;
ret = true;
} else {
Node father = this.seekFather(key);
if (father == null) {
ret = false;
} else {
Node toInsert = new Node(father, key, data);
if (key.compareTo(father.key) > 0) {
father.rSon = toInsert;
ret = true;
balanceTheTree(toInsert);
} else if (key.compareTo(father.key) < 0) {
father.lSon = toInsert;
ret = true;
balanceTheTree(toInsert);
} else {
ret = false;
}
}
}
return ret;
}
private void rightRotation(Node theN) {
Node k2 = theN.rSon;
theN.rSon = k2.lSon;
k2.lSon = theN;
}
private void leftRotation(Node theN) {
Node k1 = theN.lSon;
theN.lSon = k1.rSon;
k1.rSon = theN;
}
private void leftRightRotation(Node theN) {
leftRotation(theN.rSon);
rightRotation(theN);
}
private void rightLeftRotation(Node theN) {
rightRotation(theN.lSon);
leftRotation(theN);
}
private void balanceTheTree(Node theN) {
if (theN == null) {
} else {
if (Math.abs(Math.subtractExact(computeH(theN.rSon), computeH(theN.lSon))) > 1) {
System.out.println("A droite " + theN.getLabel());
if (computeH(theN.lSon) > computeH(theN.rSon)) {
leftRotation(theN);
} else {
leftRightRotation(theN);
}
} else if (Math.abs(Math.subtractExact(computeH(theN.lSon), computeH(theN.rSon))) > 1) {
System.out.println("A gauche");
} else {
balanceTheTree(theN.rSon);
balanceTheTree(theN.lSon);
}
}
}
private int computeH(Node theN) {
int ret = 1;
if (theN == null) {
ret = 0;
} else if ((theN.lSon != null) && (theN.rSon == null)) {
ret = computeH(theN.lSon) + 1;
} else if ((theN.lSon == null) && (theN.rSon != null)) {
ret = computeH(theN.rSon) + 1;
} else if ((theN.lSon != null) && (theN.rSon != null)) {
ret = Math.max(computeH(theN.lSon), computeH(theN.rSon)) + 1;
}
return ret;
}
public class Node {
// Attributs
private Node lSon ;
private Node rSon ;
private Node father ;
private T theValue ;
private E key ;
// Constructeur
public Node (Node father, E key, T theValue) {
this.father = father;
this.key = key;
this.theValue = theValue;
}
public String getLabel() {
return String.valueOf(key);
}
public Node getLeft() {
return lSon;
}
public Node getRight() {
return rSon;
}
public Node clone() {
return new Node(this.father, this.key, this.theValue);
}
}
}
Метод computeH () позволяет мне узнать размер узла
Метод вставки работает правильно .
Дерево, которое я хочу сбалансировать
public static void main(String[] args) {
BinaryTreeTable binaryTreeTable = new BinaryTreeTable();
binaryTreeTable.insert(10, "Test");
binaryTreeTable.insert(5, "Test");
binaryTreeTable.insert(7, "Test");
binaryTreeTable.insert(3, "Test");
binaryTreeTable.insert(4, "Test");
binaryTreeTable.insert(15, "Test");
binaryTreeTable.insert(19, "Test");
binaryTreeTable.insert(16, "Test");
binaryTreeTable.insert(20, "Test");
binaryTreeTable.showTree();
}