9b. Gelinkte lijsten
2021-03-04
slides.com/jod/pt_9b
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
Centraal idee
- Gebruik aaneengelinkte nodes
- Elke node houdt één element bij, en een pointer bij naar de node met het volgende element
- De laatste node heeft NULL als volgende
- Speciale pointer kop wijst naar eerste node
typedef struct Node_tag {
char c;
struct Node_tag* volgende;
} Node;
Bvb. sequentie ['p', 'e', 't']
'p'
volgende
'e'
volgende
't'
volgende
NULL
kop
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Element toevoegen (vooraan)
Node* voegToe(Node* kop, char element){
Node* nieuw = (Node*) malloc(sizeof(Node));
nieuw->c = element;
nieuw->volgende = kop;
return nieuw;
}
int main(){
char* s = "pet";
Node* kop = NULL;
for(int i=2; i>=0; --i){
kop = voegToe(kop, s[i]);
}
// ...
}
kop
NULL
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Node* voegToe(Node* kop, char element){
Node* nieuw = (Node*) malloc(sizeof(Node));
nieuw->c = element;
nieuw->volgende = kop;
return nieuw;
}
int main(){
char* s = "pet";
Node* kop = NULL;
for(int i=2; i>=0; --i){
kop = voegToe(kop, s[i]);
}
// ...
}
kop
NULL
't'
volgende
NULL
Element toevoegen (vooraan)
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Node* voegToe(Node* kop, char element){
Node* nieuw = (Node*) malloc(sizeof(Node));
nieuw->c = element;
nieuw->volgende = kop;
return nieuw;
}
int main(){
char* s = "pet";
Node* kop = NULL;
for(int i=2; i>=0; --i){
kop = voegToe(kop, s[i]);
}
// ...
}
kop
NULL
't'
volgende
NULL
'e'
volgende
Element toevoegen (vooraan)
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Node* voegToe(Node* kop, char element){
Node* nieuw = (Node*) malloc(sizeof(Node));
nieuw->c = element;
nieuw->volgende = kop;
return nieuw;
}
int main(){
char* s = "pet";
Node* kop = NULL;
for(int i=2; i>=0; --i){
kop = voegToe(kop, s[i]);
}
// ...
}
kop
NULL
't'
volgende
NULL
'e'
volgende
'p'
volgende
Element toevoegen (vooraan)
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Vrijgeven
kop
?
'e'
volgende
't'
volgende
NULL
'p'
volgende
tmp
Node* geefVrij(Node* kop){
while(kop!=NULL){
Node* tmp = kop->volgende;
free(kop);
kop = tmp;
}
return NULL;
}
int main(){
// ...
kop = geefVrij(kop);
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Vrijgeven
kop
'e'
volgende
NULL
't'
volgende
NULL
tmp
Node* geefVrij(Node* kop){
while(kop!=NULL){
Node* tmp = kop->volgende;
free(kop);
kop = tmp;
}
return NULL;
}
int main(){
// ...
kop = geefVrij(kop);
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Vrijgeven
kop
'e'
volgende
NULL
't'
volgende
NULL
tmp
Node* geefVrij(Node* kop){
while(kop!=NULL){
Node* tmp = kop->volgende;
free(kop);
kop = tmp;
}
return NULL;
}
int main(){
// ...
kop = geefVrij(kop);
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Vrijgeven
kop
't'
volgende
NULL
tmp
Node* geefVrij(Node* kop){
while(kop!=NULL){
Node* tmp = kop->volgende;
free(kop);
kop = tmp;
}
return NULL;
}
int main(){
// ...
kop = geefVrij(kop);
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Vrijgeven
kop
't'
volgende
NULL
tmp
Node* geefVrij(Node* kop){
while(kop!=NULL){
Node* tmp = kop->volgende;
free(kop);
kop = tmp;
}
return NULL;
}
int main(){
// ...
kop = geefVrij(kop);
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Vrijgeven
NULL
tmp
kop
Node* geefVrij(Node* kop){
while(kop!=NULL){
Node* tmp = kop->volgende;
free(kop);
kop = tmp;
}
return NULL;
}
int main(){
// ...
kop = geefVrij(kop);
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Voorbeeld main
int main(){
char* s = "pet";
Node* kop = NULL;
for(int i=2; i>=0; --i){
kop = voegToe(kop, s[i]);
}
Node* tmp = kop;
while(tmp!=NULL){
printf("tmp->c: %c\n",tmp->c);
tmp = tmp->volgende;
}
kop = geefVrij(kop);
}
$ ./a.out
tmp->c: p
tmp->c: e
tmp->c: t
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Invoegen
void voegIn(Node* oud, Node* nieuw){
nieuw->volgende = oud->volgende;
oud->volgende = nieuw;
}
kop
'e'
volgende
't'
volgende
NULL
NULL
'p'
volgende
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Invoegen
void voegIn(Node* oud, Node* nieuw){
nieuw->volgend = oud->volgend;
oud->volgend = nieuw;
}
kop
'e'
volgende
't'
volgende
NULL
'p'
volgende
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Invoegen
void voegIn(Node* oud, Node* nieuw){
nieuw->volgend = oud->volgend;
oud->volgend = nieuw;
}
kop
'e'
volgende
't'
volgende
NULL
'p'
volgende
Maar twee operaties, onafhankelijk van lengte van lijst
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Verwijderen
kop
NULL
't'
volgende
NULL
'e'
volgende
'p'
volgende
n
teVerwijderen
void verwijderVolgende(Node* n){
if(n==NULL || n->volgende==NULL){
return; // geen volgende
}else{
Node* teVerwijderen = n->volgende;
n->volgende = teVerwijderen->volgende;
free(teVerwijderen);
}
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Verwijderen
kop
NULL
't'
volgende
NULL
'e'
volgende
'p'
volgende
teVerwijderen
void verwijderVolgende(Node* n){
if(n==NULL || n->volgende==NULL){
return; // geen volgende
}else{
Node* teVerwijderen = n->volgende;
n->volgende = teVerwijderen->volgende;
free(teVerwijderen);
}
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Verwijderen
kop
NULL
't'
volgende
NULL
'p'
volgende
teVerwijderen
Maar ~4 operaties, onafhankelijk van lengte van lijst
void verwijderVolgende(Node* n){
if(n==NULL || n->volgende==NULL){
return; // geen volgende
}else{
Node* teVerwijderen = n->volgende;
n->volgende = teVerwijderen->volgende;
free(teVerwijderen);
}
}
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Dubbelgelinkte lijst
- Dubbelgelinkte lijst: ook pointer bij naar vorige node
- Laat toe om in twee richtingen door lijst te lopen
typedef struct Node_tag{
Data data;
struct Node_tag* volgende;
struct Node_tag* vorige;
} Node;
'p'
volgende
vorige
'e'
volgende
vorige
't'
volgende
vorige
NULL
NULL
kop
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Circulaire lijst
- Eerste en laatste element verwijzen naar elkaar
- Geen vast begin- of eindpunt
- Kan zowel enkelgelinkt als dubbelgelinkt
typedef struct Node_tag{
Data data;
struct Node_tag* volgende;
struct Node_tag* vorige;
} Node;
'p'
volgende
vorige
'e'
volgende
vorige
't'
volgende
vorige
kop
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Samenvoegen circulaire lijsten
'p'
volgende
vorige
'i'
volgende
vorige
'n'
volgende
vorige
kop2
'p'
volgende
vorige
'e'
volgende
vorige
't'
volgende
vorige
kop1
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Samenvoegen circulaire lijsten
'p'
volgende
vorige
'i'
volgende
vorige
'n'
volgende
vorige
kop2
'p'
volgende
vorige
'e'
volgende
vorige
't'
volgende
vorige
kop1
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Samenvoegen circulaire lijsten
void voegSamen(Node* kop1, Node* kop2){
Node* begin1 = kop1;
Node* eind1 = kop1->vorige;
Node* begin2 = kop2;
Node* eind2 = kop2->vorige;
begin1->vorige = eind2;
eind2->volgende = begin1;
begin2->vorige = eind1;
eind1->volgende = begin2;
}
Maar 8 operaties, onafhankelijk van lengte van lijst
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Oefeningen
- Schrijf een keerOm procedure die de volgorde van de nodes in een gelinkte lijst omkeert
- Schrijf een swap procedure die twee nodes in een dubbel gelinkte lijst verwisselt van plaats
- Uitdaging: schrijf een swap voor een enkel-gelinkte lijst
// richting omkeren
void keerOm(Node* kop);
// omwisselen
void swap(Node* eerste, Node* tweede);
- Hoeveel stappen heb je nodig om een node met een bepaald element te vinden in de lijst?
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Samenvatting
- Gelinkte lijst bestaat uit aaneengelinkte nodes
- Elementen maken deel uit van node
- Toevoegen en verwijderen van elementen vereist constant aantal operaties
- Aantal operaties om twee circulair dubbelgelinkte lijsten samen te voegen is constant
9b. Gelinkte lijst
By Jo Devriendt
9b. Gelinkte lijst
- 504