ads1_2021/code/python/src/algorithms/search/binary.py

67 lines
2.1 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.local.maths import *;
from src.local.typing import *;
from src.core.log import *;
from src.algorithms.methods import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES/CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CHECKS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def preChecks(L: List[int], **_):
assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!';
return;
def postChecks(L: List[int], x: int, index: int, **_):
if x in L:
assert index >= 0, 'Der Algorithmus sollte nicht -1 zurückgeben.';
assert L[index] == x, 'Der Algorithmus hat den falschen Index bestimmt.';
else:
assert index == -1, 'Der Algorithmus sollte -1 zurückgeben.';
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ALGORITHM binary search
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Binärsuchalgorithmus', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def BinarySearch(L: List[int], x: int) -> int:
'''
Inputs: L = Liste von Zahlen, x = Zahl.
2021-10-24 13:18:39 +02:00
Annahme: L sei aufsteigend sortiert.
2021-10-24 13:18:39 +02:00
Outputs: Position von x in L, sonst 1 wenn x nicht in L.
'''
if len(L) == 0:
logDebug('x nicht in L');
return -1;
AddTimeCost();
m = math.floor(len(L)/2);
if L[m] == x:
logDebug('x in Position m gefunden');
return m;
elif x < L[m]:
logDebug('Suche in linker Hälfte fortsetzen.');
index = BinarySearch(L=L[:m], x=x);
return index;
else: # x > L[m]
logDebug('Suche in rechter Hälfte fortsetzen.');
index = BinarySearch(L=L[m+1:], x=x);
if index >= 0:
index += (m + 1); # NOTE: muss Indexwert kompensieren
return index;