Bruderbaum
Der Bruderbaum
Definition:
Ein Bruderbaum ist ein Baum, bei dem jeder innere Knoten entweder zwei Kinder hat, oder er hat nur ein Kind und einen Bruder, der zwei Kinder hat.Alle Blätter liegen auf einer Höhe, sie enthalten die Daten. In einem Knoten steht immer das höchste Element des linken Teilbaumes des Knotens.
Implementierung:
download
/*
* Created on 30-Nov-2003
*
*/
/**
* @author Lina Ourima
* ich übernehme keine garantie für die korrektheit dieser
* implementierung, ich habe aber mein bestes versucht
*/
public class BrotherTree {
Node root;
public static void main(String[] args) {
BrotherTree b = new BrotherTree();
for(int i = 0; i < 6; i++){
b.insert(i);
boolean bool = b.isBrotherTree();
System.out.println("Bruderbaum? "+bool);
if(!bool) return;
}
for(int i = 0; i < 6; i++){
System.out.print(i+" löschen... ");
boolean bool = b.delete(i);
System.out.println(bool);
if(!bool) return;
b.print();
b.printLeaves();
bool = b.isBrotherTree();
System.out.println("Bruderbaum? "+bool);
if(!bool) return;
}
}
int height = -1;
boolean isBrotherTree()
{
height = -1;
return hasSameHeight(root, 0) && isBrotherTree(root);
}
boolean hasSameHeight(Node n, int h){
boolean b = true;
if(n == null) return true;
if(n.left== null && n.right == null){
if(height == -1){
height = h;
}
if(height != h){
System.out.println("Blatt["+n.nr+":"+n.number+"] auf Höhe "+h+" sollte Höhe "+height+" sein!");
return false;
}
return true;
}
if(n.left!= null){
b = hasSameHeight(n.left, h+1);
}
if(n.right!= null){
b = b && hasSameHeight(n.right, h+1);
}
return b;
}
boolean isBrotherTree(Node n)
{
if(n == null) return true;
if(n.left == null && n.right == null) return true;
if(n.left == null) { //wurzel hat nur ein kind
System.out.println("Linkes Kind von "+n.nr+":"+n.number+"ist null");
return false;
}
if(n.right == null) {//wurzel hat nur ein kind
System.out.println("Wurzel "+n.nr+":"+n.number+" hat nur ein Kind");
return false;
}
int gc = 0;
if(n.right.left != null) gc++;
if(n.right.right != null) gc++;
if(n.left.left != null) gc++;
if(n.left.right != null) gc++;
if(gc > 2 || gc == 0) {
if(n.right.right == null){
return isBrotherTree(n.right.left) && isBrotherTree(n.left);
}
if(n.left.right == null){
return isBrotherTree(n.right) && isBrotherTree(n.left.left);
}
return isBrotherTree(n.right) && isBrotherTree(n.left);
} else {
System.out.println("Knoten "+n.nr+":"+n.number+" hat nur "+gc+" Enkel");
return false;
}
}
void printLeaves()
{
System.out.println("***Print Leaves***");
printLeaves(root);
System.out.println();
}
void printLeaves(Node n)
{
if(n == null){
System.out.print("null");
return;
}
if(n.left != null){
printLeaves(n.left);
}
if(n.left == null && n.right == null){
System.out.print("["+n.number+"]");
return;
}
if(n.right != null){
printLeaves(n.right);
}
}
String[] s = new String[20];
void print()
{
System.out.println("***Print Tree***");
for(int i = 0; i < 20; i++){
s[i] = "";
}
print(root, 0);
for(int i = 0; i < 20; i++){
if(s[i]!=""){
System.out.println(s[i]);
}
}
System.out.println();
}
void print(Node n, int h)
{
//Inorder
if(n == null){
s[h] += "Null";
return;
}
if(n.left != null){
print(n.left, h+1);
}
s[h] += n.toString();
if(n.right != null){
print(n.right, h+1);
}
}
boolean insert(int x){
System.out.println(x+" einfügen");
if(root == null){
root = new Node(x);
System.out.println("neue Wurzel");
print();
return true;
}
Node neighbar = findNeighbar(root, x);
if(neighbar == null) {
System.out.println("War schon vorhanden");
print();
return false;
} //Knoten schon vorhanden
Node n = new Node(x);
insert(neighbar, n);
changeLabels(n);
print();
return true;
}
Node find(Node n, int x){
if(n == null){
return null;
}
if(n.left == null && n.right == null){
if(n.number == x){
return n;
} else {
System.out.println(x+" nicht gefunden, fand stattdessen "+n.number);
return null;
}
}
if(n.right == null || x <= n.number){
return find(n.left, x);
}
if(x > n.number){
return find(n.right, x);
}
return null; // dahin dürfen wir im korrekten bruderbaum nicht kommen
}
boolean delete(int k){
Node n = find(root, k);
if(n == null){
System.out.println("Knoten nicht gefunden!");
return false;
}
delete(n);
return true;
}
Node getBrother(Node n){
if(n.parent == null) return null;
if(n.parent.left == n) return n.parent.right;
return n.parent.left;
}
void delete(Node n){
System.out.println("delete:: "+n);
//print();
if(n.parent == null){ // n wurzel
root = null;
return;
}
Node daddy = n.parent;
Node brother = getBrother(n);
if(daddy.parent == null){ // wurzel, ein kind wird gelöscht, baum verliert höhe
//bruder muss existieren (wurzel immer zwei kinder)
root = brother;
brother.parent = null;
brother.computeMax();
System.out.println("wurzel, ein kind wird gelöscht, baum verliert höhe wurzel: "+root);
return;
}
Node opa = daddy.parent;
if(daddy.right == null){ //vater hatte nur ein kind
System.out.println("vater hatte nur ein kind, delete "+daddy);
delete(daddy);
return;
}
daddy.deleteChild(n);
if(daddy.left == null){
//fehler....
System.out.println("daddy.left == null daddy: "+daddy.nr+":"+daddy.number);
}
Node uncle = getBrother(daddy);
if(uncle == null){ //kein onkel
Node urOpa = opa.parent;
System.out.println("kein Onkel ");
//jetzt muss vater onkel mit zwei kindern haben
Node daddysUncle = getBrother(opa);
if(urOpa.right == opa){ //opa hat linken bruder
System.out.println("opa hat linken bruder");
Node willbeDeleted = daddysUncle.right;
opa.setRightChild(daddy);
opa.setLeftChild(daddysUncle.right);
if(opa.right.right == null && opa.left.right == null){ // opa hat nur zwei enkel
System.out.println("verschmelzen");
opa.left.setRightChild(opa.right.left);
opa.right = null;
}
willbeDeleted.parent = daddysUncle;
delete(willbeDeleted);
return;
}else { //der bruder vom opa steht rechts
//opas linkes kind ist schon der daddy
System.out.println("opa hat rechten bruder");
Node willbeDeleted = daddysUncle.left;
opa.setRightChild(daddysUncle.left);
if(opa.right.right == null && opa.left.right == null){ // opa hat nur zwei enkel
System.out.println("verschmelzen");
opa.left.setRightChild(opa.right.left);
opa.right = null;
}
willbeDeleted.parent = daddysUncle;
delete(willbeDeleted);
return;
}
}
if(uncle.right != null){ // Onkel hat 2 Kinder
System.out.println("Onkel hat 2 Kinder");
changeLabels(opa);
return;
}
//Onkel hat nur ein Kind, verschmelzen
System.out.println("Onkel hat nur ein Kind, verschmelzen");
if(opa.left == daddy){
daddy.setRightChild(uncle.left);
delete(uncle);
} else {
uncle.setRightChild(daddy.left);
delete(daddy);
}
return;
}
void insert(Node neighbar, Node x){
if(neighbar.parent == null){//neighbar ist wurzel
if(x.number < neighbar.number){
root = new Node(x, neighbar);
} else {
root = new Node(neighbar, x);
}
return;
}
Node daddy = neighbar.parent;
if(daddy.right == null){ //vater hat nur ein kind
x.parent = daddy;
if(neighbar.number < x.number){
daddy.right = x;
daddy.max = x.max;
}
if(neighbar.number > x.number){
daddy.right = neighbar;
daddy.max = neighbar.max;
daddy.left = x;
daddy.number = x.max;
}
return;
//kann nicht gleich sein
}
// Vater hat zwei Kinder
Node one, two, three;
if(x.number < daddy.left.number) {
one = x;
two = daddy.left;
three = daddy.right;
} else
if(x.number > daddy.right.number){
one = daddy.left;
two = daddy.right;
three = x;
} else {
one = daddy.left;
two = x;
three = daddy.right;
}
if(daddy.parent == null){ //Vater Wurzel
System.out.println("Vater Wurzel");
daddy.setLeftChild(one);
daddy.setRightChild(two);
three.parent = new Node(three);
root = new Node(daddy, three.parent);
return;
}
Node opa = daddy.parent;
if(opa.right == null){ //Vater hat keinen Bruder
one.parent = new Node(one);
one.parent.parent = daddy.parent;
daddy.setLeftChild(two);
daddy.setRightChild(three);
opa.setLeftChild(one.parent);
opa.setRightChild(daddy);
return;
}
// Vater hat Bruder
Node uncle = getBrother(daddy);
Node orphant;
if(opa.right == uncle) {
orphant = three;
daddy.setLeftChild(one);
daddy.setRightChild(two);
} //Vater hat rechten Bruder
else {
orphant = one;
daddy.setLeftChild(two);
daddy.setRightChild(three);
}
//Vater hat Bruder
if(uncle.right == null){ //Bruder vom Vater hat nur ein Kind
uncle.addChild(orphant);
return;
} else {//Bruder vom Vater hat zwei Kinder
orphant.parent = new Node(orphant);
System.out.println("Bruder vom Vater hat zwei Kinder");
System.out.println("daddy.left "+daddy.left+"daddy.right "+daddy.right
+"uncle.left "+uncle.left+"uncle.right "+uncle.right
+"orphant "+orphant+"orphant.parent "+orphant.parent);
insert(daddy, orphant.parent);
return;
}
}
void changeLabels(Node n){
if(n != null && n.parent!=null){
if(n.parent.right!=null){
n.parent.max = n.parent.right.max;
} else {
/*System.out.println(n);
System.out.println(n.parent);
System.out.println(n.parent.max);
System.out.println(n.parent.left);*/
n.parent.max = n.parent.left.max;
}
n.parent.number = n.parent.left.max;
changeLabels(n.parent);
}
}
Node findNeighbar(Node n, int x){
if(n.number == x){
return null;
}
if(n.left == null){
System.out.println("Nachbar von "+x+" ist "+n);
return n;
}
if(n.right == null || x < n.number){
return findNeighbar(n.left, x);
}
if(x > n.number){
return findNeighbar(n.right, x);
}
return null;
}
static int numNode = 0;
class Node{
int number;
int max; //gröstes element in seinem teilbaum
Node left, right, parent;
int nr;
void computeMax(){
if(left == null){
return;
}
number = left.max;
if(right == null){
max = left.max;
return;
}
max = right.max;
}
void setLeftChild(Node n){
left = n;
if(left != null){
n.parent = this;
number = n.max;
} else {
if(right != null){
left = right;
number = left.max;
max = left.max;
right = null;
} else {
max = number;
}
}
}
void setRightChild(Node n){
right = n;
if(right != null){
n.parent = this;
max = n.max;
} else {
if(left != null){
max = left.max;
} else {
max = number;
}
}
}
void addChild(Node n){
if(left.number < n.number){
setRightChild(n);
} else {
setRightChild(left);
setLeftChild(n);
}
}
void deleteChild(Node n){
if(left == n){
setLeftChild(right);
right = null;
number = left.max;
max = left.max;
}
if(right == n){
right = null;
number = left.max;
max = left.max;
}
}
public String toString(){
if(left == null && right == null){
if(parent != null){
return "["+parent.nr+"<-"+nr+":"+number+"]";
}
if(parent != null){
return "[*null<-"+nr+":"+number+"*]";
}
}
String s = "";
if(parent == null){
s += "(*";
if(left!=null)s += left.nr+":"+left.number+" ";
s += "."+nr+":"+number+".";
if(right!=null) s += " "+right.nr+":"+right.number;
s += "*)";
} else {
s += "("+parent.nr+"<- ";
if(left!=null) s += left.nr+":"+left.number+" ";
s += "."+nr+":"+number+".";
if(right!=null) s += " "+right.nr+":"+right.number;
s += ")";
}
return s;
}
Node(int i){
number = i;
max = i;
nr = numNode;
numNode++;
}
Node(Node l){
number = l.max;
max = l.max;
left = l;
left.parent = this;
nr = numNode;
numNode++;
}
Node(Node l, Node r){
number = l.max;
max = r.max;
left = l;
right = r;
left.parent = this;
right.parent = this;
nr = numNode;
numNode++;
}
}
}
/*
0 einf³gen
neue Wurzel
***Print Tree***
(*.0:0.*)
Bruderbaum? true
1 einf³gen
Nachbar von 1 ist (*.0:0.*)
***Print Tree***
(*0:0 .2:0. 1:1*)
[2<-0:0][2<-1:1]
Bruderbaum? true
2 einf³gen
Nachbar von 2 ist [2<-1:1]
Vater Wurzel
***Print Tree***
(*2:0 .5:1. 4:2*)
(5<- 0:0 .2:0. 1:1)(5<- 3:2 .4:2.)
[2<-0:0][2<-1:1][4<-3:2]
Bruderbaum? true
3 einf³gen
Nachbar von 3 ist [4<-3:2]
***Print Tree***
(*2:0 .5:1. 4:2*)
(5<- 0:0 .2:0. 1:1)(5<- 3:2 .4:2. 6:3)
[2<-0:0][2<-1:1][4<-3:2][4<-6:3]
Bruderbaum? true
4 einf³gen
Nachbar von 4 ist [4<-6:3]
Bruder vom Vater hat zwei Kinder
daddy.left [4<-6:3]daddy.right [4<-7:4]uncle.left [2<-0:0]uncle.right [2<-1:1]
phant [8<-3:2]orphant.parent (*3:2 .8:2.*)
Vater Wurzel
***Print Tree***
(*5:1 .10:2. 9:4*)
(10<- 2:0 .5:1. 8:2)(10<- 4:3 .9:4.)
(5<- 0:0 .2:0. 1:1)(5<- 3:2 .8:2.)(9<- 6:3 .4:3. 7:4)
[2<-0:0][2<-1:1][8<-3:2][4<-6:3][4<-7:4]
Bruderbaum? true
5 einf³gen
Nachbar von 5 ist [4<-7:4]
***Print Tree***
(*5:1 .10:2. 9:3*)
(10<- 2:0 .5:1. 8:2)(10<- 12:3 .9:3. 4:4)
(5<- 0:0 .2:0. 1:1)(5<- 3:2 .8:2.)(9<- 6:3 .12:3.)(9<- 7:4 .4:4. 11:5)
[2<-0:0][2<-1:1][8<-3:2][12<-6:3][4<-7:4][4<-11:5]
Bruderbaum? true
0 l÷schen... delete:: [2<-0:0]
Onkel hat nur ein Kind, verschmelzen
delete:: (5<- 3:2 .8:2.)
Onkel hat 2 Kinder
true
***Print Tree***
(*5:2 .10:2. 9:3*)
(10<- 2:1 .5:2.)(10<- 12:3 .9:3. 4:4)
(5<- 1:1 .2:1. 3:2)(9<- 6:3 .12:3.)(9<- 7:4 .4:4. 11:5)
[2<-1:1][2<-3:2][12<-6:3][4<-7:4][4<-11:5]
***Print Leaves***
[1][2][3][4][5]
Bruderbaum? true
1 l÷schen... delete:: [2<-1:1]
kein Onkel
opa hat rechten bruder
verschmelzen
delete:: (9<- 6:3 .12:3.)
Onkel hat nur ein Kind, verschmelzen
delete:: (10<- 4:4 .9:5.)
wurzel, ein kind wird gel÷scht, baum verliert h÷he wurzel: (*2:2 .5:3. 4:4*)
true
***Print Tree***
(*2:2 .5:3. 4:4*)
(5<- 3:2 .2:2. 6:3)(5<- 7:4 .4:4. 11:5)
[2<-3:2][2<-6:3][4<-7:4][4<-11:5]
***Print Leaves***
[2][3][4][5]
Bruderbaum? true
2 l÷schen... delete:: [2<-3:2]
Onkel hat 2 Kinder
true
***Print Tree***
(*2:3 .5:3. 4:4*)
(5<- 6:3 .2:3.)(5<- 7:4 .4:4. 11:5)
[2<-6:3][4<-7:4][4<-11:5]
***Print Leaves***
[3][4][5]
Bruderbaum? true
3 l÷schen... delete:: [2<-6:3]
vater hatte nur ein kind, delete (5<- 6:3 .2:3.)
delete:: (5<- 6:3 .2:3.)
wurzel, ein kind wird gel÷scht, baum verliert h÷he wurzel: (*7:4 .4:4. 11:5*)
true
***Print Tree***
(*7:4 .4:4. 11:5*)
[4<-7:4][4<-11:5]
***Print Leaves***
[4][5]
Bruderbaum? true
4 l÷schen... delete:: [4<-7:4]
wurzel, ein kind wird gel÷scht, baum verliert h÷he wurzel: (*.11:5.*)
true
***Print Tree***
(*.11:5.*)
***Print Leaves***
[5]
Bruderbaum? true
5 l÷schen... delete:: (*.11:5.*)
true
***Print Tree***
Null
***Print Leaves***
null
Bruderbaum? true
*/

