aisd - 3 sortowanie i statystyki pozycyjne (1).pdf

49
Algorytmy i struktury danych sortowanie - pojęcia wstępne, podstawowe alg. sortowania tablic, zaawansowane alg. sortowania tablic, kolejki priorytetowe oparte o kopiec sortowanie w czasie liniowym, statystyki pozycyjne

Upload: michael-miller

Post on 02-Oct-2015

226 views

Category:

Documents


0 download

TRANSCRIPT

  • Algorytmy i struktury

    danych sortowanie - pojcia wstpne,

    podstawowe alg. sortowania tablic,

    zaawansowane alg. sortowania tablic,

    kolejki priorytetowe oparte o kopiec

    sortowanie w czasie liniowym,

    statystyki pozycyjne

  • Sortowanie

    Uporzdkowanie elementw

    Klucz fragment danych, dla ktrego jest okrelona

    relacja uporzdkowania

    Zoono problemu najlepszy znany algorytm

    Sortowanie tablic czy plikw

    Zachowanie uporzadkowania czciowego

    Mediana

    Statystyka pozycyjna

  • Indeksy

    Bezporednie sortowanie elementw

    Sortowanie indeksu

    1 7 2 4 8 11 9 5

    1 7 2 4 8 11 7 2

    bezporednie

    0 2 3 7 1 4 6 5

    index

  • Klasyczne algorytmy dla tablic

    sortowanie przez wstawianie (Insertion Sort)

    w kolejnym kroku nastpny element z czci nie posortowanej

    wstawiany jest na odpowiedni pozycj czci posortowanej

    sortowanie przez wybieranie (Selection Sort)

    w kolejnym kroku najwikszy (najmniejszy) element z czci

    nie posortowanej wstawiany jest na koniec czci posortowanej

    sortowanie przez zamian (Exchange, Bubble Sort)

    zamiana elementw miejscami a do skutku

    N. Wirth Algorytmy+Struktury danych = programy

  • Sortowanie bbelkowe

    1 7 2 4 8 11 7 2

    2 7

    I II 4

    7

    7 11 2 11

    III IV

    for j in range(0,n):

    for i in range(0,n-1):

    if(A[i] > A[i+1]):

    A[i],A[i+1] = A[i+1],A[i]

  • Sortowanie bbelkowe

    1 7 2 4 8 11 7 2

    2 7 4 7

    7 11 2 11

    I II

    1 7 2 4 8 11 7 2

    2 7 4 7

    7 11 2 11

    7 8 2 8

    for j in range(0,n):

    for i in range(0,n-1):

    if(A[i] > A[i+1]):

    A[i],A[i+1] = A[i+1],A[i]

  • Sortowanie bbelkowe

    //wariant podstawowy for j in range(0,n):

    for i in range(0,n-1):

    if(A[i] > A[i+1]):

    A[i],A[i+1] = A[i+1],A[i]

    //wariant ulepszony wewntrzna ptla nie przeglda

    //uporzdkowanych elementw for j in range(n-1,-1,-1):

    for i in range(0,j):

    if(A[i] > A[i+1]):

    A[i],A[i+1] = A[i+1],A[i]

  • Sortowanie bbelkowe

    //wariant ulepszony - detekcja koniecznoci powtrze for j in range(n-1,-1,-1):

    change = false

    for i in range(0,j):

    if(A[i] > A[i+1]):

    A[i],A[i+1] = A[i+1],A[i]

    change = true

    if not change: break

  • Sortowanie bbelkowe

    Waciwoci:

    alg. prosty w implementacji

    zoono O(n2)

    zwizy kod - mae stae proporcjonalnoci

    zachowuje uporzdkowania czciowe

    Stosunkowo najgorsze zachowanie spord prostych

    metod

  • Sortowanie przez proste

    wstawianie

    zachowuje uporzdkowania czciowe

    pesymistyczna zoono O(N2)

    mniej zapisw ni przy sortowaniu przez zamian parami

    1 7 2 8 11 4 7 2

    2 7

    X = 1 X = 7 X = 2 for i in range (1, n)

    x = A[i]

    p = znajdz_miejsce_na(x)

    A[p] = x

  • Sortowanie przez proste

    wstawianie

    1 2 7 8 11 4 7 2

    4 7 8

    11

    X = 2 X = 8 X = 11 X = 4

    zachowuje uporzdkowania czciowe

    pesymistyczna zoono O(N2)

    mniej zapisw ni przy sortowaniu przez zamian parami

    for i in range (1, n)

    x = A[i]

    p = znajdz_miejsce_na(x)

    A[p] = x

  • Sortowanie przez proste

    wstawianie

    def ProsteWstawianie(A, n):

    for i in range (1, n):

    x = A[i]

    for j in range (i-1, -1, -1):

    if x>=A[j] : break

    A[j+1] = A[j]

    A[j+1] = x

  • Sortowanie Shella Zaawansowane sortownie przez wstawianie elementw

    1. Wybieramy k = kp

    2. Sortujemy przez wstawianie proste podciagi caej tablicy (co

    k-ty element)

    3. zmniejszamy k tak dugo a osignie 1

    o zoonoci alg. decyduje kp i sposb zmiany k

    kp = 1 oznacza zwyke sortowanie

    dla ki = 2i - 1 (....., 31, 15, 7, 3, 1 )

    algorytm ma zoono O(N1.2)

    dla ki = 2r3q (r,q N) (......, 20, 16, 10, 9, 8, 6, 4, 3, 2, 1)

    algorytm ma zoono O(N log2N)

    algorytm zachowuje uporzdkowanie czciowe

  • Sortowanie Shella

    1 2 7 8 11 4 7 2

    4

    zachowuje uporzdkowanie czciowe

    pesymistyczna zoono O(N1.2)

    for k in [ ..., 31, 15, 7, 3, 1] :

    sortuj_przez_wstawianie_k_podtablic(A)

    #A[0],A[k],A[2k] ...

    #A[1],A[k+1],A[2k+1] ...

    #...

    #A[k-1],A[2k-1],A[3k-1] ...

    k=7

  • Sortowanie Shella

    1 2 7 8 11 4 7 2

    4

    zachowuje uporzdkowanie czciowe

    pesymistyczna zoono O(N1.2)

    for k in [ ..., 31, 15, 7, 3, 1] :

    sortuj_przez_wstawianie_k_podtablic(A)

    #A[0],A[k],A[2k] ...

    #A[1],A[k+1],A[2k+1] ...

    #...

    #A[k-1],A[2k-1],A[3k-1] ... 1 2 4 8 11 4 7 2 11

    2

    k=7 k=3

    8

    7

  • Sortowanie Shella def ShellSort (A, N):

    k = 2lg N - 1

    while k >= 1:

    for i in range(k,N):

    x = A[i]

    j = i-k

    while j >= 0 and x < A[j]:

    A[j+k] = A[j]

    j -= k

    A[j+k] = x

    k = (k+1)/2 1

  • Sortowanie szybkie

    Zaawansowane sortowanie przez zamian elementw

    1. Podziel tablic A[p..r] na dwie A1[p..q] i A2[q+1..r],

    takie, e kady element nalecy do A1 jest mniejszy

    ni dowolny element A2

    2. Posortuj A1 i A2

  • Quicksort - implementacja def QuickSort(A, l, r):

    if (l < r) :

    q = Partition(A, l, r)

    QuickSort (A, l, q)

    QuickSort (A, q+1, r)

    QuickSort(Tablica, 0, MAX-1)

  • Partition

    1. Wybieramy element x (granic podziau)

    2. Idc od poczatku oprzedziau szukamy pierwszego

    elementu wikszego lub rwnego ni x.

    3. Idc od gry przedziau szukamy ostatniego

    elementu mniejszego lub rwnego ni x

    4. Zamieniamy znalezione elementy.

    5. Koczymy gdy poszukiwania dotr to tego samego

    elementu

    6. Warunki brzegowe:

    co bdzie gdy wybierzemy min/max w przedziale?

  • Partition - implementacja def Partition(A, l, r):

    x = A[l]

    i = l-1

    j = r+1

    while true:

    while true:

    j = j-1

    if A[j] = x : break

    if i

  • Randomized partition

    Zapobiega umylnemu wygenerowaniu

    najgorszego przypadku danych (ale dalej

    moliwe jest wystpienie takiego przypadku)

    def RandomPartition(A, l, r):

    i = Random(l, r)

    A[i],A[l] = A[l],A[i]

    return Partition(A, l, q)

  • Qicksort - waciwoci redni czas O(N log N)

    pesymistyczny czas O(N2)

    prosty algorytm niewielki narzut

    najgorszy przypadek:

    Partition za kadym razem tworzy obszary

    o rozmiarach N-1 i 1

    Randomized Partition brak moliwoci podania

    najgorszego przypadku

    Aby zmniejszy ew. zajto stosu (w najgorszym przypadku

    ~N) mona wybiera do sortowania najpierw mniejszy

    a potem wikszy z przedziaw (co najwyej log N)

    Zachowanie uporzdkowania czciowego zaley od

    implementacji funkcji Partition

  • Kopiec

    Kady element jest nie mniejszy (wikszy) ni jego

    dzieci

    15

    9 13

    8 7 10 1

    2 4 3

    15 9 13 8 7 10 1 2 4 3

    def Parent(i): return i/2

    def Left(i): return i*2

    def Right(i): return i*2+1

    UWAGA index = 1..size

    A[Parent(i)] >= A[i]

    1

    2 3

    4 5 6 7

    8 9 10

  • Przywracanie wasnoci kopca

    Z: waciwo kopca moe nie by speniona tylko dla

    korzenia

    1) rozpocznij od korzenia (W=Root)

    2) if jest speniona waciwo kopca dla W i synw:

    koniec

    else

    zamie W z wikszym z synw W

    powtrz 2) dla nowego W

  • Przywracanie w. kopca

    15

    5 14

    10 4 9 3

    2 8 1

    15

    10 14

    5 4 9 3

    2 8 1

    15

    10 14

    8 7 9 3

    2 5 1

    1

    2 3

    4 5 6 7

    8 9 10

    1

    2 3

    4 5 6 7

    8 9 10

    1

    2 3

    4 5 6 7

    8 9 10

  • Przywracanie wasnoci kopca def Heapify(A, i, size):

    L = Left(i)

    R = Right(i)

    if LA[i-1]:

    maxps = L

    else:

    maxps = i

    if RA[maxps-1]:

    maxps = R

    if maxps != i:

    A[i-1],A[maxps-1] = [maxps-1],A[i-1]

    Heapify(A, maxps, size)

  • Sortowanie kopcowe

    Tworzenie kopca z caej tablicy

    Przywracamy wasno kopca dla coraz wikszych kopcw

    Dla kolejnych (coraz mniejszych) kopcw Wybr najwikszego elementu (korze kopca),

    Zamiana z ostatnim,

    Zmniejszenie rozmiarw kopca,

    Przywrcenie wasnoci kopca.

  • Budowa kopca 5 1 3 2 11 7 4 10 5 7

    5

    1 3

    2 11 7 4

    10 6 7

    1

    2 3

    4 5 6 7

    8 9 10

    5

    1 3

    10 11 7 4

    2 6 7

    1

    2 3

    4 5 6 7

    8 9 10

    5

    1 7

    10 11 3 4

    2 6 7

    1

    2 3

    4 5 6 7

    8 9 10

    5

    11 7

    10 7 3 4

    2 6 1

    1

    2 3

    4 5 6 7

    8 9 10

    11

    10 7

    6 7 3 4

    2 5 1

    1

    2 3

    4 5 6 7

    8 9 10

    11 10 7 6 7 3 4 2 5 1

  • Sortowanie kopca 11 10 7 8 7 9 3 2 4 1 8 7 7 4 1 9 9 2 10 11

    11

    10 7

    8 7 9 9

    2 4 1

    1

    2 3

    4 5 6 7

    8 9 10

    1

    10 7

    8 7 9 9

    2 4 11

    1

    2 3

    4 5 6 7

    8 9

    10

    8 7

    4 7 9 9

    2 1 11

    1

    2 3

    4 5 6 7

    8 9

    1

    8 7

    4 7 9 9

    2 10 11

    1

    2 3

    4 5 6 7

    8

    8

    7 7

    4 1 9 9

    2 10 11

    1

    2 3

    4 5 6 7

    8

  • Sortowanie kopcowe def BuildHeap(A, size):

    for i in range(size/2,0,-1):

    Heapify(A, i, size)

    def HeapSort(A, size):

    BuildHeap(A, size)

    for i in range(size-1,1,-1) :

    A[i], A[0] = A[0], A[i]

    Heapify(A, 1, i)

  • Sortowanie przez scalanie

    nie jest wymagany dostp do wszystkich elementw

    np. dla plikw, list

    podzia cigu A -> B,C

    scalenie B+C -> cig par

    cig par - > B,C

    scalenie B+C -> cig czwrek

    cig czwrek - > B,C

    scalenie B+C -> cig semek

    .

  • Sortowanie przez scalanie we: 40, 60, 10, 45, 90, 20, 09, 72

    podzia: (40) (60) (10) (45)

    (90) (20) (09) (72)

    scalanie: (40 90) (20 60) (09 10) (45 72)

    podzia: (40 90) (20 60) (09 10) (45 72)

    scalanie: (09 10 40 90) (20 45 60 72)

    podzia : (09 10 40 90) (20 45 60 72)

    scalanie: (09 10 20 40 45 60 72 90)

  • Kolejka priorytetowa

    Przykad: zadania do wykonania, zamwienia

    Wymagane operacje:

    Dodaj element o priorytecie X

    Pobierz element o najwyszym priorytecie

    Przeczytaj element o najwyszym priorytecie (bez

    usuwania)

    Przy realizacji kolejki priorytetowej przy pomocy kopca

    Zapis: dodawanie elementw do kopca

    Odczyt: zwr A[0] i przebuduj kopiec

  • Dodawanie do kopca 1) dodaj nowy element w na koniec kopca

    2) if jest speniona waciwo kopca dla W\

    i ojca W:

    koniec

    else:

    zamie W z ojcem W

    powtrz 2) dla W i nowego ojca W

  • Dodawanie do kopca

    13

    10 7

    6 7 3 4

    2 5 1

    1

    2 3

    4 5 6 7

    8 9 10

    11

    13 10 7 6 7 3 4 2 5 1 11

    7 13 11 7 6 10 3 4 2 5 1

    13

    11 7

    6 10 3 4

    2 5 1

    1

    2 3

    4 5 6 7

    8 9 10

    7

  • Usunicie maksimum/minimum

    Spostrzeenie: Maximum (Minimum) jest korze kopca

    1) Usuwamy korze

    2) Na miejsce korzenia wstawiamy ostatni

    element kopca

    3) Wykonujemy Heapify(Root)

  • Kolejka priorytetowa - realizacja def HeapInsert(A, size, newElement):

    if size>=MAXSIZE:

    ERROR przepelnienie kopca

    else:

    size=size+1

    i = size

    while i>1 and A[Parent(i)-1]

  • Kolejka priorytetowa - realizacja def HeapGetMax(A, size):

    if size

  • Sortowanie liniowe?

    Niekiedy dodatkowe informacje o kluczach

    lub charakterze elementw umoliwiaj

    sortowanie w czasie liniowym

  • Sortowanie przez zliczanie Czas liniowy

    Zaoenie: wszystkie elementy s liczbami

    z przedziau 0..maxN

    maxN jest akceptowalnie due (tablica mieci si

    w pamici komputera)

    1) zlicz (w tablicy A) wystpienia poszczeglnych\

    elementw

    2) przygotuj tablice B z pocztkami sekwencji

    B[] = 0

    B[i] = B[i-1] + A[i-1]

    3) przepisz elementy do nowej tablicy C na pozycj

    C[B[element.klucz]++] = element

  • Sortowanie przez zliczanie def CountingSort(A, B, maxN, size):

    for i in range(0, maxN+1):

    C[i] = 0

    for i in range(0, size):

    C[A[i]] = C[A[i]]+1

    # C[i] zawiera liczb elementw rwnych i

    for i in range(1, maxN+1):

    C[i] = C[i] + C[i-1]

    # C[i] zawiera liczb elementw

  • Sortowanie przez zliczanie We I A[i] B[i] Wy

    A3 0 0 0 E1

    B2 1 2 0+1+1 I1

    C3 2 2 2+1+1 B2

    D5 3 2 4+1+1 F2

    E1 4 2 6+1+1 A3

    F2 5 1 8+1 C3

    G4 6 0 9 G4

    H4 7 0 9 H4

    I1 8 0 9 D5

  • Sortowanie kubekowe Czas liniowy

    Zaoenie: wszystkie klucze s liczbami (rzeczywistymi) z

    przedziau x0 .. x1

    Rwnomierny rozkad wartoci kluczy w przedziale

    1) podziel dziedzin kluczy na n rwnych przedziaw

    dugoci p = (x1 - x0) / n,

    gdzie i-ty przedzia < x0+(i-1)*p , x0+i*p),

    dla i = 1..n, a ostatni (pierwszy) przedzia jest

    obustronnie domknity

    2) przepisz n elementw do n list (kubekw), tak

    aby elementy na i-tej miay klucze z nalece do

    i-tego przedziau

    3) Posortuj elementy w kubekach (dowolnym alg.)

    4) Wypisz zawarto poszczeglnych kubekw od i = 1

    do n

  • Wyszukiwanie maksimum def Minimum(A, size):

    m = A[0]

    for i in range(1,size):

    if (m>A[i]): m=A[i]

    return m

  • Wyszukiwanie min i maks def MinMax(A, size):

    mi = A[0]

    ma = A[0]

    for i in range(2,size+2,2) :

    if A[i]

  • Zwracanie kilku wartoci C/C++ struct MM {

    ELEMENT min, max;

    MM(ELEMENT emin, ELEMENT emax) {// konstruktor

    Min = emin;

    Max = emax;

    }

    };

    MM Minmax(ELEMENT A[], INDEX size)

    {

    .....

    return MM(min, max);

    //bez konstruktora trzeba uy zmiennej

    //chwilowej

    }

  • Wyszukiwanie i-tej statystyki

    Oczekiwany czas dziaania = O(n)

    Pesymistyczny czas dziaania = O(n2)

    def RandomizedSelect(A, i, l, r):

    if l == r: return A[p]

    q = RandomizedPartition(A, l, r)

    k = ql+1

    if i

  • Wyszukiwanie i-tej statystyki Pesymistyczny czas dziaania = O(n)

    INDEX PartitionX(ELEMENT A[], INDEX p, INDEX r,

    ELEMENT e)

    ELEMENT Select(ELEMENT A[], INDEX p, INDEX r)

    1. Podziel elementy p do q na n/5 grup po 5 elementw O(n)

    2. Wyznacz median kadej z n/5 grup, sortujc je (czas stay). Jeli (ostatnia) ma parzyst liczb elementw wybierz wiksz z median

    O(n)

    3. Wywoaj rekurencyjnie x = Select(...) na zbiorze median

    wyznaczonym w kroku 2 - b.d.

    4. Podziel tablic A wzgldem mediany median tj. x i zmodyfikowanej

    PartitionX. Niech wynik bdzie k - O(n)

    5. Wywoaj rekurencyjnie Select(A, p, k) jeeli i

  • Wyszukiwanie i-tej statystyki

    x

    Uwagi:

    Co najmniej poowa median jest wiksza rwna x

    Co najmniej n/5 grup zawiera 3 elementy wiksze rwne x,

    przy czym jedna z nich zawiera x, a druga moe by niepena

    Std liczba elementw wiksza (mniejsza) od x wynosi co

    najmniej 3 (1/2 n/5 - 2) 3n/10 - 6