AlgorithmenGrundlagenLogikSummenregeln đLogarithmus RegelnGeometrische ReiheRechenoperationen + ZifferstellenSchleifeninvarianteLaufzeitanalyse von Algorithmen âłLaufzeit von CodeElementare ZuweisungenMaster-Theorem (Divide-And-Conquer) đLandau Notation đ Ÿïž$f \in o(g)$$f \in O(g)$$f \in \Omega(g)$$f \in \Theta(g)$$f \in \omega(g)$Landau Notation FolgerungenBekannte OrdnungenO(log n)O(n)O(n log n)O(n2)O(nk)SortierenBubble SortđInsertion SortđSelection SortMerge SortQuick Sort â©Quick SelectBFPRTHeap SortSchranken des SortierproblemsCounting Sort đ§źRadix SortSuchen đLineare SucheBinĂ€re SucheDatenstrukturenVergleichFIFO vs LIFODynamisches ArrayPower dictionaryPrioritĂ€tswartschlangeHeapsBinĂ€rer HeapBinomial HeapHollow HeapFibonacci HeapBĂ€umeBinĂ€re SuchbĂ€ume đČAVL-BĂ€ume (Fibonacci BĂ€ume) đŽHash Tabelle đżGrundlagen des HashingPerfekte Hashfunktion đKollisisionswahrscheinlichkeitOffenes Hashing mit geschlossener Adressierung âGeschlossenes Hashing mit offener AdressierungPolynomielles SondierenDoppelhashingSuchen nach LöschenUniverselles HashingGraphen đAllgemeinesDarstellungAdjazenzmatrixAdjazenzlisteGraph-DurchlaufBreitendurchlaufTiefendurchlaufTopologisches SortierenGraph Isomorphismus ProbelmKosarajuâs AlgorithmusBellman-Ford AlgorithmusDijkstra AlgorithmusJohnsonâs APSP AlgorithmFloyd-Warshall AlgorithmusMinimale SpannbĂ€umeGrundlagenKruskal AlgorithmusPrim AlgorithmusĂbungenLaufzeiten bestimmenBeweise: $g \notin O(f)$Beweise: ${n\choose k} \in \Theta(n^k)$Beweise: $log(n) \in O(n^k)$Anzahl der FunktionsaufrufeWie kann man den Katasube-Ofman Algorithmus verallgemeinern?Wurf mit BĂ€llen auf EimerDijkstra mit negativen KantenPseudocodeSorting AlgorithmsInsertion SortSelection SortMerge SortQuick SortHeap SortCounting SortRadix SortDatenstrukturenVerkettete ListeDoppelt verkettete ListeStackQueueBinĂ€rer HeapGraphenTopologisches SortierenDFSBFSBellman-FordDijkstraKruskalPrim
VertrÀge bestehen aus
The loop invariant is a single condition or set of conditions that the algorithm maintains at the beginning, the end, and during each iteration of its execution
The loop invariant for selection sort is that the elements of the newly sorted array up to the current index, A[0..i]
will contain the i smallest elements of our original input, A[0..n-1]
. They will also be in sorted order.
The loop invariant for insertion sort states that all elements up to the current index, A[0..i]
, make up a sorted permutation of the elements originally found in A[0..i]
before we began sorting.
String str;
int i = j + 3;
if (j == 7)
Sequenzen von Anweisungen
if
) oder Fallunterscheidungen (switch
)
One basic way to get an algorithm with this running time is to process the input in a single pass, spending a constant amount of time on each item of input encountered
E.g. computing the maximum, merging two sorted lists into one sorted list
max = arr[0]
for i in range(1,len(arr)):
if arr[i] > max:
max = arr[i]
return max
Idee: Vergleiche Paare von benachbarten SchlĂŒsseln und tausche, wenn linker SchlĂŒssel gröĂer ist als rechter
Maximum wandert nach hinten
xxxxxxxxxx
int n = a.length;
for i in range(0, i < n):
for j in range (0, j < n-i-1):
if (a[j] > a[j+1]):
swap(a,j,j+1)
Variable i: wieviele Elemnte am Ende sind schon soritiert
Variable j: Nachbarschaftsvergleiche auf dem unsortierten "Rest"
đą Anzahl der Vergleiche :
đ Anzahl der Vertauschungen:
đ SchlĂŒssel: âZahlen die sortiert werden sollen
Vergleichbar mit dem Sortieren von Spielkarten auf der Hand
xxxxxxxxxx
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while j >=0 and key < arr[j] :
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
ist die "aktuelle" Karte die eingeordnet werden muss
Algorithmus | Kosten | Anzahl |
---|---|---|
for i = 2 to A.length | ||
key = A[i] | ||
j = i - 1 | ||
while j > 0 and A[j] > key | ||
A[j + 1] = A[j] | ||
j = j - 1 | ||
A[j + 1] = key |
= Anzahl der AusfĂŒhrungen des while loop
Der Test fĂŒr for und while loops wird einmal öfter ausgefĂŒhrt, als der Inhalt der Schleife
Anzahl der Vergleiche:
Best Case: bei sortierter Folge
Average und Worst Case:
Anzahl Verschiebeoperationen:
Idee: Suche jeweils nÀchstes kleinstes Element
xxxxxxxxxx
public void selectionSort(int[] a) {
for(int i = 0; i < a.length-1; i++) {
int min = i;
for(int k = i+1; j < n; j++) {
if(a[j] < a[min])
min = j;
}
swap(a,i,min)
}
}
Anzahl der Vertauschungen:
Idee: Optimierung von Merge Sort durch in-situ Sortieren
âxdef quickSort(arr,low,high):
if low < high:
pi = partition(arr,low,high)
quickSort(arr,low,pi-1)
quickSort(arr,pi+1,high)
â
def partition(arr,low,high):
i = (low-1)
pivot = arr[high] #could be random
for j in range(low,high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[high] = arr[high], arr[i+1]
return(i+1)
Worst Case: Entarteter Baum
Average Case: Jede LĂ€nge ist gleich wahrscheinlich, im Durchschnitt ist als die LĂ€nge der gröĂten Teilfolge
Pivot kann zufÀllig gewÀhlt werden oder deterministisch mit dem Median-of-Medians Algorithmus in
Pivot: The value within the partitioning space that I want to find a position for
j: Scanning function
i: Remembers the last position that an element was placed in, that was less than the pivotx
BinÀrbÀume allgemein:
Heap Struktur: BinĂ€rbaum, der zwei Eigenschaften erfĂŒllen muss
"Beinahe-Max-Heap" (die Max-Heap-Eigenschaft ist bei der Wurzel verletzt)
Heapaufbau
Heapify: FĂŒr jeden der Knoten (weil jeder mal Wurzel wird) wir gemacht
xxxxxxxxxx
l = 0
r = n - 1
while (l <= r) do
m = round((r + l) / 2)
if A[m] == x then return m
if A[m] < x then l = m + 1
else r = m - 1
return -1
Baum | Sortierte Liste | Sortiertes Array | |
---|---|---|---|
EinfĂŒgen | |||
Löschen | |||
Zugriff |
Array hat feste GröĂe
push()
Opertation normalerweise , wenn Array noch Platz hat, wenn nicht muss ein neues Array mit doppelter GröĂe alloziert werden. In diesem Fall mĂŒssen alle Elemente in das neue Array kopiert werden
Reallozieren des Arrays auf halbe GröĂe, wenn das Array nur noch zu befĂŒllt ist. pop()
Operation also normal , mit Reallozieren
Amortisierte Zeitanalyse fĂŒr push()
und pop()
push()
und pop()
bringen 5⏠in die KasseDatenstruktur, die es erlaubt das kleinste Element schnell zu finden und aus der Menge zu entfernen
Mögliche Implementierung durch perfektem binĂ€ren Baum, der die Heapeigenschaft erfĂŒllt
Baum erfĂŒllt (Min-)Heapeigenschaft falls fĂŒr jeden Knoten ausser der Wurzel der SchlĂŒsselwert gröĂer ist als der SchlĂŒsselwert des Vaterknotens
BinÀrbaum, fehlende BlÀtter rechts unten
Höhe
Ănderungen nur entlag eines Pfades Wurzel-Blatt
insert()
und deleteMin
brauchen
min()
dauert
buildHeap()
braucht
siftDown()
Sammlung von BinomialbÀumen, jeder Baum ist ein Heap
Es darf von jedem Grad nur einen Baum geben (merge trees of equal degree)
In einem BinÀrbaum von Grad hat die Wurzel Kinder
Der Baum hat Höhe
push()
mit Worst Case , amortisiert in . push()
muss meistens nur auf kurzen BĂ€umen stattfinden
decreaseKey()
mit Worst Case , da der SchlĂŒssel eventuell bis nach ganz oben bubbeln muss
popMin()
mit Worst Case
Laufzeit
Eine BinÀrer Suchbaum muss die Form , wenn im linken Teilbaum und im rechten Teilbaum liegt
âïž Min-Heap:
âïž Max-Heap:
Insert(key, value)
Remove(key)
Ănderungen im baum mit
Suche der entsprechenden Position:
Wie hoch kann ein ABL-Baum fĂŒr eine gegebene Knotenanzahl maximal werden?
ist die minimale Anzahl Knoten eines AVL-Baums der Höhe
FĂŒr beliebigen minimal gefĂŒllten AVL-Baum der Höhe gilt:
Ăhnelt der Fibonacci Reihe. Deswegen
Links-links Rotation bei EinfĂŒgung in Teilbaum "rechts rechts"
Links-rechts Rotation bei EinfĂŒgung in Teilbaum "links-rechts"
Rechts-links Rotation bei EinfĂŒgung in Teilbaum "rechts-links"
Rotationen brauchen konstante Zeit , EinfĂŒgen mit Rebalancierung also
Beim Löschen kann es passieren, dass man den ganzen Pfad entlag Rebalancierungen vornehmen muss, maximal also Rotationen. Löschen mit Rebalancierung also im Worst Case
Beinahe AVL-Baum: Nur an der Wurzel um debalanciert
Nutzung zweier unabhÀngiger Hashfunktionen
Sondierung mit
H
eine endliche Menge an Hashfunktionen von nach . H
ist universell falls fĂŒr mit die Anzahl der Hashfunktionen H
mit höchstens ist.Verwenden einer Queue (First In, First Out), um die Suche zu organisieren
Ein Knoten wird ausgewĂ€hlt, dann besucht und als âvisitedâ markiert. Dann kommen die Nachbarknoten in die Queue und werden wiederum ausgewĂ€hlt, besucht und als âvisitedâ markiert
Ablauf:
Verwenden eines Stack (First In, Last Out), um die Suche zu organisieren
Zeitstempel der ersten PrĂŒfung des Knotens
Zeitstempel, an der der Algorithmus mit Knoten fertig ist
VorgÀnger von in der Suche
Laufzeit:
Die Kanten heiĂen Baumkanten und bilden einen Wald (Tiefenwald)
Nach DFS ist jedem Knoten ein Intervall zugeordnet
Wenn , dann ist eine "ab"-Kante
Wenn , dann ist eine "auf"-Kante
In einem DAG gibt es keine "auf"-Kanten
Wenn , dann ist eine "rĂŒckwĂ€rts"-Kante
Der Fall einer "vorwÀrts"-Kante kann nicht auftreten (wegen Tiefensuche)
Ablauf:
Nur möglich, wenn der Graph keine Zyklen enthÀlt (nur bei DAGs)
Laufzeit:
Jeder Baum kann topologisch Sortiert werden (erst alle Knoten von k, dann k-1, ... bis zur Wurzel rĂŒckwerts in die Liste einfĂŒgen)
Oftmals gibt es mehrere Möglichkeiten eine topologische Sortierung zu erstellen
Anschaulich: Alle Kanten "zeigen nach rechts"
Idee zum Algorithmus (alternativer Algorithmus ĂŒber DFS)
Linker Graph | Rechter Graph | |
---|---|---|
Anzahl Knoten | 6 | 6 |
Anzahl Kanten | 8 | 8 |
Anzahl Knoten mit 2 Kanten | 2 | 2 |
Anzahl Knoten mit 3 Kanten | 4 | 4 |
Zyklen der LĂ€nge 3 | 0 | 6 |
Starke Zusammenhangskomponenten (SCC): Zwei Knoten gehören genau dann zu einer solchen Komponente, wenn man zwischen ihnen hin und her gehen kann
Doppelter DFS zur Identifikation der SCC
Laufzeit:
Single Source Shortest Path
Kann mit negativen Kantengewichten umgehen
Ablauf
Laufzeit:
Bellman-Ford's Algorithmus und Dijkstra's Algorithmus sind in ihrer Struktur sehr Àhnlich. WÀhrend Dijkstra nur die unmittelbaren Nachbarn eines Vertexes betrachtet, geht Bellman in jeder Iteration jede Kante durch.
Bei Dijkstra wird jede Kante nur einmal relaxiert
Ablauf
Weg zum Startknoten hat Kosten , alle andere haben Kosten â
Ist der Knoten in der Warteschlange enthalten und sind die Kosten ĂŒber die neue Kante geringer als die bisherigen Kosten?
Laufzeit:
DeleteMin
nur Zeit, also insgesamt Benutzt Bellman Ford um negative Kantengewichte in positive Umzuwandeln und Dijkstra um die kĂŒrzesten Wege zu finden
Ablauf:
h[]
gespeichertZeitkomplexitÀt:
Versucht sukzessive, zwei Knoten ĂŒber einen Zwischenknoten gĂŒnstiger zu verbinden als bisher
Ablauf:
Laufzeit:
Der Algorithmus wird mit einem Wald, welcher aus BĂ€umen mit einzelnen Knoten besteht, initialisiert
Die Kanten werden ihrem Gewicht nach in einer Warteschlange sortiert
In jeder Iteration wird eine Kante aus der Warteschlange entfernt
Dies wird so lange wiederholt, bis alle Knoten zum selben Baum gehören oder keine Kanten mehr in der Warteschlange sind
Laufzeit:
Der Algorithmus beginnt den Baum mit einem beliebigen einzelnen Knoten, und fĂŒgt dann in jeder Iteration eine Kante hinzu
Diese hinzugefĂŒgte Kante hat unter allen Kanten, welche den Baum mit Knoten auĂerhalb des Baums verbinden, minimales Gewicht
Dieser Vorgang wird so lange wiederholt, bis alle Knoten im Baum sind.
Die effizienteste Implementierung des Algorithmus erfolgt ĂŒber eine Warteschlange. Diese Warteschlange speichert alle Knoten, welche schon besucht wurden, aber noch nicht in den Baum eingefĂŒgt sind
Die Reihenfolge der Knoten in der Warteschlange wird ĂŒber die Distanz jedes Knoten zum Baum bestimmt. In jeder Iteration wird also der Knoten, welcher ĂŒber die billigste Kante mit dem Baum verbunden ist, aus der Warteschlange entfernt.
Laufzeit:
Beweise:
Induktion ĂŒber mit
Beweis:
Beweis:
Da
xxxxxxxxxx
i = n;
while (i > 1) do
for j in range(1,i)
f(j);
i = i/3
ist die Anzahl der Aufrufe der Funktion
fĂŒr alle , da bereits im ersten Durchlauf die inneren for-Schleife -mal durchlaufen wird
Master Theorem:
Da , wird der erste Fall angewendt und damit ist
wir -mal aufgerufen, jeder Aufruf hat Laufzeit. Insgesamt also
xxxxxxxxxx
function insertionSort(inputArr) {
let n = inputArr.length;
for (let i = 1; i < n; i++) {
// Choosing the first element in our unsorted subarray
let current = inputArr[i];
// The last element of our sorted subarray
let j = i-1;
while ((j > -1) && (current < inputArr[j])) {
inputArr[j+1] = inputArr[j];
j--;
}
inputArr[j+1] = current;
}
return inputArr;
}
xxxxxxxxxx
mark first element as sorted
for each unsorted element X
'extract' the element X
for j = lastSortedIndex down to 0
if current element j > X
move sorted element to the right by 1
break loop and insert X here
xxxxxxxxxx
function selectionSort(inputArr) {
let n = inputArr.length;
for(let i = 0; i < n; i++) {
// Finding the smallest number in the subarray
let min = i;
for(let j = i+1; j < n; j++){
if(inputArr[j] < inputArr[min]) {
min=j;
}
}
if (min != i) {
// Swapping the elements
let tmp = inputArr[i];
inputArr[i] = inputArr[min];
inputArr[min] = tmp;
}
}
return inputArr;
}
xxxxxxxxxx
repeat (numOfElements - 1) times
set the first unsorted element as the minimum
for each of the unsorted elements
if element < currentMinimum
set element as new minimum
swap minimum with first unsorted position
xxxxxxxxxx
function mergeSort(array) {
const half = array.length / 2
// Base case or terminating case
if(array.length < 2){
return array
}
const left = array.splice(0, half)
return merge(mergeSort(left),mergeSort(array))
}
â
function merge(left, right) {
let arr = []
// Break out of loop if any one of the array gets empty
while (left.length && right.length) {
// Pick the smaller among the smallest element of left and right sub arrays
if (left[0] < right[0]) {
arr.push(left.shift())
} else {
arr.push(right.shift())
}
}
// Concatenating the leftover elements
// (in case we didn't go through the entire left or right array)
return [ arr, left, right ]
}
xxxxxxxxxx
split each element into partitions of size 1
recursively merge adjacent partitions
for i = leftPartIdx to rightPartIdx
if leftPartHeadValue <= rightPartHeadValue
copy leftPartHeadValue
else: copy rightPartHeadValue
copy elements back to original array
xxxxxxxxxx
function quickSortRecursive(arr, start, end) {
// Base case or terminating case
if (start >= end) {
return;
}
// Returns pivotIndex
let index = partition(arr, start, end);
// Recursively apply the same logic to the left and right subarrays
quickSort(arr, start, index - 1);
quickSort(arr, index + 1, end);
}
â
function partition(arr, start, end){
// Taking the last element as the pivot
const pivotValue = arr[end];
let pivotIndex = start;
for (let i = start; i < end; i++) {
if (arr[i] < pivotValue) {
// Swapping elements
[arr[i], arr[pivotIndex]] = [arr[pivotIndex], arr[i]];
// Moving to next element
pivotIndex++;
}
}
// Putting the pivot value in the middle
[arr[pivotIndex], arr[end]] = [arr[end], arr[pivotIndex]]
return pivotIndex;
};
xxxxxxxxxx
for each (unsorted) partition
randomly select pivot, swap with first element
storeIndex = pivotIndex + 1
for i = pivotIndex + 1 to rightmostIndex
if element[i] < element[pivot]
swap(i, storeIndex); storeIndex++
swap(pivot, storeIndex - 1)
xxxxxxxxxx
â
function heapSort(a){
let n = a.length;
for(let i=Math.floor(n/2)-1;i>=0;i--){
max_heapify(a,i,n); //Building max heap
}
for(let i = n-1;i>=0;i--){
swap(a,0,i); //Deleting root element
max_heapify(a,0,i); //Building max heap again
}
return a;
}
â
function max_heapify(a,i,n){
let left = 2*i; //Left child index
let right = 2*i+1; //Right child index
let maximum;
if(right<n){ //Checks if right child exist
if(a[left]>=a[right]){ //Compares children to find maximum
maximum = left;
}
else{
maximum = right;
}
}
else if(left<n){ //Checks if left child exists
maximum = left;
}
else return; //In case of no children return
if(a[i]<a[maximum]){ //Checks if the largest child is greater than parent
swap(a,i,maximum); //If it is then swap both
max_heapify(a,maximum,n); //max-heapify again
}
return;
}
â
xxxxxxxxxx
let countingSort = (arr, min, max) => {
let i = min,
j = 0,
len = arr.length,
count = [];
for (i; i <= max; i++) {
count[i] = 0;
}
for (i = 0; i < len; i++) {
count[arr[i]] += 1;
}
for (i = min; i <= max; i++) {
while (count[i] > 0) {
arr[j] = i;
j++;
count[i]--;
}
}
return arr;
};
xxxxxxxxxx
create key (counting) array
for each element in list
increase the respective counter by 1
for each counter, starting from smallest key
while counter is non-zero
restore element to list
decrease counter by 1
xxxxxxxxxx
function radixSort(arr) {
â
const max = getMax(arr); // length of the max digit in the array
â
for (let i = 0; i < max; i++) {
let buckets = Array.from({ length: 10 }, () => [ ])
for (let j = 0; j < arr.length; j++) {
buckets[getPosition(arr[ j ], i)].push(arr[ j ]); // pushing into buckets
}
arr = [ ].concat(buckets);
}
return arr
}
â
function getMax(arr) {
â
let max = 0;
for (let num of arr) {
if (max < num.toString().length) {
max = num.toString().length
}
}
return max
}
â
function getPosition(num, place){
return Math.floor(Math.abs(num)/Math.pow(10,place))% 10
}
xxxxxxxxxx
function search(v) {
â
if empty, return NOT_FOUND
â
index = 0, temp = head
while (temp.item != v)
index++, temp = temp.next
if temp == null
return NOT_FOUND
return index
â
}
â
function insert_head(v) {
Vertex vtx = new Vertex(v)
vtx.next = head
head = vtx
}
â
function delete_tail() {
â
if empty, return
â
Vertex pre = head
temp = head.next
while (temp.next != null)
pre = pre.next
pre.next = null
delete temp, tail = pre
â
}
xxxxxxxxxx
function delete_item(i) {
if empty, return
Vertex pre = head
for (k = 0; k < i-1; k++)
pre = pre.next
Vertex del = pre.next, aft = del.next
pre.next = aft, aft.prev = pre
delete del
}
â
function delete_tail() {
if empty, return
temp = tail
tail = tail.prev
tail.next = null
delete temp
}
xxxxxxxxxx
function push(v) {
Vertex vtx = new Vertex(v)
vtx.next = head
head = vtx
}
â
function pop() {
if empty, return
temp = head
head = head.next
delete temp
}
xxxxxxxxxx
function enqueue(v) {
Vertex vtx = new Vertex(v)
tail.next = vtx
tail = vtx
}
â
function dequeue() {
if empty, return
temp = head
head = head.next
delete temp
}
xxxxxxxxxx
function build_heap(arr) {
for (i = arr.length/2; i >= 1; i--)
shiftDown(i)
}
â
function insert_into_heap(v) {
A[A.length] = v
i = A.length-1
while (i > 1 && A[parent(i)] < A[i])
swap(A[i], A[parent(i)])
}
â
function extract_max() {
take out A[1]
A[1] = A[A.length-1]
i = 1; A.length--
while (i < A.length)
if A[i] < (L = the larger of i's children)
swap(A[i], L)
}
xxxxxxxxxx
function TopoSort(DAG) {
S = empty // Menge der abgearbeiteten Knoten
for (i=0, i<n, i++) {
P[i] = Anzahl VorgÀnger des Knoten i
}
while V \ S not empty {
wÀhle w aus V \ S mit P[w]==0;
gib w aus;
S = S ohne {w};
fĂŒr jeden Nachfolger v von w {
--P[v];
}
}
}
xxxxxxxxxx
DFS-iterative (G, s):
let S be stack
S.push( s ) //Inserting s in stack mark s as visited.
while ( S is not empty):
//Pop a vertex from stack to visit next
v = S.top( )
S.pop( )
//Push all the neighbours of v in stack that are not visited
for all neighbours w of v in Graph G:
if w is not visited :
S.push( w )
mark w as visited
xxxxxxxxxx
BFS (G, s)
let Q be queue.
Q.enqueue( s ) //Inserting s in queue until all its neighbours are marked.
â
mark s as visited.
while ( Q is not empty)
//Removing that vertex from queue,whose neighbour will be visited now
v = Q.dequeue( )
â
//processing all the neighbours of v
for all neighbours w of v in Graph G
if w is not visited
Q.enqueue( w )
//Stores w in Q to further visit its neighbour
mark w as visited.
xxxxxxxxxx
for v in V:
v.distance = infinity
v.p = None
source.distance = 0
for i from 1 to |V| - 1:
for (u, v) in E:
relax(u, v)
for (u, v) in E:
if v.distance > u.distance + weight(u, v):
print "A negative weight cycle exists"
â
relax(u, v):
if v.distance > u.distance + weight(u, v):
v.distance = u.distance + weight(u, v)
v.p = u
xxxxxxxxxx
function Dijkstra(G,s)
for earch v in G:
v.distance = infinity
v.p = None
source.distance = 0
Q = set of all nodes in G
while Q is not empty
u = node in Q with smallest distance
remove u from Q
for each neighbor v of u:
alt = u.distance + weight(u,v)
if alt < v.distance
v.distance = alt
v.p = u
return previous[]
xxxxxxxxxx
function kruskal(G,s)
T = empty
Q = sortiere E nach w(u,v)
for V in G
make-tree(V)
while Q is not empty AND trees-count > 1
{u,v} = Q.extractMin()
if T with {u,v} does not contain loop
T.add({u,v})
merge(tree-of(u),tree-of(v))
xxxxxxxxxx
function prim(G,s)
T = empty
for i in range (1,n)
d(V[1]) = infinity
parent(v[i]) = null
â
d(s) = 0
â
queue = V
â
while Q is not empty
u = Q.extractMin()
for all neighbors of u in G
if neighbor in queue AND w({u,neighbor}) < d[neighbor]
Q.decreaseKey()
parent[neighbor] = u