-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBinTree.java
218 lines (212 loc) · 6.18 KB
/
BinTree.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/**
* Import von Paketen, in denen benoetigte Library-Hilfsfunktionen zu finden sind
*/
import java.util.Random ;
import java.nio.file.*;
import java.io.*;
/**
* Implementiert einen sortierten Binaerbaum mit Rotation-zur-Wurzel Optimierung.
*/
public class BinTree {
/**
* Wurzel des Baums
*/
private BinTreeNode root;
/**
* Erstellt einen leeren Baum
*/
public BinTree() {
this.root = null ;
}
/**
* Erstellt einen Baum mit den vorgegebenen Zahlen
* @param xs die einzupflegenden Zahlen
*/
public BinTree(int... xs) {
for ( int x : xs ) {
this.insert(x);
}
}
/**
* Test ob der Baum leer ist
* @return true, falls der Baum leer ist, sonst false
*/
public boolean isEmpty() {
return this.root == null ;
}
/**
* Fuegt alle Zahlen aus den Baeumen in einen neuen Baum ein und gibt diesen zurueck.
* @param trees Die Baeume mit den einzufuegenden Zahlen.
* @return Der neue Baum mit allen Zahlen.
*/
public static BinTree merge(BinTree... trees) {
//ist die ursprüngliche Methode
int n= trees.length;
return helphelphelp_merge(n,trees);
}
public static BinTree helphelphelp_merge(int n,BinTree... trees) {
//führt die Method wirklich durch, durch die Variable n, kann ich den letzten Teil des Arrays quasi löschen
trees[0]=BinTree.help_merge(trees[0], trees[n-1]);
if(n>2)
{
BinTree.helphelphelp_merge(n-1,trees);
}
return trees[0];
}
private static BinTree help_merge(BinTree b1,BinTree b2)
{
// fügt die wurzel ein und ruft die Methode helphelp_merge auf
if(!(b2.root==null))
{
b1.insert(b2.root.getValue());
}
if(b2.root.hasLeft())
{
b1 =BinTree.helphelp_merge(b1, b2.root.getLeft());
}
if(b2.root.hasRight())
{
b1= BinTree.helphelp_merge(b1, b2.root.getRight());
}
return b1;
}
private static BinTree helphelp_merge(BinTree b1,BinTreeNode b2)
{
//fügt die einzelnen Nodes eines Baumes aus dem Array in den Baum b1 ein
b1.insert(b2.getValue());
if(b2.hasLeft())
{
b1 = BinTree.helphelp_merge(b1, b2.getLeft());
}
if(b2.hasRight())
{
b1 = BinTree.helphelp_merge(b1, b2.getRight());
}
return b1;
}
/**
* Fuegt eine Zahl ein. Keine Aenderung, wenn das Element
* schon enthalten ist.
* @param x einzufuegende Zahl
*/
public void insert(int x) {
if(isEmpty()) {
root = new BinTreeNode(x);
} else {
root.insert(x);
}
}
/**
* Sucht x, ohne den Baum zu veraendern.
* @param x der gesuchte Wert
* @return true, falls x im Baum enthalten ist, sonst false
*/
public boolean simpleSearch(int x) {
return root.simpleSearch(x);
}
/**
* Sucht x und rotiert den Knoten, bei dem die Suche nach x endet, in die Wurzel.
* @param x der gesuchte Wert
* @return true, falls x im Baum enthalten ist, sonst false
*/
public boolean search(int x) {
System.out.println("Search x=" + x);
return this.root.rotationSearch(x).getValue() == x;
}
/**
* @return Sortierte Ausgabe aller Elemente.
*/
public String toString() {
String output = "tree(";
output += root.toString();
output += ")";
return output;
}
/**
* Wandelt den Baum in einen Graphen im dot Format um.
* @return der umgewandelte Baum
*/
public String toDot() {
if ( this.isEmpty ()) {
return "digraph { null[shape=point]; }";
}
StringBuilder str = new StringBuilder ();
this.root.toDot (str, 0);
return "digraph { " + System.lineSeparator ()
+ "graph[ordering=\"out\"]; " + System.lineSeparator ()
+ str.toString ()
+ "}" + System.lineSeparator ();
}
/**
* Speichert die dot Repraesentation in einer Datei.
*
* @param path Pfad unter dem gespeichert werden soll (Dateiname)
* @return true, falls erfolgreich gespeichert wurde, sonst false
* @see toDot
*/
public boolean writeToFile(String path) {
boolean retval = true;
try {
Files.write(FileSystems.getDefault().getPath(path), this.toDot().getBytes());
} catch (IOException x) {
System.err.println("Es ist ein Fehler aufgetreten.");
System.err.format("IOException: %s%n" , x);
retval = false;
}
return retval;
}
/**
* Main-Methode, die einige Teile der Aufgabe testet.
*
* @param args Liste von Dateinamen, unter denen Baeume als dot
* gespeichert werden sollen. Es werden nur die ersten beiden verwendet.
*/
public static void main(String[] args) {
Random prng = new Random();
int nodeCount = prng.nextInt(10) + 5;
BinTree myTree = new BinTree();
System.out.println("Aufgabe b): Zufaelliges Einfuegen");
for(int i = 0; i < nodeCount; ++i) {
myTree.insert(prng.nextInt(30));
}
myTree.insert(15);
myTree.insert(3);
myTree.insert(23);
if (args.length > 0) {
if (myTree.writeToFile(args[0])) {
System.out.println("Baum als DOT File ausgegeben in Datei " + args [0]);
}
} else {
System.out.println("Keine Ausgabe des Baums in Datei, zu wenige Aufrufparameter.");
}
System.out.println("Aufgabe a): Suchen nach zufaelligen Elementen");
for(int i = 0; i < nodeCount; ++i) {
int x = prng.nextInt (30);
if(myTree.simpleSearch(x)) {
System.out.println(x + " ist enthalten");
} else {
System.out.println(x + " ist nicht enthalten");
}
}
System.out.println("Aufgabe c): geordnete String-Ausgabe");
System.out.println(myTree.toString());
myTree.writeToFile(args[1]);
System.out.println("Aufgabe d): Suchen nach vorhandenen Elementen mit Rotation.");
myTree.search(3);
myTree.search(23);
myTree.search(15);
if (args.length > 1) {
if (myTree.writeToFile(args[1])) {
System.out.println("Baum nach Suchen von 15, 3 und 23 als DOT File ausgegeben in Datei "
+ args [1]);
}
} else {
System.out.println("Keine Ausgabe des Baums in Datei, zu wenige Aufrufparameter.");
}
System.out.println("Aufgabe e): merge");
BinTree tree2 = new BinTree(4, 7, 2,9 ,5);
System.out.println(myTree.toString());
System.out.println(tree2.toString());
System.out.println(BinTree.merge(myTree, tree2).toString());
}
}