9c. Stacks
2021-03-05
slides.com/jod/pt_9c
Docent: Jo Devriendt
Assistent: Ann Philips
Coördinator: Joost Vennekens
voornaam.achternaam@kuleuven.be
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Twee operaties
- Push: voeg toe aan het einde
- Pop: neem weg van het einde
void push(Stack* s, char c);
char pop(Stack* s);
element 1
element 2
element 3
element 4
element 5
frame 4
frame 4
frame 4
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Twee operaties
- Push: voeg toe aan het einde
- Pop: neem weg van het einde
void push(Stack* s, char c);
char pop(Stack* s);
element 1
element 2
element 5
element 4
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Implementatie via dynamische array
#define WAARDE char
typedef struct {
int lengte;
int gereserveerd;
WAARDE* waardes;
} Stack;
Stack create() {
Stack stk = {0, 0, NULL};
return stk;
}
void destroy(Stack* stk){
if(stk->waardes!=NULL){
free(stk->waardes);
stk->lengte = 0;
stk->gereserveerd = 0;
stk->waardes = NULL;
}
}
#define WAARDE char
typedef struct {
int lengte;
int gereserveerd;
WAARDE* waardes;
} Stack;
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Reserveer
void reserveer(Stack* stk, int k){
stk->waardes = realloc(stk->waardes, sizeof(WAARDE)*k);
stk->gereserveerd = k;
if(stk->lengte > k){
stk->lengte = k;
}
}
- Reserveer geheugen voordat het nodig is
- lengte is altijd hoogstens gereserveerd
- Bvb. gereserveerd==5, lengte==2
?
?
?
element 2
element 1
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Push
- Als dynamische array te klein is, reserveer meer geheugen
- Bewaar element op index lengte van de array
- Increment lengte
typedef struct {
int lengte; // 0
int gereserveerd; // 0
WAARDE* waardes; // NULL
} Stack;
initieel
void push(Stack* stk, WAARDE x){
if(stk->lengte==stk->gereserveerd){
reserveer(stk, 2*stk->lengte+1);
}
stk->waardes[stk->lengte]=x;
stk->lengte++;
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Push
- Als dynamische array te klein is, reserveer meer geheugen
- Bewaar element op index lengte van de array
- Increment lengte
typedef struct {
int lengte; // 1
int gereserveerd; // 1
WAARDE* waardes; // ...
} Stack;
na push(..., 'a');
'a'
void push(Stack* stk, WAARDE x){
if(stk->lengte==stk->gereserveerd){
reserveer(stk, 2*stk->lengte+1);
}
stk->waardes[stk->lengte]=x;
stk->lengte++;
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Push
- Als dynamische array te klein is, reserveer meer geheugen
- Bewaar element op index lengte van de array
- Increment lengte
?
'b'
'a'
typedef struct {
int lengte; // 2
int gereserveerd; // 3
WAARDE* waardes; // ...
} Stack;
na push(..., 'b');
void push(Stack* stk, WAARDE x){
if(stk->lengte==stk->gereserveerd){
reserveer(stk, 2*stk->lengte+1);
}
stk->waardes[stk->lengte]=x;
stk->lengte++;
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Push
void push(Stack* stk, WAARDE x){
if(stk->lengte==stk->gereserveerd){
reserveer(stk, 2*stk->lengte+1);
}
stk->waardes[stk->lengte]=x;
stk->lengte++;
}
- Als dynamische array te klein is, reserveer meer geheugen
- Bewaar element op index lengte van de array
- Increment lengte
'b'
'a'
typedef struct {
int lengte; // 3
int gereserveerd; // 3
WAARDE* waardes; // ...
} Stack;
na push(..., 'c');
'c'
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Pop
WAARDE pop(Stack* stk){
stk->lengte--;
WAARDE tmp = stk->waardes[stk->lengte];
if(stk->lengte<=stk->gereserveerd/2){
reserveer(stk,stk->gereserveerd/2);
}
return tmp;
}
- Decrement lengte
- Als meer gereserveerd wordt dan momenteel in gebruik, reserveer minder geheugen
'b'
'a'
typedef struct {
int lengte; // 3
int gereserveerd; // 3
WAARDE* waardes; // ...
} Stack;
na push(..., 'c');
'c'
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Pop
WAARDE pop(Stack* stk){
stk->lengte--;
WAARDE tmp = stk->waardes[stk->lengte];
if(stk->lengte<=stk->gereserveerd/2){
reserveer(stk,stk->gereserveerd/2);
}
return tmp;
}
- Decrement lengte
- Als veel meer gereserveerd wordt dan momenteel in gebruik, reserveer minder geheugen
?
'b'
'a'
typedef struct {
int lengte; // 2
int gereserveerd; // 3
WAARDE* waardes; // ...
} Stack;
na pop();
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Pop
WAARDE pop(Stack* stk){
stk->lengte--;
WAARDE tmp = stk->waardes[stk->lengte];
if(stk->lengte<=stk->gereserveerd/2){
reserveer(stk,stk->gereserveerd/2);
}
return tmp;
}
- Decrement lengte
- Als meer gereserveerd wordt dan momenteel in gebruik, reserveer minder geheugen
'a'
typedef struct {
int lengte; // 1
int gereserveerd; // 1
WAARDE* waardes; // ...
} Stack;
na pop();
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Voorbeeld main
void main() {
Stack stk = create();
Stack* sptr = &stk;
push(sptr,'h');
push(sptr,'e');
push(sptr,'l');
push(sptr,'l');
push(sptr,'o');
push(sptr,'\0');
printf("stk: %s\n", stk.waardes);
for(int i=0; i<3; ++i){
printf("pop: %c\n", pop(sptr));
}
push(sptr,'\0');
printf("stk: %s\n", stk.waardes);
destroy(sptr);
}
$ ./a.out
stk: hello
pop:
pop: o
pop: l
stk: hel
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Waarom factor 2?
void push(Stack* stk, WAARDE x){
if(stk->lengte==stk->gereserveerd){
reserveer(stk, 2*stk->lengte+1);
}
stk->waardes[stk->lengte]=x;
stk->lengte++;
}
WAARDE pop(Stack* stk){
stk->lengte--;
WAARDE tmp=stk->waardes[stk->lengte];
if(stk->lengte<=stk->gereserveerd/2){
reserveer(stk,stk->gereserveerd/2);
}
return tmp;
}
- realloc kopieert alle data: lineair aantal operaties - O(n)
- niet bij elke push of pop herhalen: reserveer meer dan nodig
- "Geamortiseerd" levert dit een constant aantal operaties per push/pop
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Oefening
- Implementeer stack m.b.v. dubbelgelinkte lijst
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Samenvatting
-
Stack is een lineaire datastructuur met twee operaties
- push
- pop
-
Implementatie kan met
- dubbelgelinkte lijst
- dynamische arrays
- reserveer meer geheugen dan strikt nodig om lineaire overhead te minimaliseren
9c. Stacks
By Jo Devriendt
9c. Stacks
- 529