Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| statnice:bakalar:b4b33alg [2025/06/08 13:29] – [Bubble Sort] zapleka3 | statnice:bakalar:b4b33alg [2026/06/06 17:15] (current) – [Counting Sort] knedl1k | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ==== Základní algoritmy a datové struktury pro vyhledávání a řazení. Vyhledávací stromy, rozptylovací tabulky. Prohledávání grafu. Úlohy dynamického programování. Asymptotická složitost a její určování. ==== | + | ====== Základní algoritmy a datové struktury pro vyhledávání a řazení. Vyhledávací stromy, rozptylovací tabulky. Prohledávání grafu. Úlohy dynamického programování. Asymptotická složitost a její určování. |
| [[https:// | [[https:// | ||
| Line 476: | Line 476: | ||
| === Mazání === | === Mazání === | ||
| * Najdeme a odstraníme klíč (případně jej nahradíme in-order předchůdcem/ | * Najdeme a odstraníme klíč (případně jej nahradíme in-order předchůdcem/ | ||
| - | * Při návratu nahoru testujeme balance; pokud je mimo intervál | + | * Při návratu nahoru testujeme balance; pokud je mimo interval |
| * V nejhorším provedeme až $O(\log n)$ rotací | * V nejhorším provedeme až $O(\log n)$ rotací | ||
| Line 483: | Line 483: | ||
| * prakticky používá v databázových systémech a souborových systémech. | * prakticky používá v databázových systémech a souborových systémech. | ||
| - | B-strom je řízen parametrem **minimální stupeň | + | B-strom je řízen parametrem **minimální stupeň |
| - | * Každý uzel (kromě kořene) má alespoň $t - 1$ a nejvýše $2t - 1$ klíčů. | + | * Každý uzel (kromě kořene) má alespoň $\lfloor |
| * Z toho plyne, že každý vnitřní uzel má mezi $t$ až $2t$ potomků. | * Z toho plyne, že každý vnitřní uzel má mezi $t$ až $2t$ potomků. | ||
| * Kořen může mít méně než $t - 1$ klíčů. | * Kořen může mít méně než $t - 1$ klíčů. | ||
| Line 493: | Line 493: | ||
| * Každý uzel má minimální a maximální počet klíčů (viz definice $t$ výše). | * Každý uzel má minimální a maximální počet klíčů (viz definice $t$ výše). | ||
| - | * Když uzel překročí maximální počet klíčů ($2t - 1$), rozdělí se na dva uzly a prostřední klíč se přesune do rodiče. | + | * Když uzel překročí maximální počet klíčů ($2t$), rozdělí se na dva uzly a prostřední klíč se přesune do rodiče. |
| * Pokud rodič také překročí maximální počet klíčů, proces se opakuje až ke kořeni. | * Pokud rodič také překročí maximální počet klíčů, proces se opakuje až ke kořeni. | ||
| Line 504: | Line 504: | ||
| === Vkládání === | === Vkládání === | ||
| * Klíč vkládáme do správného listu. | * Klíč vkládáme do správného listu. | ||
| - | * Pokud uzel překročí $2t - 1$ klíčů: | + | * Pokud uzel překročí $2t$ klíčů: |
| * Rozdělíme ho na dvě části. | * Rozdělíme ho na dvě části. | ||
| * Prostřední klíč přesuneme do rodiče. | * Prostřední klíč přesuneme do rodiče. | ||
| Line 512: | Line 512: | ||
| === Mazání === | === Mazání === | ||
| - | * Pokud uzel klesne pod $t - 1$ klíčů, musíme situaci opravit: | + | * Pokud uzel klesne pod $\lfloor |
| * **Borrow** – vypůjčíme si klíč od sourozence. | * **Borrow** – vypůjčíme si klíč od sourozence. | ||
| * **Merge** – sloučíme uzel se sourozencem a jeden klíč stáhneme z rodiče. | * **Merge** – sloučíme uzel se sourozencem a jeden klíč stáhneme z rodiče. | ||
| Line 541: | Line 541: | ||
| {{https:// | {{https:// | ||
| + | |||
| + | <code python> | ||
| + | # Insertion Sort | ||
| + | def insertion_sort(arr): | ||
| + | for i in range(1, len(arr)): | ||
| + | key = arr[i] | ||
| + | j = i - 1 | ||
| + | while j >= 0 and arr[j] > key: | ||
| + | arr[j + 1] = arr[j] | ||
| + | j -= 1 | ||
| + | arr[j + 1] = key | ||
| + | return arr | ||
| + | </ | ||
| ==== Selection Sort ==== | ==== Selection Sort ==== | ||
| Line 551: | Line 564: | ||
| {{https:// | {{https:// | ||
| + | |||
| + | <code python> | ||
| + | # Selection Sort | ||
| + | def selection_sort(arr): | ||
| + | for i in range(len(arr)): | ||
| + | min_idx = i | ||
| + | for j in range(i + 1, len(arr)): | ||
| + | if arr[j] < arr[min_idx]: | ||
| + | min_idx = j | ||
| + | arr[i], arr[min_idx] = arr[min_idx], | ||
| + | return arr | ||
| + | </ | ||
| ==== Bubble Sort ==== | ==== Bubble Sort ==== | ||
| Line 560: | Line 585: | ||
| {{https:// | {{https:// | ||
| + | |||
| <code python> | <code python> | ||
| + | # Bubble Sort | ||
| def bubble_sort(arr): | def bubble_sort(arr): | ||
| - | | + | |
| - | swapped = False | + | swapped = False |
| - | + | for i in range(n): | |
| - | | + | if arr[i] > arr[i + 1]: |
| - | if arr[i] > arr[i + 1]: | + | arr[i], arr[i + 1] = arr[i + 1], arr[i] |
| - | arr[i], arr[i + 1] = arr[i + 1], arr[i] | + | swapped = True |
| - | | + | if not swapped: |
| - | | + | break |
| - | | + | return arr |
| - | | + | |
| - | break | + | |
| - | return arr | + | |
| </ | </ | ||
| Line 584: | Line 608: | ||
| {{https:// | {{https:// | ||
| + | |||
| + | <code python> | ||
| + | # QuickSort | ||
| + | def quicksort(arr): | ||
| + | if len(arr) <= 1: | ||
| + | return arr | ||
| + | pivot = arr[0] | ||
| + | less = [x for x in arr[1:] if x < pivot] | ||
| + | greater_eq = [x for x in arr[1:] if x >= pivot] | ||
| + | return quicksort(less) + [pivot] + quicksort(greater_eq) | ||
| + | </ | ||
| ==== Merge Sort ==== | ==== Merge Sort ==== | ||
| Line 593: | Line 628: | ||
| {{https:// | {{https:// | ||
| + | |||
| + | <code python> | ||
| + | # Merge Sort | ||
| + | def merge_sort(arr): | ||
| + | if len(arr) <= 1: | ||
| + | return arr | ||
| + | mid = len(arr) // 2 | ||
| + | left = merge_sort(arr[: | ||
| + | right = merge_sort(arr[mid: | ||
| + | return merge(left, right) | ||
| + | |||
| + | def merge(left, right): | ||
| + | result = [] | ||
| + | i = j = 0 | ||
| + | while i < len(left) and j < len(right): | ||
| + | if left[i] <= right[j]: | ||
| + | result.append(left[i]) | ||
| + | i += 1 | ||
| + | else: | ||
| + | result.append(right[j]) | ||
| + | j += 1 | ||
| + | result.extend(left[i: | ||
| + | result.extend(right[j: | ||
| + | return result | ||
| + | </ | ||
| ==== Heap Sort ==== | ==== Heap Sort ==== | ||
| Line 602: | Line 662: | ||
| {{https:// | {{https:// | ||
| + | |||
| + | <code python> | ||
| + | # Heap Sort | ||
| + | def heapify(arr, | ||
| + | largest = i | ||
| + | l = 2 * i + 1 | ||
| + | r = 2 * i + 2 | ||
| + | if l < n and arr[l] > arr[largest]: | ||
| + | largest = l | ||
| + | if r < n and arr[r] > arr[largest]: | ||
| + | largest = r | ||
| + | if largest != i: | ||
| + | arr[i], arr[largest] = arr[largest], | ||
| + | heapify(arr, | ||
| + | |||
| + | def heap_sort(arr): | ||
| + | n = len(arr) | ||
| + | for i in range(n // 2 - 1, -1, -1): | ||
| + | heapify(arr, | ||
| + | for i in range(n - 1, 0, -1): | ||
| + | arr[0], arr[i] = arr[i], arr[0] | ||
| + | heapify(arr, | ||
| + | return arr | ||
| + | </ | ||
| ==== Radix Sort ==== | ==== Radix Sort ==== | ||
| Line 609: | Line 693: | ||
| * Vhodný pro řetězce nebo celá čísla s pevnou délkou. | * Vhodný pro řetězce nebo celá čísla s pevnou délkou. | ||
| * Používá se např. u PSČ, osobních čísel apod. | * Používá se např. u PSČ, osobních čísel apod. | ||
| + | |||
| + | <code python> | ||
| + | # Radix Sort | ||
| + | def counting_sort_by_digit(arr, | ||
| + | n = len(arr) | ||
| + | output = [0] * n | ||
| + | count = [0] * 10 | ||
| + | for i in range(n): | ||
| + | index = (arr[i] // exp) % 10 | ||
| + | count[index] += 1 | ||
| + | for i in range(1, 10): | ||
| + | count[i] += count[i - 1] | ||
| + | for i in reversed(range(n)): | ||
| + | index = (arr[i] // exp) % 10 | ||
| + | output[count[index] - 1] = arr[i] | ||
| + | count[index] -= 1 | ||
| + | return output | ||
| + | |||
| + | def radix_sort(arr): | ||
| + | if not arr: | ||
| + | return [] | ||
| + | max_val = max(arr) | ||
| + | exp = 1 | ||
| + | while max_val // exp > 0: | ||
| + | arr = counting_sort_by_digit(arr, | ||
| + | exp *= 10 | ||
| + | return arr | ||
| + | </ | ||
| ==== Counting Sort ==== | ==== Counting Sort ==== | ||
| - | Nevyužívá porovnávání, | + | Nevyužívá porovnávání, |
| * Stabilní, velmi rychlý: $O(n + k)$ (k … rozsah hodnot) | * Stabilní, velmi rychlý: $O(n + k)$ (k … rozsah hodnot) | ||
| Line 620: | Line 732: | ||
| <code python> | <code python> | ||
| - | def countingSort(arr): | + | # Counting Sort |
| - | max_val = max(arr) | + | def counting_sort(arr): |
| - | count = [0] * (max_val + 1) | + | if not arr: |
| - | + | return [] | |
| - | while len(arr) > 0: | + | |
| - | num = arr.pop(0) | + | count = [0] * (max_val + 1) |
| - | count[num] += 1 | + | |
| - | + | count[num] += 1 | |
| - | arr = [] | + | |
| - | for i in range(len(count)): | + | for i in range(len(count)): |
| - | arr += [i] * count[i] | + | |
| - | + | return | |
| - | | + | |
| </ | </ | ||
| Line 655: | Line 766: | ||
| Je to všeobecná strategie pro řešení optimalizačních úloh. Významné vlastnosti: | Je to všeobecná strategie pro řešení optimalizačních úloh. Významné vlastnosti: | ||
| * Hledané optimální řešení lze sestavit z vhodně volených optimálních řešení téže úlohy nad redukovanými daty. | * Hledané optimální řešení lze sestavit z vhodně volených optimálních řešení téže úlohy nad redukovanými daty. | ||
| - | * V rekurzivně formulovaném postupu řešení se opakovaně objevují stejné menší podproblémy. DP umožňuje obejít opakovaný výpočet většinou jednoduchou tabelací výsledků menších podproblémů, | + | * V rekurzivně formulovaném postupu řešení se opakovaně objevují stejné menší podproblémy. DP umožňuje obejít opakovaný výpočet většinou jednoduchou tabelací výsledků menších podproblémů, |
| ===== Dynamické programování pro Nejdelší Společnou Posloupnost (LCS) ===== | ===== Dynamické programování pro Nejdelší Společnou Posloupnost (LCS) ===== | ||
| - | < | + | |
| - | **Myšlenka algoritmu: | + | * Například u posloupností {BDCABA} |
| - | * Cíl: Najít | + | * Časová složitost: $O(m \cdot n)$, kde $m$ a $n$ jsou délky řetězců. |
| - | * Dynamické programování (DP) využívá 2D tabulku pro ukládání dílčích výsledků. Buňka `dp[i][j]` udává délku LCS pro první `i` znaků řetězce `X` a první `j` znaků řetězce `Y`. | + | |
| - | * Pokud `X[i-1] == Y[j-1]`, přidáme tento znak k LCS a přičteme 1 k `dp[i-1][j-1]`. | + | |
| - | * Pokud se znaky liší, vezmeme maximum z `dp[i-1][j]` | + | |
| - | **Pseudokód v Pythonu:** | + | |
| - | ```python | + | * Cíl: Najít nejdelší posloupnost znaků, která se vyskytuje ve stejném pořadí v obou vstupních řetězcích (ne nutně souvisle). |
| + | * Dynamické programování (DP) využívá 2D tabulku pro ukládání dílčích výsledků. | ||
| + | * Buňka | ||
| + | * Pokud `X[i-1] == Y[j-1]`, přidáme tento znak k LCS a přičteme 1 k `dp[i-1][j-1]`. | ||
| + | * Pokud se znaky liší, vezmeme maximum z `dp[i-1][j]` (horní buňka) a `dp[i][j-1]` (levá buňka). | ||
| + | |||
| + | * **Pseudokód v Pythonu: | ||
| + | < | ||
| def lcs(X, Y): | def lcs(X, Y): | ||
| m = len(X) | m = len(X) | ||
| Line 672: | Line 787: | ||
| # Vytvoření DP tabulky s nulami (m+1 x n+1) | # Vytvoření DP tabulky s nulami (m+1 x n+1) | ||
| dp = [[0]*(n+1) for _ in range(m+1)] | dp = [[0]*(n+1) for _ in range(m+1)] | ||
| - | | + | |
| # Naplnění tabulky | # Naplnění tabulky | ||
| for i in range(1, m+1): | for i in range(1, m+1): | ||
| Line 680: | Line 795: | ||
| else: | else: | ||
| dp[i][j] = max(dp[i-1][j], | dp[i][j] = max(dp[i-1][j], | ||
| - | | + | |
| # Rekonstrukce LCS z tabulky | # Rekonstrukce LCS z tabulky | ||
| i, j = m, n | i, j = m, n | ||
| Line 694: | Line 809: | ||
| j -= 1 | j -= 1 | ||
| return '' | return '' | ||
| - | ``` | + | </ |
| **Příklad tabulky pro `X = " | **Příklad tabulky pro `X = " | ||
| - | - Řešení: **" | ||
| + | Řešení: **" | ||
| + | |||
| + | **Tabulka: | ||
| | | | | ||
| |---|---|---|---|---|---|---|---|---| | |---|---|---|---|---|---|---|---|---| | ||
| Line 709: | Line 826: | ||
| | A | 0 | 1 | 2 | 2 | 3 | 3 | 4 | 4 | | | A | 0 | 1 | 2 | 2 | 3 | 3 | 4 | 4 | | ||
| - | **Vysvětlení tabulky: | + | * **Vysvětlení tabulky: |
| - | * První řádek a sloupec jsou inicializovány na 0 (prázdné podřetězce). | + | * První řádek a sloupec jsou inicializovány na 0 (prázdné podřetězce). |
| - | * Buňka `dp[5][7]` (hodnota 4) ukazuje délku LCS. Cesta pro rekonstrukci je vyznačena šipkami: | + | * Buňka `dp[5][7]` (hodnota 4) ukazuje délku LCS. |
| - | - Začínáme od `dp[6][7]` | + | * Cesta pro rekonstrukci je postup diagonální |
| - | **Časová složitost:** | + | |
| - | * Naplnění tabulky: $O(m \cdot n)$, rekonstrukce: $O(m + n)$. | + | * Naplnění tabulky: $O(m \cdot n)$ |
| - | * Celkem: $O(m \cdot n)$. | + | * Rekonstrukce: $O(m + n)$ |
| - | </ | + | * Celkem: $O(m \cdot n)$ |
| - | ===== Rozptylovací tabulky (Hashing) ===== | + | |
| + | |||
| + | |||
| + | ===== 7. Rozptylovací tabulky (Hashing) ===== | ||
| * hashovací funkce, řešení kolizí, otevřené a zřetězené tabulky, double hashing, srůstající tabulky, univerzální hashování. | * hashovací funkce, řešení kolizí, otevřené a zřetězené tabulky, double hashing, srůstající tabulky, univerzální hashování. | ||
| - | * rozptylovací | + | * Rozptylovací tabulky – tabulka, určená k redukování dat na menší data, která budou jednoznačná. |
| - | * Hashovací funkce přiřadí k potenciálně libovolnému množství dat hodnotu | + | * Základ datové struktury slovníku, kde operace search a insert mají konstantní složitost. |
| - | * Hashovací funkce v kontextu algoritmizace by měla být hlavně rychlá (narozdíl | + | * Hashovací |
| + | * Hashovací funkce přiřadí k potenciálně libovolnému množství dat hodnotu, která | ||
| + | * V kontextu algoritmizace by měla být hlavně rychlá (na rozdíl | ||
| + | |||
| + | * Cíl je generovat minimum kolizí. | ||
| + | * Kolize – situace, kdy dvěma různým datům přiřadíme | ||
| * Umožňují vyhledávat v tabulkách s průměrnou časovou složitostí $O(1)$. | * Umožňují vyhledávat v tabulkách s průměrnou časovou složitostí $O(1)$. | ||
| + | |||
| ==== Algoritmické úlohy (soutěžní) ==== | ==== Algoritmické úlohy (soutěžní) ==== | ||
| - | * Two Sum – O(n) hledání dvojice se zadaným součtem pomocí `set`. | + | * Two Sum – $O(n)$ hledání dvojice se zadaným součtem pomocí `set`. |
| * Dynamické programování s memoizací – ukládání $T(n)$ do hashe (Fibonacci, LCS…). | * Dynamické programování s memoizací – ukládání $T(n)$ do hashe (Fibonacci, LCS…). | ||
| * Rolling hash (Rabin–Karp) – rychlé vyhledávání vzoru v textu. | * Rolling hash (Rabin–Karp) – rychlé vyhledávání vzoru v textu. | ||
| - | * Longest Consecutive Sequence – O(n) řešení s `unordered_set`. | + | * Longest Consecutive Sequence – $O(n)$ řešení s `unordered_set`. |
| * Počty výskytů / anagramy – frekvenční slovník pro srovnání řetězců. | * Počty výskytů / anagramy – frekvenční slovník pro srovnání řetězců. | ||
| Line 736: | Line 862: | ||
| * Hash join v relačních databázích při spojování tabulek. | * Hash join v relačních databázích při spojování tabulek. | ||
| * In-memory cache (DNS, LRU) pro konstantní přístup. | * In-memory cache (DNS, LRU) pro konstantní přístup. | ||
| - | * Deduplicace | + | * Deduplikace |
| * Bloom filter – pravděpodobnostní test příslušnosti s malou pamětí. | * Bloom filter – pravděpodobnostní test příslušnosti s malou pamětí. | ||
| ==== Kolize v hashovacích tabulkách ==== | ==== Kolize v hashovacích tabulkách ==== | ||
| - | Kolize | + | * Kolize |
| + | * Hashovací | ||
| + | * Tabulka je nejčastěji reprezentovaná polem s indexy $0 … n-1$, kde $n$ je délka pole. | ||
| - | Hashovací tabulky se používají k rychlému vyhledávání, | + | Existují tři běžné způsoby řešení kolizí: |
| - | + | * zřetězený hashing | |
| - | Tabulka je nejčastěji reprezentovaná polem s indexy $0 … n-1$, kde $n$ je délka pole. | + | * lineární sondování |
| - | + | * double hashing | |
| - | Existují tři běžné způsoby řešení kolizí: zřetězený hashing, lineární sondování | + | |
| === Zřetězený hashing === | === Zřetězený hashing === | ||
| - | Jak to funguje | + | * Každá adresa si zachovává spojový seznam všech hodnot, které se namapují na danou adresu. |
| + | * Vkládání | ||
| + | * Hledání – projdeme | ||
| + | * Mazání – odstraníme uzel ze seznamu | ||
| - | * **Vkládání** – vypočítáme index $h(k)$. | + | Výhody: |
| - | Pokud políčko už obsahuje prvek, vložíme nový na *konec* jeho seznamu. | + | |
| - | * **Hledání** – projdeme seznam, dokud klíč nenajdeme, nebo nedojdeme na jeho konec. | + | |
| - | * **Mazání** – odstraníme uzel ze seznamu (klasická operace na linked-listu). | + | |
| - | + | ||
| - | Výhody | + | |
| * Jednoduchá implementace, | * Jednoduchá implementace, | ||
| - | * Výkon se zhoršuje hladce – degraduje k $O(n)$ jen když se load-factor blíží ∞ a seznamy jsou dlouhé. | + | * Výkon se zhoršuje hladce – degraduje k $O(n)$ jen když se load-factor blíží ∞. |
| - | Nevýhody | + | Nevýhody: |
| * Vícenásobné alokace a ukazatele → ztráta cache-locality. | * Vícenásobné alokace a ukazatele → ztráta cache-locality. | ||
| * Potenciálně vyšší režie alokátorů při častém vkládání. | * Potenciálně vyšší režie alokátorů při častém vkládání. | ||
| - | Složitost | + | Složitost: |
| * Average-case: | * Average-case: | ||
| * Worst-case: $O(n)$ | * Worst-case: $O(n)$ | ||
| === Otevřené rozptylování – Linear probing === | === Otevřené rozptylování – Linear probing === | ||
| - | Jak to funguje | + | Jak to funguje |
| - | * **Vkládání** – vypočítáme index $h(k)$. | + | * **Vkládání** – vypočítáme index $h(k)$. Kolize ⇒ zkusíme $(h(k)+1) \mod n$, pak $+1$… dokud nenajdeme prázdné místo. |
| - | | + | |
| * **Hledání** – stejně sondujeme, dokud | * **Hledání** – stejně sondujeme, dokud | ||
| * nenajdeme klíč | * nenajdeme klíč | ||
| Line 794: | Line 918: | ||
| * $h1(k)$ – primární index v rozsahu $0 … n-1$ | * $h1(k)$ – primární index v rozsahu $0 … n-1$ | ||
| * $h2(k)$ – **krok (step)** v rozsahu $1 … n-1$; | * $h2(k)$ – **krok (step)** v rozsahu $1 … n-1$; | ||
| - | musí být nesoudělný s $n$, aby prohlídka pokryla celé pole. | + | |
| Algoritmus sondování | Algoritmus sondování | ||
| Line 815: | Line 939: | ||
| * Average-case: | * Average-case: | ||
| * Worst-case: $O(n)$ | * Worst-case: $O(n)$ | ||
| + | |||
| + | |||
| === Srůstající (coalesced) hashing === | === Srůstající (coalesced) hashing === | ||
| Kombinuje výhody otevřeného rozptylování a zřetězení: | Kombinuje výhody otevřeného rozptylování a zřetězení: | ||
| * Tabulka má vyhrazenou „sklepní“ část (**cellar**) – např. posledních 10–20 % buněk. | * Tabulka má vyhrazenou „sklepní“ část (**cellar**) – např. posledních 10–20 % buněk. | ||
| - | * Při kolizi prvek uložíme do **prvního volného** místa hledaného lineárně *odspodu* tabulky | + | * Při kolizi prvek uložíme do **prvního volného** místa hledaného lineárně *odspodu* tabulky (tj. v cellar-zóně) a pomocí ukazatele jej připojíme k řetězci své původní bucket-pozice. |
| - | | + | * Vyhledávání prochází ukazatele stejně jako u zřetězení, |
| - | * Vyhledávání prochází ukazatele stejně jako u zřetězení, | + | |
| - | | + | Různé varianty: |
| + | * LISCH (late insert standard coalesced hashing) – přidáváme na konec řetězce. | ||
| + | * EISCH (early insert…) – přidáváme na začátek řetězce. | ||
| + | * LICH, EICH – jako výše, ale se sklepem. | ||
| + | * VICH – kombinuje, kam přidat podle toho, kde řetězec končí. | ||
| Složitost | Složitost | ||
| Line 838: | Line 968: | ||
| === Univerzální hashování === | === Univerzální hashování === | ||
| - | Myšlenka: místo jediné pevné hash-funkce zvolíme při inicializaci **náhodně** $h$ | + | Myšlenka: místo jediné pevné hash-funkce zvolíme při inicializaci **náhodně** $h$ z rodiny $ℋ$, která splňuje podmínku univerzality: |
| - | z rodiny $ℋ$, která splňuje podmínku univerzality: | + | |
| $$ | $$ | ||
| Line 849: | Line 978: | ||
| Důsledky | Důsledky | ||
| - | * **Očekávaná** délka řetězce (nebo počet sond) je $\le α$, takže vkládání, | + | * **Očekávaná** délka řetězce (nebo počet sond) je $\le α$, takže vkládání, |
| - | | + | * Adversář, který nezná zvolenou $h$, neumí zkonstruovat mnoho kolizí (→ odolnost proti útokům na hash-tabulky např. v webových serverech). |
| - | * Adversář, který nezná zvolenou $h$, neumí zkonstruovat mnoho kolizí | + | |
| - | | + | |
| Složitost | Složitost | ||
| * Best / Average (v oč.) $O(1)$, protože $\mathbb{E}[\text{kolize}] \le α$. | * Best / Average (v oč.) $O(1)$, protože $\mathbb{E}[\text{kolize}] \le α$. | ||
| - | * Worst-case: stále $O(n)$ (kdybychom si vybrali „špatnou“ funkci), ale pravděpodobnost, | + | * Worst-case: stále $O(n)$ (kdybychom si vybrali „špatnou“ funkci), ale pravděpodobnost, |
| - | | + | |