TDT4120 Algoritmer og datastrukturer Interaktivt kompendium · H2026
Fremgang
0/15

Begreper

01 Grunnlag

Problem og instans #
Et problem er relasjonen mellom input og output. En instans er én bestemt input. Problemstørrelsen nn er plassen en instans trenger, som regel antall elementer.
RAM-modellen #
Random-access machine: en idealisert maskin der aritmetikk, sammenligning, hopp og oppslag i én celle koster én tidsenhet hver, og instruksjonene utføres etter hverandre. Heltallene er om lag clg⁡nc \lg n bits brede.
Asymptotisk notasjon #
Et språk for vekst som ser bort fra konstantfaktorer og lavere ordens ledd. Oppfører seg som sammenligning av tall: OO er ≤\le, Ω\Omega er ≥\ge, Θ\Theta er ==, oo er << og ω\omega er >>. De to siste krever ulikheten for enhver konstant c>0c > 0, ikke bare for én.
Beste, verste og gjennomsnittlige tilfelle #
Tre funksjoner av nn: kjøretiden for den billigste instansen av størrelse nn, for den dyreste, og den forventede kostnaden når instansen trekkes tilfeldig. Hvilket tilfelle det gjelder er uavhengig av hvilken asymptotisk operator som brukes på det.
Løkkeinvariant #
En påstand om tilstanden som holder ved starten av hver iterasjon. Vises med initialisering, vedlikehold og terminering, og er induksjonsbeviset for at løkka er korrekt.
Insertion-Sort #
Sorterer ved å holde A[0..i−1]A[0 .. i - 1] sortert og sette A[i]A[i] inn på rett plass i det utsnittet. Bruker Θ(n)\Theta(n) i beste tilfelle og Θ(n2)\Theta(n^2) i verste, og sorterer på plass.

02 Datastrukturer

Stakk #
Sist inn, først ut (LIFO). Alt skjer på toppen: Push legger på og Pop tar av, begge i konstant tid. Implementeres med en tabell og en toppindeks.
Kø #
Først inn, først ut (FIFO). Enqueue legger til bakerst og Dequeue tar ut forrest, begge i konstant tid. Implementeres gjerne som ringbuffer: en tabell der indeksene head og tail rykker fremover og går rundt til starten når de passerer enden.
Lenket liste #
Noder som peker på neste node, og i en dobbeltlenket liste også på forrige. Innsetting og sletting koster konstant tid når du står ved noden; søk følger pekerne og koster lineær tid.
Dynamisk mengde #
Funksjonalitet, ikke en bestemt struktur: hold en mengde elementer med nøkler, og støtt Search, Insert og Delete, for ordnede nøkler også Minimum, Maximum, Successor og Predecessor. Finnes ikke svaret, returneres NIL.
Hashtabell #
Oppslagstabell der en hashfunksjon regner indeksen ut fra nøkkelen, for eksempel h(k)=k mod mh(k) = k \bmod m. To nøkler kan få samme indeks, en kollisjon; med kjeding får hver plass en lenket liste som tar imot alle sine nøkler.
Belastningsfaktor #
α=n/m\alpha = n/m: antall elementer delt på antall plasser i hashtabellen. Med kjeding og jevn fordeling er forventet søketid Θ(1+α)\Theta(1 + \alpha), så tabellen bør vokse i takt med datamengden.
Perfekt hashing #
For en statisk nøkkelmengde: nøklene hashes først inn i m=nm = n plasser, og plass jj med njn_j nøkler får en sekundærtabell med nj2n_j^2 plasser og en hashfunksjon uten kollisjoner der. Søk tar konstant tid selv i verste fall, og plassen er O(n)O(n).
Amortisert analyse #
Snitt per operasjon over en hel operasjonsfølge, i verste fall. Aggregert analyse: regn ut totalt arbeid og del på antall operasjoner. Ingen sannsynlighet er involvert, i motsetning til gjennomsnittstilfellet, som er et snitt over instanser.
Tabelldobling #
Når tabellen er full, eller for en hashtabell når α\alpha har nådd en fast grense: alloker en dobbelt så stor, kopier (eller hash på nytt) alt over og fortsett. Én innsetting kan koste lineær tid, men nn innsettinger koster totalt under 3n3n operasjoner, og nøyaktig 2n−12n - 1 når nn er en toerpotens. Det er amortisert konstant per innsetting.

03 Problemer og reduksjoner

Søkeproblem #
Gitt en instans xx: finn en løsning yy slik at (x,y)∈R(x, y) \in R. Finnes ingen, feiler søket.
Beslutningsproblem #
Gitt en instans xx: avgjør om det finnes en løsning yy med (x,y)∈R(x, y) \in R. Svaret er ja eller nei, og problemet kan ses som mengden av ja-instanser.
Optimeringsproblem #
Blant de akseptable løsningene til en instans: finn en som er best mulig etter et gitt mål, for eksempel størst, kortest eller billigst.
Sertifikat #
En påstått løsning som verifiseres: gitt xx og sertifikatet yy, sjekk om (x,y)∈R(x, y) \in R. Å verifisere er ofte langt billigere enn å finne løsningen selv.
Orakel #
En hypotetisk subrutine som antas å løse et gitt problem. Reduksjoner beskrives med orakler: det som gjenstår etter omformingen av instansen, overlates til oraklet.
Reduksjon #
Å løse problem XX ved å omforme instansen og bruke et orakel for problem YY. Cook-reduksjoner tillater mange orakelkall, Levin-reduksjoner ett kall med oversettelse av løsningen tilbake, og Karp-reduksjoner ett kall der ja/nei-svaret går uendret gjennom. En billig reduksjon fra XX til YY viser at YY er minst like vanskelig som XX.

04 Splitt og hersk

Splitt og hersk #
Designmetode: løs grunntilfellet direkte, ellers del instansen i uavhengige delinstanser, løs dem rekursivt og kombiner delsvarene. Arbeidet ligger som regel i enten delingen eller kombinasjonen. Korrektheten vises ved sterk induksjon over problemstørrelsen.
Rekurrens #
En ligning som definerer en funksjon ved hjelp av seg selv på mindre argumenter, for eksempel T(n)=2T(n/2)+nT(n) = 2T(n/2) + n. Kjøretiden til en rekursiv algoritme har denne formen. En algoritmisk rekurrens har konstant grunntilfelle for små nn og terminerer, og det antas når ikke annet er sagt.
Iterasjonsmetoden #
Løser en rekurrens ved å ekspandere den rekursive forekomsten gjentatte ganger til et mønster viser seg, velge antall ekspansjoner slik at argumentet treffer grunntilfellet, og summere.
Rekursjonstre #
Iterasjonsmetoden tegnet som et tre: rota er f(n)f(n), nivå ii har aia^i noder av størrelse n/bin/b^i, og kjøretiden er summen av nivåkostnadene. Antall løvnoder er alog⁡bn=nlog⁡baa^{\log_b n} = n^{\log_b a}.
Substitusjonsmetoden #
Verifiserer en gjettet eller funnet løsning med induksjon: anta at løsningen holder for mindre argumenter, sett inn i rekurrensen og vis at den holder for nn. Sjekk grunntilfellet. Påstanden må være nøyaktig den samme før og etter, konstanten inkludert; O(1)O(1) i hypotesen og O(1)O(1) i konklusjonen kan skjule to ulike konstanter.
Masterteoremet #
Løser T(n)=aT(n/b)+f(n)T(n) = aT(n/b) + f(n) ved å sammenligne den drivende funksjonen f(n)f(n) med vannskillefunksjonen nlog⁡ban^{\log_b a}. Er ff polynomisk mindre, dominerer løvnodene: Θ(nlog⁡ba)\Theta(n^{\log_b a}). Er f=Θ(nlog⁡balg⁡kn)f = \Theta(n^{\log_b a} \lg^k n) for en konstant k≥0k \ge 0, er løsningen Θ(nlog⁡balg⁡k+1n)\Theta(n^{\log_b a} \lg^{k+1} n). En logaritmisk faktor under vannskillefunksjonen, som n/lg⁡nn/\lg n, dekkes ikke. Er ff polynomisk større og regulær, dominerer rota: Θ(f(n))\Theta(f(n)).
Binærsøk #
Søk i en sortert tabell ved å sammenligne med midtelementet og søke rekursivt i den halvdelen verdien må ligge i. T(n)=T(n/2)+1T(n) = T(n/2) + 1, altså Θ(lg⁡n)\Theta(\lg n). Det rekursive kallet er det siste i prosedyren, så algoritmen skrives like gjerne som en løkke.
Merge-Sort #
Del på midten, sorter halvdelene rekursivt og flett dem. Flettingen kopierer halvdelene til LL og RR med en vaktpost ∞\infty bakerst og flytter det minste forreste elementet til neste ledige plass, i Θ(n)\Theta(n) tid. T(n)=2T(n/2)+n=Θ(nlg⁡n)T(n) = 2T(n/2) + n = \Theta(n \lg n) i alle tilfeller.
Quicksort #
Partition velger siste element som pivot og ordner resten med små elementer til venstre og store til høyre, i Θ(n)\Theta(n) tid; pivoten havner på sin endelige plass. Delene sorteres rekursivt. Θ(nlg⁡n)\Theta(n \lg n) ved jevn deling og i snitt over alle rekkefølger, Θ(n2)\Theta(n^2) når pivoten står alene, som på sortert input. Randomized-Quicksort bytter et tilfeldig element inn som pivot. Da er hvert element med i O(lg⁡n)O(\lg n) delinger i forventning, så forventet kjøretid er Θ(nlg⁡n)\Theta(n \lg n) for enhver input.
Forventet kjøretid #
Snitt over algoritmens egne tilfeldige valg, for én fast instans. Skiller seg fra gjennomsnittstilfellet, som er et snitt over instanser, og fra amortisert kjøretid, som er et snitt over operasjonene i en følge.

05 Rangering i lineær tid

Sammenligningsbasert sortering #
Sortering som bare får informasjon om elementene gjennom parvise tester ai≤aja_i \le a_j. Insertion-Sort, Merge-Sort og Quicksort er sammenligningsbaserte; Counting-Sort, Radix-Sort og Bucket-Sort er det ikke.
Beslutningstre #
Modell for en sammenligningsbasert algoritme på nn elementer: hver indre node er en sammenligning med to utfall, hver løvnode en ferdig rekkefølge, og én kjøring er en sti fra rota. Sortering krever minst n!n! løvnoder, så høyden, antall sammenligninger i verste tilfelle, er minst lg⁡n!=Ω(nlg⁡n)\lg n! = \Omega(n \lg n).
Sorteringsgrensen #
Enhver sammenligningsbasert sorteringsalgoritme bruker Ω(nlg⁡n)\Omega(n \lg n) sammenligninger i verste tilfelle. Grensen sier ingenting om beste tilfelle, som kan være Θ(n)\Theta(n). Den smitter over på et annet problem bare gjennom en reduksjon fra sortering med kjøretid o(nlg⁡n)o(n \lg n).
Rang #
Det ii-ende minste elementet i en tabell har rang ii. Rang 1 er minimum, rang nn maksimum, og medianen har rang ⌊(n+1)/2⌋\lfloor (n+1)/2 \rfloor, den nederste av de to midterste når nn er partall.
Randomized-Select #
Finner elementet med rang ii som Quicksort med ett rekursivt kall: Randomized-Partition setter pivoten på plass qq med rang k=q−p+1k = q - p + 1 i segmentet. Er i=ki = k, er pivoten svaret; er i<ki < k, søkes rang ii blant de små, ellers rang i−ki - k blant de store. Forventet Θ(n)\Theta(n) for enhver input, Θ(n2)\Theta(n^2) i verste tilfelle.
Select #
Rangering i garantert Θ(n)\Theta(n). Pivoten er medianen av medianene til grupper på fem, funnet med et rekursivt kall, og minst 3n/103n/10 elementer havner på hver side av den. T(n)≤T(n/5)+T(7n/10)+Θ(n)=Θ(n)T(n) \le T(n/5) + T(7n/10) + \Theta(n) = \Theta(n). Gir også de kk minste elementene i lineær tid: finn rang kk og del rundt det.
Stabil sortering #
En sorteringsalgoritme er stabil når like nøkler står i samme innbyrdes rekkefølge i output som i input. Insertion-Sort, Merge-Sort og Counting-Sort er stabile; Quicksort er det ikke. Radix-Sort krever en stabil subrutine.
Counting-Sort #
Sorterer nn heltall i området 0..k0 .. k uten sammenligninger: tell forekomstene av hver verdi i CC, gjør CC kumulativ slik at C[v]C[v] er antall elementer ≤v\le v, og gå baklengs gjennom AA: trekk én fra C[A[j]]C[A[j]] og legg A[j]A[j] på den plassen i BB. Baklengs gjør den stabil. Θ(n+k)\Theta(n + k).
Radix-Sort #
Sorterer dd-sifrede tall stabilt på ett siffer om gangen, det minst signifikante først, med Counting-Sort som subrutine. Etter ii pass er tallene sortert på de ii siste sifrene; stabiliteten er induksjonssteget. Θ(d(n+k))\Theta(d(n + k)) når hvert siffer har k+1k + 1 verdier.
Bucket-Sort #
Antar input uniformt fordelt i [0,1)[0, 1). Legg A[j]A[j] i bøtte ⌊n⋅A[j]⌋\lfloor n \cdot A[j] \rfloor av nn, sorter hver bøtte med Insertion-Sort, og sett bøttene etter hverandre. Forventet Θ(n)\Theta(n) som et snitt over inputer, Θ(n2)\Theta(n^2) i verste tilfelle.

06 Rotfaste trestrukturer

Rotfast tre #
Et fritt tre, en sammenhengende graf uten sykler, med én node valgt som rot. Rota har ingen forelder, hver annen node har én, og nodene rett under en node er barna dens. En løvnode har ingen barn; de andre er indre noder. Dybden er antall kanter opp til rota, og høyden hh er den største dybden. Representeres med pekere til barna, eller med én peker til første barn og én til neste søsken.
Komplett binærtre #
Et binærtre der alle indre noder har to barn og alle løvnodene har samme dybde. Med høyde hh har det 2h2^h løvnoder og 2h−12^h - 1 indre noder, så n=2h+1−1n = 2^{h+1} - 1 noder i alt og h=⌊lg⁡n⌋h = \lfloor \lg n \rfloor.
Binært søketre #
Et binærtre med nøkler der alt i venstre deltre til en node er mindre enn eller lik noden og alt i høyre deltre større enn eller lik, for hver node. Søk, innsetting, minimum, maksimum, etterfølger og sletting følger én sti og koster O(h)O(h). Høyden er forventet Θ(lg⁡n)\Theta(\lg n) for tilfeldig innsettingsrekkefølge og n−1n - 1 i verste tilfelle; balanserte søketrær garanterer Θ(lg⁡n)\Theta(\lg n).
Inorder-Tree-Walk #
Besøker venstre deltre, så noden, så høyre deltre, rekursivt fra rota. I et binært søketre kommer nøklene ut i sortert rekkefølge. Θ(n)\Theta(n). Preorder og postorder behandler noden før eller etter de to rekursive kallene.
Tree-Insert #
Søker etter den nye nøkkelen til søket treffer nil, med en peker yy ett steg bak xx, og henger den nye noden på yy som venstre eller høyre barn. En ny node blir alltid en løvnode. O(h)O(h).
Etterfølger #
Noden med den minste nøkkelen som er større enn nøkkelen til xx, den neste i Inorder-Tree-Walk. Har xx et høyre deltre, er etterfølgeren minimum der; ellers er den den nærmeste noden over xx som har xx i sitt venstre deltre. Tree-Successor følger én sti, O(h)O(h). Forgjengeren finnes symmetrisk.
Haug #
Et binærtre som er komplett ned til nest nederste nivå, med det nederste fylt fra venstre, lagret i en tabell nummerert nivå for nivå: barna til ii er 2i2i og 2i+12i + 1, forelderen ⌊i/2⌋\lfloor i/2 \rfloor. Haugegenskapen for en maks-haug er A[Parent(i)]≥A[i]A[\text{Parent}(i)] \ge A[i] for alle ii unntatt rota, så det største elementet står i rota. En min-haug har ≤\le. Høyden er ⌊lg⁡n⌋\lfloor \lg n \rfloor.
Max-Heapify #
Reparerer en maks-haug der bare A[i]A[i] kan bryte haugegenskapen: bytt A[i]A[i] med det største barnet hvis det er større, og fortsett rekursivt der det mindre elementet havnet. Elementet synker høyst hh steg, O(lg⁡n)O(\lg n).
Build-Max-Heap #
Kaller Max-Heapify på de indre nodene fra ⌊n/2⌋\lfloor n/2 \rfloor ned til 1, nedenfra og opp, så begge deltrærne alltid er hauger når turen kommer til en node. Θ(n)\Theta(n), for de fleste nodene står langt nede og synker lite. Ikke det samme som nn kall til Max-Heap-Insert, som koster Θ(nlg⁡n)\Theta(n \lg n) i verste tilfelle.
Prioritetskø #
Dynamisk mengde med nøkler som prioriteter, gjerne med duplikater, som støtter Insert, Maximum, Extract-Max og Increase-Key, eller min-variantene. En maks-haug gir Maximum i Θ(1)\Theta(1) og de tre andre i O(lg⁡n)O(\lg n): Extract-Max flytter det siste elementet opp i rota og lar det synke, Increase-Key lar elementet stige, og Insert er Increase-Key fra −∞-\infty på en ny siste plass.
Heapsort #
Sortering ved utvelgelse med en maks-haug: bygg haugen av hele AA, og bytt så n−1n - 1 ganger rota med det siste elementet i haugen, minsk haugen og reparer rota med Max-Heapify. Sorterer på plass, Θ(nlg⁡n)\Theta(n \lg n) i verste tilfelle og Θ(n)\Theta(n) i beste, når alle elementene er like.

07 Dynamisk programmering

Dynamisk programmering #
Designmetode: rekursiv dekomponering der hvert delsvar lagres første gang det regnes ut og slås opp senere. Gir riktig svar når problemet har optimal delstruktur, og lønner seg når delinstansene overlapper. Løses med memoisering ovenfra og ned, eller iterativt nedenfra og opp i topologisk rekkefølge i delinstansgrafen.
Delinstansgraf #
Én node per forskjellig delinstans, og en kant fra uu til vv når svaret for vv bygger på svaret for uu. Må være asyklisk, og hver kjede av avhengigheter må ende i et grunntilfelle. Kalltreet til en rekursiv løsning har én node per sti i grafen som ender i instansen. Kjøretiden til dynamisk programmering er som regel lineær i antall noder og kanter.
Overlappende delinstanser #
Flere instanser bygger på den samme delinstansen, direkte eller indirekte. Skjer det på mange nivåer, blir en rekursiv løsning uten lagring eksponentiell. I splitt og hersk overlapper delinstansene ikke, så der gir lagring ingenting.
Optimal delstruktur #
En optimal løsning består av optimale løsninger på delinstansene. Vises som regel ved å bytte ut en del: var den ikke optimal, kunne den byttes ut og gi en bedre løsning. Korteste vei har egenskapen. Lengste enkle vei har den ikke, for to lengste delveier kan bruke de samme nodene.
Memoisering #
Rekursjon med hukommelse: første kall med et argument regner ut svaret og lagrer det, og senere kall med samme argument slår det opp. Løsningen ovenfra og ned (top-down) i dynamisk programmering. Løser bare delinstansene som faktisk trengs.
Lengste felles delsekvens #
Forkortet LCS. En lengste sekvens som er en delsekvens av både XX og YY, der en delsekvens er det som står igjen når null eller flere elementer strykes. LCS-Length fyller c[i,j]c[i, j] for prefiksene XiX_i og YjY_j rad for rad og lagrer en pil i bb, og Print-LCS følger pilene bakfra. Θ(mn)\Theta(mn).
Det binære ryggsekkproblemet #
Gjenstander med verdi viv_i og vekt wiw_i, og en kapasitet WW: velg gjenstander med størst mulig totalverdi og totalvekt høyst WW, der hver gjenstand er med eller ikke med. K[i,j]K[i, j] er det beste med gjenstandene 1,…,i1, \ldots, i og kapasitet jj, og er den største av verdien uten gjenstand ii og verdien med den. Θ(nW)\Theta(nW), som er pseudopolynomisk.
Pseudopolynomisk kjøretid #
Polynomisk som funksjon av et tall fra inputen, men ikke av inputstørrelsen i bits. Ryggsekkløsningen bruker Θ(nW)\Theta(nW), men WW tar bare m=⌊lg⁡W⌋+1m = \lfloor \lg W \rfloor + 1 bits, så kjøretiden er Θ(n2m)\Theta(n 2^m).

08 Grådighet

Grådighet #
Designmetode: gjør det valget som ser best ut her og nå, løs den ene delinstansen som er igjen, og sett valget og delløsningen sammen. Valget tas før noen delinstans er løst. Algoritmen er riktig når problemet har grådighetsegenskapen og optimal delstruktur.
Grådighetsegenskapen #
Det finnes en optimal løsning som tar det første grådige valget. Egenskapen sier bare at det første valget er trygt. At alle de grådige valgene er trygge, følger først sammen med optimal delstruktur, ved induksjon.
Utvekslingsargument #
Bevis for grådighetsegenskapen: ta en vilkårlig optimal løsning, bytt ut ett av valgene med det grådige, og vis at løsningen fortsatt er lovlig og ikke blir dårligere. Da finnes en optimal løsning med det grådige valget.
Det kontinuerlige ryggsekkproblemet #
Som det binære ryggsekkproblemet, men du kan ta med en andel mellom 0 og 1 av hver gjenstand og får samme andel av verdien. Løses grådig: fyll sekken etter synkende kilopris vi/wiv_i / w_i, så bare den siste gjenstanden blir delt. O(nlg⁡n)O(n \lg n) med sorteringen.
Aktivitetsutvalg #
Velg flest mulig aktiviteter [si,fi)[s_i, f_i) der ingen to overlapper. Det grådige valget er aktiviteten som slutter først, og delinstansen som er igjen, er aktivitetene som starter ved sluttiden dens eller senere. Greedy-Activity-Selector bruker Θ(n)\Theta(n) når aktivitetene er sortert etter sluttid.
Prefiksfri kode #
Binær kode der ingen kodeord er et prefiks av et annet, så en kodet tekst kan dekodes ett kodeord om gangen fra starten. Tegnes som et kodetre med tegnene i løvnodene: kodeordet er stien fra rota, med 0 for venstre og 1 for høyre barn, og lengden er dybden.
Huffman-kode #
En optimal prefiksfri kode, laget av Huffmans algoritme. Hvert tegn starter som et tre i en min-prioritetskø på frekvens, og n−1n - 1 ganger slås de to trærne med lavest frekvens sammen under en ny node med summen av frekvensene. O(nlg⁡n)O(n \lg n) med en binær haug.

09 Traversering av grafer

Nabolister #
Grafrepresentasjon med én liste per node: G.Adj[u]G.\mathit{Adj}[u] inneholder ut-naboene til uu. Tar Θ(V+E)\Theta(V + E) plass. Å gå gjennom naboene til uu tar tid proporsjonal med antallet, men å sjekke om (u,v)(u, v) er en kant krever et søk i lista. Standardvalget for traversering.
Nabomatrise #
Grafrepresentasjon som en ∣V∣×∣V∣|V| \times |V|-tabell der auv=1a_{uv} = 1 når (u,v)(u, v) er en kant. Tar Θ(V2)\Theta(V^2) plass uansett antall kanter, og svarer på om (u,v)(u, v) er en kant i konstant tid. Symmetrisk for en urettet graf.
Traverseringstre #
Treet som forgjengerkantene (v.π,v)(v.\pi, v) danner etter en traversering, med startnoden som rot. BFS gir et bredde-først-tre der stien fra rota er en korteste vei. DFS gir en dybde-først-skog med ett tre per kall fra hovedløkka.
Dybde-først-søk #
Forkortet DFS. Traversering som går videre fra den nyeste noden den har oppdaget: DFS-Visit kaller seg selv på hver hvite nabo med en gang. DFS starter fra hver hvite node etter tur og gir hver node en starttid u.du.d og en sluttid u.fu.f. Θ(V+E)\Theta(V + E).
Parentesteoremet #
I en dybde-først-skog er intervallene [u.d,u.f][u.d, u.f] og [v.d,v.f][v.d, v.f] enten disjunkte, eller så ligger det ene inni det andre, og da er den indre noden en etterkommer av den ytre. Skrives «(u» ved u.du.d og «u)» ved u.fu.f, blir parentesene riktig nøstet.
Hvit-sti-teoremet #
vv er en etterkommer av uu i en dybde-først-skog hvis og bare hvis det, da uu ble oppdaget, fantes en sti fra uu til vv med bare hvite noder.
Kantklassifisering #
DFS deler kantene i tre-kanter (i dybde-først-skogen), bakoverkanter (til en forfader), foroverkanter (til en etterkommer, utenfor treet) og krysskanter (alle andre). Kanten (u,v)(u, v) er en tre-kant hvis vv er hvit når den undersøkes, en bakoverkant hvis vv er grå, og en forover- eller krysskant hvis vv er svart. En rettet graf har en sykel hvis og bare hvis DFS finner en bakoverkant.
DAG #
Rettet asyklisk graf: en rettet graf uten sykler. Har en topologisk sortering, og DFS finner ingen bakoverkanter i den.
Topologisk sortering #
En rekkefølge av nodene i en DAG der uu kommer før vv for hver kant (u,v)(u, v). Topological-Sort kjører DFS og setter hver node først i en lenket liste når den blir ferdig, så lista blir sortert etter synkende sluttid. Θ(V+E)\Theta(V + E).
Sterke komponenter #
De største mengdene av noder i en rettet graf der hver node kan nå hver annen langs rettede stier. Kollapses hver komponent til én node, blir grafen en DAG. Strongly-Connected-Components kjører DFS på GG, og så DFS på GTG^{\mathrm T} med startnodene etter synkende sluttid: hvert tre er én komponent. Θ(V+E)\Theta(V + E).
Bredde-først-søk #
Forkortet BFS. Traversering med en FIFO-kø fra en startnode ss: nodene besøkes lag for lag, i stigende avstand. Gir v.d=δ(s,v)v.d = \delta(s, v), korteste vei målt i antall kanter, og et bredde-først-tre av forgjengerkanter. O(V+E)O(V + E).