package ith_element /* ---------------------------------------------------------------- * * IMPORTS * ---------------------------------------------------------------- */ import ( "ads/internal/core/logging" "ads/internal/core/metrics" "ads/internal/core/utils" ) /* ---------------------------------------------------------------- * * GLOBAL VARIABLES/CONSTANTS * ---------------------------------------------------------------- */ // /* ---------------------------------------------------------------- * * ALGORITHM find ith smallest * ---------------------------------------------------------------- */ /* Inputs: L = Liste von Zahlen, i = Ordinalzahl Annahmen: - L enthält keine Duplikate. - L enthält mindestens i Elemente. Outputs: Wert des i. kleinste Element in L. Beachte 1.kleinstes <==> Minimum. */ func FindIthSmallest(L []int, i int) int { n := len(L) // extrahiere Wert + Index des Minimums - bedarf n Schritte metrics.AddTimeCost(n) index := utils.ArgMinInt(L) minValue := L[index] // Falls i = 1, dann wird das Minimum gesucht, sonst Minimum entfernen und nach i-1. Element suchen if i == 1 { logging.Debug("Das i. kleinste Element wurde gefunden.") return minValue } else { logging.Debug("Entferne Minimum: %[1]v.", minValue) i = i - 1 L_ := utils.PopIndexListInt(L, index) // entferne Element mit Index = index return FindIthSmallest(L_, i) } } /* ---------------------------------------------------------------- * * ALGORITHM find ith smallest (D & C) * ---------------------------------------------------------------- */ /* Inputs: L = Liste von Zahlen, i = Ordinalzahl Annahmen: - L enthält keine Duplikate. - L enthält mindestens i Elemente. Outputs: Wert des i. kleinste Element in L. Beachte 1.kleinstes <==> Minimum. */ func FindIthSmallestDC(L []int, i int) int { metrics.AddTimeCost() p := L[len(L)-1] // NOTE: Pivotelement kann beliebig gewählt werden // Werte in L in linke und rechte Teillisten um das Pivotelement aufteilen: Ll := []int{} // wird alle Elemente in L < p enthalten Lr := []int{} // wird alle Elemente in L > p enthalten for i := 0; i < len(L); i++ { x := L[i] if x < p { Ll = append(Ll, x) } else if x > p { Lr = append(Lr, x) } } // Fallunterscheidung: if len(Ll) == i-1 { logging.Debug("Es gibt i-1 Elemente vor p=%[1]v. ==> i. kleinste Element = p", p) return p } else if len(Ll) >= i { logging.Debug("Es gibt >= i Elemente vor p=%[1]v. ==> Suche in linker Hälfte!", p) return FindIthSmallestDC(Ll, i) } else { logging.Debug("Es gibt < i-1 Elemente vor p=%[1]v. ==> Suche in rechter Hälfte!", p) i = i - (len(Ll) + 1) return FindIthSmallestDC(Lr, i) } }