Om man ska skriva ut alla talen i trädet vill man oftast göra det i
så kallad inordning (eng. inorder), dvs från vänster
till höger.
Fråga: Hur skriver man ut trädet i inordning?
Rekursivt svar: Först skriver man ut vänsterträdet,
sedan rottalet, sist högerträdet.
...men ett tomt träd skriver man inte alls.
Följande funktion gör att write(root) skriver ut
1 17 666 4711 9999 för vårt träd.
#Inordning
def write(p):
if p != None:
write(p.left)
print p.value
write(p.right)
Om man kastar om dom tre sista satserna får man ändå ut alla talen
på skärmen men i andra ordningar. Preordning (eng.
preorder) innebär att rottalet skrivs först, sedan vänsterträdet
och sist högerträdet.
I vårt exempel blir ordningen
4711 17 1 666 9999.
Om vi återgår till orkesterträdet kan vi se att preordning faktiskt ger vettigare utskrift. Så här blir koden i det fallet.
#Preordning
def write(p):
if p != None:
print p.value
write(p.down)
write(p.right)
Utskriften blir då den naturliga. Om vi för tydlighets skull
använder indragning av orden på lägre nivå blir utskriften
Orkester
Blås
Trä
Bleck
Stråk
Vi
Va
Vc
Kb
Slag
(Hur gör man för att få dessa indragningar?)
Slutligen kan man skriva ut i postordning (eng. postorder) och det innebär att vänsterträdet skrivs först, sedan högerträdet och sist roten. Det ger 1 666 17 9999 4711 i vårt exempel.
n.
Exempel: För sortering är n antalet tal som ska sorteras.
T(n) för växande n?
|             n     |         log(n)         |       nlog(n)       |         n2         |         2n         | |
|---|---|---|---|---|---|
| 10 | 10 s | 1 s | 10 s | 100 s | 17 min |
| 100 | 100 s | 2 s | 3 min | 2 tim | 1022 år |
| 10000 | 10000 s (ca 3 tim) | 4 s | 11 tim | 3 år |
Istället för att ange den exakta tidsfunktionen T(n) nöjer vi
oss med att ange ordoklassen O(n).
Definition
T(n) är O(F(n)) om det finns positiva konstanter
c och n0 sådana att 0<=T(n)<=cF(n)
för n>=n0
cF(n) anger en övre gräns för T(n) då n är stort.
T(n) = 10n2 + 100n + 10logn + 1000 säger vi är O(n2).
O(n) (i värsta fallet måste vi titta på alla n elementen).
Här följer en funktion för linjärsökning i en lista.
def linjarsokning(listan, nyckel):
for x in listan:
if x == nyckel:
return True
return False
|
| 11 | 13 | 13 | 20 | 22 | 25 | 28 | 30 | 31 | 32 | 32 | 48 | 62 |
| 11 | 13 | 13 | 20 | 22 | 25 |      |      |      |      |      |      |      |
|      |      |      | 20 | 22 | 25 |      |      |      |      |      |      |      |
|      |      |      |      |      | 25 |      |      |      |      |      |      |      |
O(log n) i värsta fallet:
n element och undrar hur många varv sökningen kan ta.
Antal element att söka bland halveras i varje varv, så första varvet får vi
n/2, andra varvet n/4, tredje varvet n/8. Vi är klara när det bara finns ett
element kvar att titta på och då är n/2x=1 där x är antal varv.
Vi två-logaritmerar bägge led och får att x=2log(n).
def binsok(listan, nyckel):
"""Söker i "listan" efter "nyckel". Returnerar True om den hittas, False annars"""
vanster = 0
hoger = len(listan)-1
found = False
while vanster <= hoger and not found:
mitten = (vanster + hoger)/2
if listan[mitten] == nyckel:
found = True
else:
if nyckel < listan[mitten]:
hoger = mitten-1
else:
vanster = mitten+1
return found
|