Hallo!
ist jetzt keine Hausaufgabe, sondern Klausurvorbereitung und zwar zum Thema Datenstrukturen und Algorithmen.
Ich habe versucht eine Wegkompression mit einzubauen, indem ich bei find die Knoten direkt unter die Wurzel hänge und durch das Mitzählen der Kinder habe ich versucht Union-By-Size zu implementieren. Das ganze ist für Kruskal gedacht, darum weiß ich vorher wieviele Knoten es werden und kann diese einfach von 0 bis n-1 in das Array packen.
Ergibt aus meiner Sicht bisher zumindest sehr viel Sinn das ganze
Jetzt geht es um den Aufwand für union und find. ich würde sagen, dass der Aufwand für union = Aufwand für find ist, da ich am Anfang von Union die find-methode zwei mal Aufrufen muss um an die Wurzeln zu kommen. Der Rest läuft dann mit konstantem Aufwand.
Den Aufwand für find würde ich jetzt als O(1) beschreiben, weil bei Union und find durch die Wegkompression immer direkt unter die Wurzel gehängt werden und dadurch der Zugriff in konstanter Laufzeit möglich ist.
Nun ist meine Frage, ob dies so richtig ist? Vielen Dank!
ist jetzt keine Hausaufgabe, sondern Klausurvorbereitung und zwar zum Thema Datenstrukturen und Algorithmen.
Java:
public class UFS {
protected UFSNode[] nodes;
public UFS(int k){
nodes = new UFSNode[k];
for(int i = 0; i<k; i++){
nodes[i] = new UFSNode(i);
}
}
public int find(int index){
return nodes[index].getRoot().nummer;
}
public void union(int indexa, int indexb){
int a = find(indexa);
int b = find(indexb);
if(a != b){
if(nodes[a].getKinder() >= nodes[b].getKinder()){
nodes[b].setSucc(nodes[a]);
nodes[a].setKinder(nodes[a].getKinder() + nodes[b].getKinder() + 1);
}else{
nodes[a].setSucc(nodes[b]);
nodes[b].setKinder(nodes[a].getKinder() + nodes[b].getKinder() + 1);
}
}
}
public String toString(){
String result = "";
for(int i = 0; i < nodes.length; i++){
result += i + ": Wurzel " + find(i) + ", direkter Vorgänger: " + nodes[i].succ.nummer + ", Kinder " + nodes[i].getKinder() + "\n";
}
return result;
}
}
Java:
public class UFSNode {
protected UFSNode succ;
protected int nummer;
protected int kinder;
public UFSNode(int i){
nummer = i;
kinder = 0;
succ = this;
}
public void setSucc(UFSNode n){
this.succ = n;
}
public void setKinder(int i){
kinder = i;
}
public int getKinder(){
return kinder;
}
public UFSNode getRoot(){
if(this.succ == this){
return this;
}else if(this.succ == this.succ.succ){
return this.succ;
}else{
UFSNode n = this.succ.getRoot();
this.succ.setKinder(this.succ.getKinder() - 1);
this.succ = n;
n.setKinder(n.getKinder() + 1);
return n;
}
}
}
Ich habe versucht eine Wegkompression mit einzubauen, indem ich bei find die Knoten direkt unter die Wurzel hänge und durch das Mitzählen der Kinder habe ich versucht Union-By-Size zu implementieren. Das ganze ist für Kruskal gedacht, darum weiß ich vorher wieviele Knoten es werden und kann diese einfach von 0 bis n-1 in das Array packen.
Ergibt aus meiner Sicht bisher zumindest sehr viel Sinn das ganze
Jetzt geht es um den Aufwand für union und find. ich würde sagen, dass der Aufwand für union = Aufwand für find ist, da ich am Anfang von Union die find-methode zwei mal Aufrufen muss um an die Wurzeln zu kommen. Der Rest läuft dann mit konstantem Aufwand.
Den Aufwand für find würde ich jetzt als O(1) beschreiben, weil bei Union und find durch die Wegkompression immer direkt unter die Wurzel gehängt werden und dadurch der Zugriff in konstanter Laufzeit möglich ist.
Nun ist meine Frage, ob dies so richtig ist? Vielen Dank!