Stakke, køer og lidt om hægtede lister

Relaterede dokumenter
Stakke, køer og lidt om hægtede lister - kapitel 16 og 17

Prioritetskøer ved»heap«, simulering

Træer. Datastrukturer & Algoritmer, Datalogi C Forelæsning 9/

Søgetræer: Generel repræsentation af (sorterede) mængder og funktioner Databasesystemer...

Introduktion til datastrukturer. Introduktion til datastrukturer. Introduktion til datastrukturer. Datastrukturer

Introduktion til datastrukturer

Introduktion til datastrukturer. Introduktion til datastrukturer. Introduktion til datastrukturer. Datastrukturer

Skriftlig eksamen i Datalogi

Introduktion til datastrukturer. Philip Bille

Skriftlig eksamen i Datalogi

Datastrukturer (recap)

02105 Eksamensnoter. Lasse Herskind S maj Sortering 3

Danmarks Tekniske Universitet

Binære søgetræer. Binære søgetræer. Nærmeste naboer. Nærmeste nabo

Om binære søgetræer i Java

Binære søgetræer. Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb. Philip Bille

Datastrukturer (recap) Datastruktur = data + operationer herpå

Danmarks Tekniske Universitet

Algoritmer og datastrukturer Course No Cheat Sheet May 15, 2012

Danmarks Tekniske Universitet

DM507 Algoritmer og datastrukturer

DM507 Algoritmer og datastrukturer

Binære søgetræer. Binære søgetræer. Nærmeste naboer. Nærmeste nabo

Prioritetskøer og hobe. Philip Bille

Abstrakte datatyper C#-version

1. Redegør for Lister, stakke og køer mht struktur og komplexitet af de relevante operationer

Rekursion og dynamisk programmering

DM507 Algoritmer og datastrukturer

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Vejledende løsninger

Danmarks Tekniske Universitet

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned.

Algoritmeanalyse. Øvre grænse for algoritme. Øvre grænse for problem. Nedre grænse for problem. Identificer essentiel(le) operation(er)

Invarianter. Invariant: Et forhold, som vedligeholdes af algoritmen gennem (dele af) dens udførelse. Udgør ofte kernen af ideen bag algoritmen.

Datastrukturer (recap)

Løsning af møntproblemet

Datalogi OB, Efterår 2002 OH er, forelæsning 10/ Klasser og nedarvning

Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

DM507 Algoritmer og datastrukturer

Danmarks Tekniske Universitet

Prioritetskøer. Prioritetskøer Træer og hobe Repræsentation af hobe Algoritmer på hobe Hobkonstruktion Hobsortering. Philip Bille

Hashing og hashtabeller

Divide-and-Conquer algoritmer

Danmarks Tekniske Universitet

Forelæsning Uge 5 Mandag

Prioritetskøer. Prioritetskøer. Prioritetskøer. Prioritetskøer

Orienterede grafer. Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer.

Sortering. Eksempel: De n tal i sorteret orden

Danmarks Tekniske Universitet

Sortering af information er en fundamental og central opgave.

Sortering. Eksempel: De n tal i sorteret orden

Grafer og grafalgoritmer

Prioritetskøer. Prioritetskøer. Prioritetskøer. Prioritetskøer

Divide-and-Conquer algoritmer

DANMARKS TEKNISKE UNIVERSITET

Orienterede grafer. Orienterede grafer. Orienterede grafer. Orienterede grafer

Orienterede grafer. Orienterede grafer. Orienterede grafer. Vejnetværk

16 Træer. Noter. Definition af et træ. Definitioner i tilknytning til træer. Repræsentation af træer. Binære træer. Den abstrakte datatype.

DM507 Algoritmer og datastrukturer

Software Construction 1. semester (SWC) januar 2014 Spørgsmål 1

DM507 Algoritmer og datastrukturer

Divide-and-Conquer algoritmer

BRP Sortering og søgning. Hægtede lister

DM507 Algoritmer og datastrukturer

Klasser og nedarvning

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

Sortering af information er en fundamental og central opgave.

Skriftlig eksamen i Datalogi

Danmarks Tekniske Universitet

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: n 2 n (log n) 2. 3 n /n 2 n + (log n) 4

BRP Tal. Om computer-repræsentation og -manipulation. Logaritmer

Danmarks Tekniske Universitet

Skriftlig eksamen i Datalogi

Grafer og grafalgoritmer

Design by Contract Bertrand Meyer Design and Programming by Contract. Oversigt. Prædikater

Danmarks Tekniske Universitet

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 23n log n. 4 n (log n) log n

Danmarks Tekniske Universitet

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: (logn) 7 n 1/2 2 n /n 3 2logn n 2 /logn

Divide-and-Conquer algoritmer

Hashing og hashtabeller

Programmeringscamp. Implementer funktionerne én for én og test hele tiden.

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 4 n n 3n n 2 /logn 5 n n (logn) 3n n 2 /logn 4 n n 5 n

Software Construction 1 semester (SWC) Spørgsmål 1

Forelæsning Uge 4 Torsdag

Forelæsning Uge 2 Torsdag

Syntaks og syntaksgenkendelse, særligt regulære udtryk og tilstandsmaskiner og lidt om anvendelser i bioinformatik

Sortering. De n tal i sorteret orden. Eksempel: Kommentarer:

Danmarks Tekniske Universitet

BRP Kursusintroduktion og Java-oversigt

DM02 Kogt ned. Kokken. Januar 2006

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Forelæsning Uge 4 Torsdag

Induktive og rekursive definitioner

DATALOGI 0GB. Skriftlig eksamen tirsdag den 6. januar 2004

Transkript:

Datastrukturer & Algoritmer, Datalogi C Forelæsning 4/11-2003 Henning Christiansen Stakke, køer og lidt om hægtede lister - kapitel 16 og 17 Hvorfor? Fundamentale datastrukturer man får brug for igen og igen Et indblik i Java Collections API Dagens program: Stakke eksempler på anvendelse implementation i Java vha. arrays Køer (nej, ikke sådan nogen, der siger muuuuuuuuuh) eksempler på anvendelse implementation i Java vha. cirkulært array Hægtede lister tungere end arrays men ultimativ fleksibilitet enkelthægtet dobbelthægtet Meget kort om priotitetskøer [specielt interesserede kan læse kap. 21] (1)

Datastrukturen en stak: Implementerer først-ind sidst-ud samling af objekter: Mindst følgende metoder void push(object x) lægger x på stakken Object topandpop() returnerer øverste element på stak. (kaldes andre steder ofte blot pop ) Forståelse af stak ud fra operationerne: push(a); push(b); topandpop() == b; topandpop() == a; Forståelse ud fra model: 3 4 2 2 2 2 2 push(2) push(3) topandpop() push(4) topandpop() topandpop() ==3 ==4 ==2 Velegnet til ting som er indlejret i hinanden: Rekursive metoder implementeres ved stak: metodekald: push plads til parametre og lokale variable returhop: pop, dvs. glemme alt om kald og gå tilbage til gammel tilstand Håndoptimering af rekursive metode: Ofte relevant hvis compiler spilder unødigt meget overhead på rekursive procedurekald: Vedligehold en lokal stak svarende til lokale variable og parametre God opgave: Afskaf rekursionen i quicksort mod at indføre en stak (2)

Anvendelse af stak til syntaksgenkendelse af programmeringssprog: Eksempel på grammatik med matchende paranteser (ingen operatorer): <udtryk> ::= 1 2 3... 9 ( udtryk ) { udtryk } <udtryk> <udtryk> Følgende er eksempel på udtryk (1 2) {4(5 6) {7} } Algoritme for genkendelse: t = læs_et_tegn(); while(true) { if(er_et_ciffer(t)) ; //skip else if(t== ) ) if(topandpop()!= ( ) fejl; else if(t== } ) if(topandpop()!= { ) fejl; else push(t); if (!flere-tegn-at-læse()) break; t = læs_et_tegn();}; if(stakken-er-tom) det_gik_godt; else det_gik_skidt; NB: kan også implementeres ved rekursion (3)

Anvendelse af stak: Enhver compiler benytter en regnestak At udregne 1 + 2*3*(4 + 5): push 1; push 2; push 3; mult; // push( topandpop() * topandpop() ) push 4; push 5; add; // push( topandpop() + topandpop() ) mult; // push( topandpop() * topandpop() ) add; // push( topandpop() + topandpop() ) // resultatet er på stakken I praksis: De øverste dele af stakken opbevares i regneregistre og resten i RAM Push, add, mult osv. findes som maskininstruktioner... men compilere producerer ofte mellemkode som ser ud som overfor (4)

Implementation af en generel stak i Java (jvf. bogen s. 514 ff) benytter et array som fordobles ved overløb public class ArrayStack implements Stack { public ArrayStack( ) {thearray = new Object[ DEFAULT_CAPACITY ]; topofstack = -1;} public boolean isempty( ) { return topofstack == -1;} public void makeempty( ) { topofstack = -1; } public Object top( ) { if( isempty( ) ) throw new UnderflowException( "ArrayStack top" ); return thearray[ topofstack ]; } public void pop( ) { if( isempty( ) ) throw new UnderflowException( "ArrayStack pop" ); topofstack--; } public Object topandpop( ) { if( isempty( ) ) throw new UnderflowException( "ArrayStack topandpop" ); return thearray[ topofstack-- ];} public void push( Object x ) { if( topofstack + 1 == thearray.length ) doublearray( ); thearray[ ++topofstack ] = x;} private void doublearray( ) { Object [ ] newarray; newarray = new Object[ thearray.length * 2 ]; for( int i = 0; i < thearray.length; i++ ) newarray[ i ] = thearray[ i ]; thearray = newarray;} private Object [ ] thearray; private int topofstack; private static final int DEFAULT_CAPACITY = 10; } (5)

Køer (simple kø; ikke prioritetskø som er noget andet) Implementerer først-ind først-ud samling af objekter: Mindst følgende metoder void enqueue(object x) stiller x i køen Object dequeue() returnerer forreste element i køen Forståelse af stak ud fra operationerne: enqueue(a); enqueue(b); dequeue() == a; dequeue() == b; Forståelse ud fra model: enqueue(a) enqueue(b); dequeue() == a dequeue() == b <> <a> <b,a> <b> <> tom forrest=bagest=a forrest=a forrest=bagerst=b forrest:? bagerst=b bagest.? Anvendelser: som hjælpere for andre algoritmer, f.eks. korteste vej, topologisk sortering simulering af fysisk kø afvikling af printerjobs datanetværk: ophobning af ikke modtagne pakker... (6)

Implementation ved cirkulært array: cirkulært hvordan vi tænker på det! public class ArrayQueue implements Queue { public ArrayQueue( ) { thearray = new Object[ DEFAULT_CAPACITY ]; makeempty( );} public void makeempty( ) { currentsize = 0; front = 0; back = -1; } public Object dequeue( ) {... } public void enqueue( Object x ) {...} private Object [ ] thearray; private int currentsize; private int front; private int back; private static final int DEFAULT_CAPACITY = 10;} (7)

Cirkulært array (8)

Implementation af metoder i Java public class ArrayQueue implements Queue { public ArrayQueue( ) {thearray = new Object[ DEFAULT_CAPACITY ]; makeempty( );} public boolean isempty( ) { return currentsize == 0;} public void makeempty( ) { currentsize = 0; front = 0; back = -1; } public Object dequeue( ) {if( isempty( ) ) throw new UnderflowException( "ArrayQueue dequeue" ); currentsize--; Object returnvalue = thearray[ front ]; front = increment( front ); return returnvalue; } private int increment( int x ) { if( ++x == thearray.length ) x = 0; return x; } public Object getfront( ) { if( isempty( ) ) throw new UnderflowException( "ArrayQueue getfront" ); return thearray[ front ];} public void enqueue( Object x ) { if( currentsize == thearray.length ) doublequeue( ); back = increment( back ); thearray[ back ] = x; currentsize++; } (9)

private void doublequeue( ) { Object [ ] newarray; newarray = new Object[ thearray.length * 2 ]; // Copy elements that are logically in the queue for( int i = 0; i < currentsize; i++, front = increment( front ) ) newarray[ i ] = thearray[ front ]; thearray = newarray; front = 0; back = currentsize - 1; } private Object [ ] thearray; private int currentsize; private int front; private int back; } private static final int DEFAULT_CAPACITY = 10; (10)

Hægtede lister, den grundlæggende idé: Fleksibel datastruktur, som kan implementere stakke, køer med videre med udvidede metoder Vigtigste egenskab: Der kan indsættes og slettes hvor som helst i listen Eksempel: class ListNode { Object element; ListNode next; public void ListNode(Object e, ListNode n) {element=e; next=n;} } At indsætte objekt x vilkårligt sted i listen udpeget ved reference current : current.next = new ListNode(x, current.next); At slette element efter current : current.next = current.next.next; (11)

Hægtede lister i Java (Collections API) NB: Bogens version, lidt anderledes end Collections! Kombinerer tre klasser: listeelementer: ListNodes som holder Object er LinkedListIterator (som ikke er en udvidelse af Iterator) o generaliseret position i listen LinkedList: En liste som selvstændigt objekt, o implementation List som er impl. af Collection class ListNode { public ListNode( Object theelement ) {this( theelement, null );} public ListNode( Object theelement, ListNode n ) { element = theelement; next = n;} public Object element; public ListNode next;} public class LinkedList { public LinkedList( ) {header = new ListNode( null );} // methods private ListNode header; } Tom liste: (12)

Formål med header-element: For at forenkle implementation af metoder: Den tomme liste ligner en hver anden liste, f.eks. indsættelse. Indsættelse... indsætte hvor? LinkedListIterator, krydsning mellem Iterator ~ den generaliserede for-sætning Listeposition for indsættelse og sletning m.v. public class LinkedListIterator { LinkedListIterator( ListNode thenode ) {current = thenode;} public boolean isvalid( ) {return current!= null;} public Object retrieve( ) {return isvalid( )? current.element : null;} public void advance( ) {if(isvalid()) current=current.next;} ListNode current; } public class LinkedList { public LinkedList() {... } public boolean isempty() {... } public LinkedListIterator zeroth(){return new LinkedListIterator(header);} public LinkedListIterator first(){return new LinkedListIterator(header.next);} public void insert( Object x, LinkedListIterator p ) { if( p!= null && p.current!= null ) p.current.next = new ListNode( x, p.current.next );} public LinkedListIterator find( Object x ) { ListNode itr = header.next; while( itr!= null &&!itr.element.equals( x ) ) itr = itr.next; return new LinkedListIterator( itr ); } public void remove( Object x ){ LinkedListIterator p = findprevious(x); // ref. to element before x if(p.current.next!= null) p.current.next = p.current.next.next; }} // Bypass deleted node (13)

Variationer: Dobbelthægtede lister: Fordel: Vi kan rykke iterator frem og tilbage på konstant tid Omkostning: Fylder en reference mere pr. knude; Indsætte, slette tager ca. 2 x længere tid. Sorterede lister SortedLinkedList extends LinkedList Udvider med metode insert( Comparable x), som (ifølge sagens natur) må tælle sig ca. halvvejs gennem listen Kombinerer listens fleksibilitet med fordelen ved at ting er sorteret; OBS: Binær søgning virker ikke :( Se bogens afsnit 17.5 og dokumentation for Javas Collections API for stort udvalg af metoder. (14)

Kort om prioritetskøer (kapitel 21) Til speciel interesserede: Nemmere at forstå, når vi har kigget på træer. En kø hvor elementerne indsættes vilkårligt og tages ud efter prioritet.»elementer«defineret som Comparable, og prioritetet bestemmes efter, hvilke der er»mindst«målt ved compareto void insert(comparable x ) Comparable deletemin( ) Comparable findmin( ) boolean isempty( ) void makeempty( ) int size( ) --> Insert x --> Return and remove smallest item --> Return smallest item --> Return true if empty; else false --> Remove all items --> Return size Ikke understøttet i bogens implementation: void decreasekey( p, v)--> Decrease value in p to v Implementation ved Binary Heap (DK: ofte en hob): Elegant repræsentation af binært træ i et array. (15)

Definition: Et fuldstændigt binært træ er lige dybt over det hele bortset fra nederste etage, som er fyldt fra venstre mod højre. 1 / \ / \ 2 3 / \ / \ 4 5 6 7 / \ / 8 9 10 Nummerering antyder mulig placering i array: - 1 2 3 4 5 6 7 8 9 10 venstre deltræ = * 2 højre deltræ = *2 +1 (Der er sgi da smart) over-knude = / 2 og rund ned Træet ovenfor er ikke en binær hob. Definition: En binær hob er et fuldstændigt binært træ hvor, for hver knude ved værdi k, er enhver værdi i undertræerne k. 23 / \ 38 117 Bemærk: en anden egenskab end det binære søgetræ 23 / \ 11 35 (16)

Eksempel på binær hob og repræsentation i array 13 / \ / \ 21 16 / \ / \ 24 31 19 68 / \ / 65 26 32-13 21 16 24 31 19 68 65 26 32 Tydeligvis ikke sorteret men en svagere egenskab, som er nemmere at vedligeholde Operationer: findmin() return array[1] :) deletemin() slette array[1] og ryste strukturen så egenskaben kommer på plads igen insert(x) placere i bunden og»rulle«op indtil pengene passer (17)

Afslutning: Tilsyneladende en stor rodebunke af datastrukturer som ligner hinanden!!! Hjælp, hvad gør vi? Overvej følgende spørgsmål? Hvilken overordnet strategi har vi brug for Stak? sidst-ind-først-ud Kø? Først-ind-først-ud Noget endnu mere fleksibelt, i retning af (dobbelt-hægtet) liste?... eller prioritetskø? Generel i forhold til valg af Collection eller klasser i det hele taget: Hvilke metoder har vi brug for? Hvilke metoder er tidskritiske?... sidder i den inderste løkke og kaldes igen og igen og igen? Hvilke kun en sjælden gang? (18)