ads1_2021/code/golang/internal/algorithms/search/ith_element/ith_element.go

95 lines
2.7 KiB
Go

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)
}
}