Sökning och sortering Sökning i oordnad lista Att söka efter data man lagrat undan för senare användning är vanligt Egentligen har man ingen annan anledning för att lagra undan data Har man mycket data och många sökningar måste man fundera över hur man organiserar sina data Riktigt stora mängder data organiseras i specialapplikationer som kallas databaser (en annan kurs) Vi tittar på det mest grundläggande, leta i mindre datamängder, sortera mindre datamängder för snabbare sökning För att förenkla resonemanget tittar vi på numeriska data som vi organiserar på enklast möjliga sätt, i listor Normalt så letar vi i listor med poster i någon form där en informationsbärande enhet är ett nyckelvärde och posten innehåller mer information, t.ex: { pnr : 451211-5306, förnamn : Sten, efternamn : Smart,...} där den självklara nyckeln är pnr while idx < last and location == None: DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 1 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 2 / 19 Sökning med vaktpost i oordnad lista Sökning i ordnad lista Man kan använda sig av ett trick för att förenkla villkoren i slingan. Man låter det finnas en extra plats (sista platsen + 1) där man lagrar det man söker. Då kan man söka utan att kolla index, man hittar ju senast på sista platsen. Man kallar det för att använda vaktpost (sentinel): lista.append(nyckel) while location == None: if location < last: while idx < last and location == None and lista[idx] <= nyckel: if location!= None and nyckel == lista[location]: Om listan är ordnad behöver vi inte söka igenom hela listan. Elementen i listan är i stigande ordning. DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 3 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 4 / 19
Sökning med vaktpost i ordnad lista Sökning i sorterad lista binärsökning Även här kan man använda vaktpost men då blir det krångligare villkor för träff: Om vi söker i en sorterad indexerbar lista kan vi söka på ett smartare sätt: lista.append(nyckel) while location == None and lista[idx] <= nyckel: if location!= None and location < last and \ nyckel == lista[location]: Intervallhalveringsmetoden kallas vid sökning för binärsökning. 1. mitten = (vänster + höger) // 2 2. om nyckel < lista[mitten] så höger = mitten annars vänster = mitten 3. Om vänster < höger så fortsätt från 1 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 5 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 6 / 19 Binärsökning Sortering vänster = 0 höger = len(lista) - 1 while vänster < höger: mitten = (vänster + höger + 1) // 2 if nyckel < lista[mitten]: höger = mitten - 1 vänster = mitten if lista[vänster] == nyckel: return vänster Så gott som varje program innehåller delar för att sortera data Om vi söker ofta i våra data och om vi har mycket data blir sortering viktig Eftersom sortering är ett vanligt och tidskrävande moment i bearbetningen har mycket arbete lagts ner på att ta fram bra metoder Vi skall titta på tre enkla (långsamma) metoder. DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 7 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 8 / 19
Urvalssortering Urvalssortering i Python 1. Sök reda på minsta elementet 2. Byt första och minsta elementen med varandra 3. Om det finns fler element: Sortera resten med samma metod. 2 17 5 13 9 22 23 15 def urvalssortering(lista): for i in range(len(lista)-1): m = i for j in range(i + 1, len(lista)): if lista[j] < lista[m]: m = j lista[i], lista[m] = lista[m], lista[i] 2 5 17 13 9 22 23 15 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 9 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 10 / 19 Urvalssortering i Scheme Utbytessortering 1. Gå igenom listan, jämför grannar och byt om de står fel 2. Sista elementet står rätt, räkna bort! 3. Om det finns fler element: Sortera med samma metod. (define (selection-sort lista) (define (sort lista sorterad-lista) (if (null? lista) sorterad-lista (let ((min (find-min (cdr lista) (car lista)))) (sort (delete min lista) (append sorterad-lista (list min)))))) (sort lista ())) 17 5 13 9 22 2 15 23 5 13 9 17 2 15 22 23 5 9 13 2 15 17 22 23 5 9 2 13 15 17 22 23 5 2 9 13 15 17 22 23 2 5 9 13 15 17 22 23 2 5 9 13 15 17 22 23 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 11 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 12 / 19
Utbytessortering (bubbelsortering) Bättre utbytessortering def utbytessortering(lista): for i in range(len(lista), 1, -1): for j in range(i-1): if lista[j] > lista[j+1]: lista[j], lista[j+1] = lista[j+1], lista[j] Metoden kan förbättras genom att man avbryter om man inte utfört något byte under ett pass. def utbytessortering(lista): for i in range(len(lista), 1, -1): ready = True for j in range(i-1): if lista[j] > lista[j+1]: lista[j], lista[j+1] = lista[j+1], lista[j] ready = False if ready: break DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 13 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 14 / 19 Insättningssortering Insättningssortering 1. Betrakta listan som en redan sorterad del och en osorterad del. 2. Så länge den osorterade delen inte är tom ta ett tal ur den osorterade delen och sortera in i den sorterade delen. 17 23 5 13 9 22 2 15 def insättningssortering(lista): for i in range(len(lista)): j = i-1 key = lista[i] while (lista[j] > key) and (j >= 0): lista[j+1] = lista[j] j -= 1 lista[j+1] = key 5 17 23 13 9 22 2 15 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 15 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 16 / 19
Insättningssortering i Scheme Hur bra är det här? I scheme blir det så här: (define (insertion-sort lista) (define (sortin element lista) (cond ((null? lista) (list element)) ((< element (car lista)) (cons element lista)) (else (cons (car lista) (sortin element (cdr lista)))))) (define (iter-sort lista elements) (if (null? elements) lista (iter-sort (sortin (car elements) lista) (cdr elements)))) (iter-sort () lista)) Metoderna fungerar lika bra för alla typer av element. Ev måste man definiera egna motsvarigheter till >, < och = men i övrigt som förut. Alla tre metoderna består av dubbelloop för jämförelse och flyttning av element. För varje element med index 1 i n För varje element i j n <operationer på listan> (n i + 1) = n Finns det bättre metoder? i + 1 = n 2 n n + 1 2 + n = n2 2 + n 2 = O(n2 ) DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 17 / 19 DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 18 / 19 Enkel analys a<b a<c b<c c<b a<b a<c a<b b c a c<b a b a<c går inte c a<b a<c b går inte a<b<c Ja! Mer om det senare DA2001 (Föreläsning 17) Datalogi 1 Hösten 2018 19 / 19