datastruct1
TRANSCRIPT
Datastructuren 2014/15
docent: Hendrik Jan Hoogeboom kmr.162 071 527 7062 .
coordinatie: Nelleke Louwe Kooijmans assistentie: Bart Hijmans, Bart van Strien, Ivo Muusse
• tentamen • programmeeropgaven, in C++
www.liacs.nl/home/hoogeboo/dat/
boek
aanbevolen Adam Drozdek Data Structures and Algorithms in C++ 4th / International Edition ISBN13: 9781133613053
table of contents
1. object-oriented programming using C++ ⇒programmeermethoden
2. complexity analysis ⇒complexiteit
3. linked lists 4. stacks and queues 5. recursion 6. binary trees, heaps, … ⇒algoritmiek
etc.
verwante colleges
datastructuren3
algoritmiek*2
Complexiteit4
fund informatica 1 (discrete wiskunde)
concepten progtalen3
databases2
software engineering3
complexiteit sorteeralgoritmes
programmeermethoden1
abstract programmeren While ( S.boven >= 0 )
{ a = S.vakje[S.boven] ; S.boven-- ; … }
While ( not S.isleeg() ) { S.pop( a ) ; … }
× × ×
boven
vakje struct S
× × Λ × S
abstracte datastructuren
implementatie datastructuur niet zichtbaar in gebruik (in algoritme)
•wat doet de datastructuur •hoe is dat geimplementeerd
specificatie vastleggen ‘interface’
representatie keuze typen + definities
implementatie coderen methoden
tijd & ruimte: randvoorwaarden implementatie bibliotheken LEDA, STL standard
adt voorbeeld
R : reële getallen domein: R
operaties: 0, 1, +, -, *, /, =, …
abstract data type ~ class
adt voorbeeld
S : stapel van gehele getallen domein: geordende rijen elementen uit Z operaties:
init: S levert de lege rij () op.
isleeg: S B true bij lege rij, anders false.
push: S x Z S getal wordt vooraan in rij gezet.
pop: S S x Z voorste getal wordt verwijderd en terug- gegeven; ongedefinieerd bij lege rij.
top: S Z voorste getal wordt teruggegeven, maar niet verwijderd.
adt voorbeeld geeft de operaties en hun semantiek
maar niet de syntax in de progtaal legt een keuze vast: er is geen ‘unieke’ stapel ‘wat’ niet ‘hoe’
abstracte datatypen
elementen
domein
specificatie
implementatie
representatie
datastructuur
structuur
operaties
coderen
interface
gebruik
abstractie “OOP”
voordelen • preciese specificaties
gescheiden ontwikkeling
• modulariteit apart compileren: snel te wijzigen overdraagbaar header file
• afschermen informatie ‘hiding’ bv. 0-de element string integriteit: consistentie, correctheid
• overzichtelijkheid
• onafhankelijkheid implementatie
lokaal te wijzigen
‘encapsulation’
nivo’s van abstractie
♣ priority queue
•verzameling objecten met prioriteit •initialiseren, leeg-test, toevoegen, hoogste vinden, en verwijderen
♣ heap
complete boom met ‘heap-eigenschap’ trickle-up sift-down
♣ array
40 38 31 12 37 6 3
1 2 3 4 5 6 7 ..
vader(i) = i/2
bouwstenen + specie C++
bool pointer * char array [] int class / struct float dieptestructuur = == destructor ‘generiek’ programmeren:
– OOP object oriented programming – template <datatype>
templates
stapel van int, float, … ?
type parameters template <class T> class Stack { T storage[50]; … } Stack <int> intObject; Stack <float> floatObject; overloading, at compiletime
OOP
zie Programmeermethoden
Object data eigenschappen methoden gedrag Class ‘type’ van object Inheritance overerven eigenschappen + gedrag uit te breiden, aan te passen Polymorphism een object past zijn gedrag aan
u bent gewaarschuwd ! … class D af te leiden van een class B …
is een instantie van D ook een instantie van B ? … vraag … wordt niet gesteld … … onjuist en potentieel gevaarlijk … In de literatuur wemelt het van de gevallen waarin overerving misbruikt wordt: • een cirkel wordt van een punt afgeleid (een cirkel is geen speciaal geval van een punt); • een stack wordt van een lijst afgeleid (een stack is geen speciaal geval van een lijst).
klasse punt typedef int Coor; class Punt { public: // constructoren Punt(){ xx=0; yy=0; }; Punt( Coor x0, Coor y0 ) { xx=x0; yy=y0; }; // methoden void Schuif( Coor dx, Coor dy ); void Teken(); private: // data Coor xx, yy; };
void Punt::Schuif( Coor dx, Coor dy ) { xx += dx; yy += dy; }; void Punt::Teken() { cout << "punt(" << xx << "," << yy << ") "; };
methoden
klasse punt typedef int Coor; class Punt { public: // constructoren Punt(){ xx=0; yy=0; }; Punt( Coor x0, Coor y0 ) { xx=x0; yy=y0; }; // methoden void Schuif( Coor dx, Coor dy ); void Teken(); private: // data Coor xx, yy; };
void Punt::Schuif( Coor dx, Coor dy ) { xx += dx; yy += dy; }; void Punt::Teken() { cout << "punt(" << xx << "," << yy << ") "; };
Punt pt1, pt2(3,3) ; Animatie1( pt1 ); Animatie1( pt2 );
void Animatie1( Punt pt ) { pt.Teken(); pt.Schuif( 3, 6 ); cout << " naar "; pt.Teken(); cout << endl; };
punt(0,0) naar punt(3,6) punt(3,3) naar punt(6,9)
functie
main methoden
klasse cirkel // inheritance class Cirkel: public Punt { public: Cirkel() : Punt() { straal = 0; }; Cirkel( Coor x0, Coor y0, Coor str0) : Punt( x0, y0 ) { straal = str0; }; void Teken(); private: // naast xx, yy Coor straal; };
void Cirkel::Teken() { cout << "[" << straal << "]"; Punt::Teken(); };
methoden
klasse cirkel // inheritance class Cirkel: public Punt { public: Cirkel() : Punt() { straal = 0; }; Cirkel( Coor x0, Coor y0, Coor str0) : Punt( x0, y0 ) { straal = str0; }; void Teken(); private: // naast xx, yy Coor straal; };
void Cirkel::Teken() { cout << "[" << straal << "]"; Punt::Teken(); };
Cirkel ck1(3,3,2); Animatie1( ck1 ); Cirkel *ck2 = new Cirkel(3,0,3); Animatie1( *ck2 ); Punt *ck3 = new Cirkel(1,2,3); Animatie1( *ck3 );
// overloading void Animatie1( Cirkel ck ) { ck.Teken(); ck.Schuif( 3, 6 ); cout << " naar "; ck.Teken(); cout << endl; };
[2]punt(3,3) naar [2]punt(6,9) [3]punt(3,0) naar [3]punt(6,6) punt(1,2) naar punt(4,8)
functie
main
methoden
virtuele methoden
Punt *pt = new Punt(1,2), *ck = new Cirkel(3,3,2); Animatie2( *pt ); Animatie2( *ck );
void Animatie2( Punt & pt ) { pt.Teken(); pt.Schuif( 3, 6 ); cout << " naar "; pt.Teken(); cout << endl; };
punt(1,2) naar punt(4,8) [2]punt(3,3) naar [2]punt(6,9)
functie
main
•early vs. late binding •compile time vs. run time •nieuwe klassen •dynamische structuren
class Punt { .. virtual void Teken(); .. };
? by reference