Algorytmy i Struktury Danych. Liniowe struktury danych - Lista Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 5 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 1 / 40
Lista Lista - struktura danych, w których elementy sa ułożone w liniowym porzadku. Porzadek na liście określaja wskaźniki zwiazane z każdym elementem listy. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 2 / 40
Lista Lista - struktura danych, w których elementy sa ułożone w liniowym porzadku. Porzadek na liście określaja wskaźniki zwiazane z każdym elementem listy. Lista jedno- i dwukierunkowa - notacja wspólna head[l] - pierwszy element listy L. Jeżeli head[x]=nil to lista jest pusta. tail[l] - ostatni element listy L. key[x] - klucz znajdujacy się w węźle x. next[x] - następnik elementu x. Jeżeli next[x]=nil to x nie ma następnika, jest więc ostanim elementem listy (tzw. ogon). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 2 / 40
Lista Lista - struktura danych, w których elementy sa ułożone w liniowym porzadku. Porzadek na liście określaja wskaźniki zwiazane z każdym elementem listy. Lista jedno- i dwukierunkowa - notacja wspólna head[l] - pierwszy element listy L. Jeżeli head[x]=nil to lista jest pusta. tail[l] - ostatni element listy L. key[x] - klucz znajdujacy się w węźle x. next[x] - następnik elementu x. Jeżeli next[x]=nil to x nie ma następnika, jest więc ostanim elementem listy (tzw. ogon). Lista dwukierunkowa - notacja dodatkowa prev[x] - poprzednik elementu x. Jeżeli prev[x]=nil to x nie ma poprzednika, jest więc pierwszym elementem listy (tzw. głowa). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 2 / 40
Lista jedno- i dwu kierunkowa - schemat Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 3 / 40
Podstawowe operacje na listach Wyszukiwanie elementu na liście Dołaczanie elementu do listy Usuwanie elementu z listy Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 4 / 40
Wyszukiwanie elementu na liście Algorytm wyszukiwania elementu w liście jedno- i dwukierunkowej Cel: Wyszukanie elementu na liście; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 5 / 40
Wyszukiwanie elementu na liście Algorytm wyszukiwania elementu w liście jedno- i dwukierunkowej Cel: Wyszukanie elementu na liście; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Kryterium poszukiwania, np. wartość danej elementarnej; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 5 / 40
Wyszukiwanie elementu na liście Algorytm wyszukiwania elementu w liście jedno- i dwukierunkowej Cel: Wyszukanie elementu na liście; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Kryterium poszukiwania, np. wartość danej elementarnej; Algorytm: List-Search(L,k) 1: x := head[l]; 2: while (x!=nil and key[x]!=k) do 3: x := next[x]; 4: end while 5: return x; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 5 / 40
Wyszukiwanie elementu na liście Złożoność Procedura List-Search(L, k) wyznacza pierwszy element o kluczu k na liście L. Ponieważ niekiedy potrzebne jest przejście całej listy L, aby znaleźć element o kluczu k, to pesymistyczny czas działania procedury List-Search na liście o n elementach wynosi O(n). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 6 / 40
Wyszukiwanie elementu na liście jednokierunkowej - pewna implementacja Definicja listy jednokierunkowej typedef long T; typedef struct NODE { T value; struct NODE* next; } Node; typedef struct { Node* first; Node* last; } List; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 7 / 40
Wyszukiwanie elementu na liście jednokierunkowej - pewna implementacja Definicja funkcji Node* search(list const* L, T x); // zwraca wskaźnik do pierwszego wystąpienia // elementu x na liście L Node* search(list const* L, T x) { Node *p = L->first; while (p!= NULL) { if (p->value == x) { return p; } p = p->next; } return NULL; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 8 / 40
Wyszukiwanie elementu na liście dwukierunkowej - pewna implementacja Definicja listy dwukierunkowej typedef long T; typedef struct NODE { T value; struct NODE* next; struct NODE* prev; } Node; typedef struct { Node* first; Node* last; } List; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 9 / 40
Wyszukiwanie elementu na liście dwukierunkowej - pewna implementacja Definicja funkcji Node* search(list const* L, T x); // zwraca wskaźnik do pierwszego wystąpienia // elementu x na liście L Node* search(list const* L, T x) { Node *p = L->first; while (p!= NULL) { if (p->value == x) { return p; } p = p->next; } return NULL; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 10 / 40
Dołaczanie elementu do listy jednokierunkowej Algorytm wstawiania elementu do listy jednokierunkowej na poczatek Cel: Dołaczanie elementu do listy jednokierunkowej na poczatek; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 11 / 40
Dołaczanie elementu do listy jednokierunkowej Algorytm wstawiania elementu do listy jednokierunkowej na poczatek Cel: Dołaczanie elementu do listy jednokierunkowej na poczatek; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Dołaczany element; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 11 / 40
Dołaczanie elementu do listy jednokierunkowej Algorytm wstawiania elementu do listy jednokierunkowej na poczatek Cel: Dołaczanie elementu do listy jednokierunkowej na poczatek; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Dołaczany element; Algorytm: List-Insert-1-Begin(L,x) 1: next[x]:= head[l]; 2: head[l] := x; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 11 / 40
Dołaczanie elementu do listy jednokierunkowej na poczatek Złożoność Procedura List-Insert-1-Begin(L, x) przyłacza element x (dla którego pole key zostało wcześniej zainicjowane) na poczatek listy jednokierunkowej. Procedura List-Insert-1-Begin na liście o n elementach działa w czasie O(1). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 12 / 40
Dołaczanie elementu do listy jednokierunkowej - przykład Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 13 / 40
Dołaczanie elementu do listy jednokierunkowej na poczatek - pewna implementacja Definicja funkcji void push_front(list* L, T w); void push_front(list* L, T w) { Node* p = malloc(sizeof(node)); p->value = w; p->next = NULL; } if (L->first == NULL) { L->first = L->last = p; } else { p->next = L->first; L->first = p; } // lista pusta Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 14 / 40
Dołaczanie elementu do listy dwukierunkowej Algorytm wstawiania elementu do listy dwukierunkowej na poczatek Cel: Dołaczanie elementu do listy dwukierunkowej na poczatek; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 15 / 40
Dołaczanie elementu do listy dwukierunkowej Algorytm wstawiania elementu do listy dwukierunkowej na poczatek Cel: Dołaczanie elementu do listy dwukierunkowej na poczatek; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Dołaczany element; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 15 / 40
Dołaczanie elementu do listy dwukierunkowej Algorytm wstawiania elementu do listy dwukierunkowej na poczatek Cel: Dołaczanie elementu do listy dwukierunkowej na poczatek; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Dołaczany element; Algorytm: List-Insert-Begin(L,x) 1: next[x]:= head[l]; 2: if (head[l]!= NIL) then 3: prev[head[l]] := x; 4: end if 5: head[l] := x; 6: prev[x] := NIL; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 15 / 40
Dołaczanie elementu do listy dwukierunkowej na poczatek Złożoność Procedura List-Insert-Begin(L, k) przyłacza element x (dla którego pole key zostało wcześniej zainicjowane) na poczatek listy. Procedura List-Insert-Begin na liście o n elementach działa w czasie O(1). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 16 / 40
Dołaczanie elementu do listy dwukierunkowej - przykład Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 17 / 40
Dołaczanie elementu do listy dwukierunkowej na poczatek - pewna implementacja Definicja funkcji void push_front(list* L, T w); void push_front(list* L, T w) { // Zadanie na ćwiczenia // Napisz definicje!!! } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 18 / 40
Dołaczanie elementu do listy jednokierunkowej Algorytm wstawiania elementu do listy jednokierunkowej na koniec Cel: Dołaczanie elementu do listy jednokierunkowej na koniec; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 19 / 40
Dołaczanie elementu do listy jednokierunkowej Algorytm wstawiania elementu do listy jednokierunkowej na koniec Cel: Dołaczanie elementu do listy jednokierunkowej na koniec; Dane wejściowe: Położenie ostatniego elementu listy (np. wskaźnik na ten element); Dołaczany element; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 19 / 40
Dołaczanie elementu do listy jednokierunkowej Algorytm wstawiania elementu do listy jednokierunkowej na koniec Cel: Dołaczanie elementu do listy jednokierunkowej na koniec; Dane wejściowe: Położenie ostatniego elementu listy (np. wskaźnik na ten element); Dołaczany element; Algorytm: List-Insert-1-End(L,x) 1: if (tail[l]!= NIL) then 2: next[tail[l]] := x; 3: end if 4: tail[l] := x; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 19 / 40
Dołaczanie elementu do listy jednokierunkowej na koniec Złożoność Procedura List-Insert-1-End(L, k) przyłacza element x (dla którego pole key zostało wcześniej zainicjowane) na koniec listy jednokierunkowej. Procedura List-Insert-1-End na liście o n elementach działa w czasie O(1). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 20 / 40
Dołaczanie elementu do listy jednokierunkowej na koniec - przykład Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 21 / 40
Dołaczanie elementu do listy jednokierunkowej na koniec - pewna implementacja Definicja funkcji void push_back(list* L, T w); void push_back(list* L, T w) { Node* p = malloc(sizeof(node)); p->value = w; p->next = NULL; } if (L->first == NULL) { /* lista pusta */ L->first = L->last = p; } else { /* cos jest w liscie */ L->last->next = p; L->last = p; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 22 / 40
Dołaczanie elementu do listy dwukierunkowej Algorytm wstawiania elementu do listy dwukierunkowej na koniec Cel: Dołaczanie elementu do listy dwukierunkowej na koniec; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 23 / 40
Dołaczanie elementu do listy dwukierunkowej Algorytm wstawiania elementu do listy dwukierunkowej na koniec Cel: Dołaczanie elementu do listy dwukierunkowej na koniec; Dane wejściowe: Położenie ostatniego elementu listy (np. wskaźnik na ten element); Dołaczany element; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 23 / 40
Dołaczanie elementu do listy dwukierunkowej Algorytm wstawiania elementu do listy dwukierunkowej na koniec Cel: Dołaczanie elementu do listy dwukierunkowej na koniec; Dane wejściowe: Położenie ostatniego elementu listy (np. wskaźnik na ten element); Dołaczany element; Algorytm: List-Insert-End(L,x) 1: if (tail[l]!= NIL) then 2: next[tail[l]] := x; 3: end if 4: prev[x] := tail[l]; 5: tail[l] := x; 6: next[x] := NIL; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 23 / 40
Dołaczanie elementu do listy dwukierunkowej na koniec Złożoność Procedura List-Insert-End(L, k) przyłacza element x (dla którego pole key zostało wcześniej zainicjowane) na koniec listy. Procedura List-Insert-End na liście o n elementach działa w czasie O(1). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 24 / 40
Dołaczanie elementu do listy dwukierunkowej - przykład Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 25 / 40
Dołaczanie elementu do listy dwukierunkowej na koniec - pewna implementacja Definicja funkcji void push_back(list* L, T w); void push_back(list* L, T w) { // Zadanie na ćwiczenia // Napisz definicje!!! } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 26 / 40
Usuwanie elementu z listy jednokierunkowej Algorytm usuwania elementu z listy jednokierunkowej Cel: Usunięcie wskazanego elementu z listy jednokierunkowej; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 27 / 40
Usuwanie elementu z listy jednokierunkowej Algorytm usuwania elementu z listy jednokierunkowej Cel: Usunięcie wskazanego elementu z listy jednokierunkowej; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Element do usunięcia; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 27 / 40
Usuwanie elementu z listy jednokierunkowej Algorytm usuwania elementu z listy jednokierunkowej Cel: Usunięcie wskazanego elementu z listy jednokierunkowej; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Element do usunięcia; Algorytm: List-Delete-1(L,x) 1: if (x==head[l]) then 2: head[l] := next[x]; 3: else 4: y := head[l]; 5: while (next[y]!=x) do 6: y := next[y]; 7: end while 8: next[y]:= next[x]; 9: end if Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 27 / 40
Usuwanie elementu z listy jednokierunkowej Złożoność Procedura List-Delete-1 usuwa element x z listy L. Ponieważ niekiedy potrzebne jest przejście całej listy L, aby znaleźć element x, to pesymistyczny czas działania procedury List-Delete-1 na liście o n elementach wynosi O(n). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 28 / 40
Usuwanie elementu z listy jednokierunkowej Definicja funkcji void pop_1(list* L, T w); void pop_1(list* L, T w) { // Zadanie na ćwiczenia // Napisz definicje!!! } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 29 / 40
Usuwanie elementu z listy dwukierunkowej Algorytm usuwania elementu z listy dwukierunkowej Cel: Usunięcie wskazanego elementu z listy dwukierunkowej; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 30 / 40
Usuwanie elementu z listy dwukierunkowej Algorytm usuwania elementu z listy dwukierunkowej Cel: Usunięcie wskazanego elementu z listy dwukierunkowej; Dane wejściowe: Położenie pierwszego elementu listy (np. wskaźnik na ten element); Element do usunięcia; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 30 / 40
Usuwanie elementu z listy dwukierunkowej - Algorytm List-Delete-2(L,x) 1: if (x==head[l]) then 2: head[l] := next[x]; 3: prev[next[x]] := NIL; 4: else 5: y := head[l]; 6: while (next[y]!=x) do 7: y := next[y]; 8: end while 9: next[y]:= next[x]; 10: if (next[x]!= NIL) then 11: prev[next[x]] := y; 12: end if 13: end if Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 31 / 40
Usuwanie elementu z listy dwukierunkowej Złożoność Procedura List-Delete-2 usuwa element x z listy L. Ponieważ niekiedy potrzebne jest przejście całej listy L, aby znaleźć element x, to pesymistyczny czas działania procedury List-Delete-2 na liście o n elementach wynosi O(n). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 32 / 40
Usuwanie elementu z listy dwukierunkowej - przykład Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 33 / 40
Usuwanie elementu z listy dwukierunkowej Definicja funkcji void pop_2(list* L, T w); void pop_2(list* L, T w) { // Zadanie na ćwiczenia // Napisz definicje!!! } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 34 / 40
Usuwanie pierwszego elementu z listy jednokierunkowej - pewna implementacja Definicja funkcji void pop_front(list* L); void pop_front(list* L) { // jeden element lub lista pusta if (L->first == L->last) { free(l->first); L->first = L->last = NULL; } else { Node* p = L->first; L->first = p->next; free(p); } } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 35 / 40
Usuwanie pierwszego elementu z listy jednokierunkowej Złożoność Funkcja pop_front usuwa pierwszy element listy jednokierunkowej. Funkcja pop_front na liście o n elementach działa w czasie O(1). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 36 / 40
Usuwanie pierwszego elementu z listy dwukierunkowej - pewna implementacja Definicja funkcji void pop_front2(list* L); void pop_front2(list* L) { //Zadanie na ćwiczenia // Napisz definicje!!! } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 37 / 40
Usuwanie ostatniego elementu z listy jednokierunkowej - pewna implementacja Definicja funkcji void pop_back(list* L); void pop_back(list* L) { // jeden element lub lista pusta if (L->first == L->last) { free(l->first); L->first = L->last = NULL; } else { Node* p = L->first; // szukamy przedostatniego elementu listy while ((p->next)!= L->last) p=p->next; L->last = p; free(p->next); // i usuwamy go p->next = NULL; } } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 38 / 40
Usuwanie ostatniego elementu z listy jednokierunkowej Złożoność Funkcja pop_back usuwa ostatni element z listy jednokierunkowej. Ponieważ potrzebne jest przejście całej listy L, aby znaleźć przedostatni element listy L, to pesymistyczny czas działania funkcji pop_back na liście o n elementach wynosi O(n). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 39 / 40
Usuwanie ostatniego elementu z listy dwukierunkowej - pewna implementacja Definicja funkcji void pop_back2(list* L); void pop_back2(list* L) { //Zadanie na ćwiczenia // Napisz definicje!!! } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 5 40 / 40