Stos LIFO Last In First Out Operacje: push - dodanie elementu na stos pop - usunięcie elementu ze stosu empty - sprawdzenie, czy stos jest pusty size - zwrócenie liczby elementów na stosie value (peek) - zwrócenie ostatniego elementu na stosie
Implementacja tablicowa: int dane[6]; int rozmiar; void push() if (rozmiar>=5) cout << "Stos pelny!"; else cout<<endl<< "PUSH (jaka liczbe polozyc na stosie): "; rozmiar=rozmiar+1; cin>>dane[rozmiar]; void pop() if (rozmiar>=1) cout<<endl<<"pop - nastapi usuniecie ze stosu liczby: "<<dane[rozmiar]; rozmiar=rozmiar-1; else cout << "Stos pusty!"; void size() cout<<endl<<"liczba elementow na stosie: "<<rozmiar; void empty() if (rozmiar==0) cout<<endl<<"stos jest pusty"; else cout<<endl<<"stos nie jest pusty";
Implementacja na zmiennych dynamicznych: typedef struct stack int info; stack *previous; ; //zwraza aktualny początek (element najwyższy stosu) stack * push(stack * wskaznik_do_stosu,int element) stack * nowy=(stack *)malloc(sizeof(stack)); nowy->info=element; nowy->previous=wskaznik_do_stosu; return nowy; int pop(stack * &wskaznik_do_stosu) if(wskaznik_do_stosu==null) return -1; int returned_value=wskaznik_do_stosu->info; stack * t=wskaznik_do_stosu; wskaznik_do_stosu=wskaznik_do_stosu->previous; free(t); return returned_value; void wypisz_stos(stack * wskaznik_do_stosu) cout<<endl<<endl; stack *t=wskaznik_do_stosu; while(t!=null) cout<<"-------"<<endl; cout<<" "<<(t->info)<<" "<<endl; t=t->previous; cout<<"-------"<<endl;
Kolejka FIFO First In First Out Operacje: push_back (add, add_to_queue, enqueue ) - dodanie elementu na koniec kolejki pop_back (remove_from_queue, dequeue) usunięcie "obsłużenie" elementu z początku kolejki size - liczba elementów w kolejce first - wartość pierwszego elementu w kolejce last - wartość ostatniego elementu w kolejce
Implementacja tablicowa: int dane[5]; int ile; int glowa; int ogon; void push() if (ile>=5) cout << "Kolejka pelna!"; else if (ile==0) cout<<endl<< "PUSH (jaka liczbe wstawic do kolejki): "; cin>>dane[ogon]; ogon=ogon+1; ile=ile+1; else cout<<endl<< "PUSH (jaka liczbe wstawic do kolejki): "; cin>>dane[ogon]; ogon=(ogon+1)%5; ile=ile+1; void pop() if (ile==0) cout<<"kolejka jest pusta!"; else cout<<endl<<"pop - usuniecie z kolejki liczby: "<<dane[glowa]; glowa=(glowa+1)%5; ile=ile-1; void size() cout<<endl<<"liczba elementow w kolejce: "<<ile; void empty() if (ile==0) cout<<endl<<" kolejka jest pusta "; else cout<<endl<<" kolejka nie jest pusta "; Implementacja na zmiennych dynamicznych: ZADANIE DOMOWE DLA CHĘTNYCH!
Lista Operacje: push_front dodanie na początek push_back dodanie na koniec pop_front pobranie z początku pop_back pobranie z końca size rozmiar empty sprawdzenie, czy nie jest pusta remove usunięcie elementu (z początku, końca lub o podanym numerze) dodatkowo: sort - sortowanie reverse odwrócenie set ustawienie wartości elementu o podanym numerze add dodanie elementu po pozycji o danym numerze Implementacja praktycznie we wszystkich językach (STL::list w C++, ArrayList w Java.utils)
Drzewo binarne Drzewo (ang. tree) jest strukturą danych zbudowaną z elementów, które nazywamy węzłami (ang. node). Dane przechowuje się w węzłach drzewa. Węzły są ze sobą powiązane w sposób hierarchiczny za pomocą krawędzi (ang. edge), które zwykle przedstawia się za pomocą strzałki określającej hierarchię. Pierwszy węzeł drzewa nazywa się korzeniem (ang. root node). Od niego "wyrastają" pozostałe węzły, które będziemy nazywać synami (ang. child node). Synowie są węzłami podrzędnymi w strukturze hierarchicznej. Synowie tego samego ojca są nazywani braćmi (ang. sibling node). Węzeł nadrzędny w stosunku do syna nazwiemy ojcem (ang. parent node). Ojcowie są węzłami nadrzędnymi w strukturze hierarchicznej. Jeśli węzeł nie posiada synów, to nazywa się liściem (ang. leaf node), w przeciwnym razie nazywa się węzłem wewnętrznym (ang. internal node, inner node, branch node). Struktura drzewa A...H węzły drzewa strzałki krawędzie. Zwrot określa kierunek hierarchii rodzić dziecko. A korzeń drzewa B,C,D bracia, synowie węzła A, który jest dla nich ojcem E,F,G bracia, synowie węzła B, który jest dla nich ojcem H syn węzła D, który jest dla niego ojcem A,B,D węzły wewnętrzne C,E,F,G,H liście
Za wyjątkiem korzenia wszystkie pozostałe węzły w drzewie posiadają swojego ojca. W normalnym drzewie liczba synów dla dowolnego węzła nie jest ograniczona. Istnieje jednakże bardzo ważna klasa drzew, w których dany węzeł może posiadać co najwyżej dwóch synów. Noszą one nazwę drzew binarnych (ang. binary tree). Ciąg węzłów połączonych krawędziami nazwiemy ścieżką (ang. path). Od korzenia do określonego węzła w drzewie wiedzie zawsze dokładnie jedna ścieżka prosta, tzn. taka, iż zawarte w niej węzły pojawiają się tylko jeden raz. Długością ścieżki (ang. path length) nazwiemy liczbę krawędzi łączących węzły w ścieżce. Dla naszego drzewa mamy następujące ścieżki proste od korzenia do kolejnych węzłów: Długość ścieżki prostej od korzenia do danego węzła nazywa się poziomem węzła (ang. node level). Korzeń drzewa ma zawsze poziom 0. W powyższym drzewie węzły B, C i D mają poziom 1, a E, F, G i H mają poziom 2. Wysokość drzewa (ang. tree height) jest równa największemu poziomowi węzłów (lub najdłuższej ścieżce rozpoczynającej się w korzeniu). Dla drzewa z przykładu wysokość jest równa 2. Wysokość węzła (ang. node height), to długość najdłuższej ścieżki od tego węzła do liścia. Dla korzenia wysokość węzła jest równa wysokości drzewa: Drzewo, w którym węzły mogą posiadać co najwyżej dwóch synów, nazywa się drzewem binarnym (ang. binary tree, B-tree). Węzły potomne nazywamy odpowiednio synem lewym (ang. left child node) i synem prawym (ang. right child node). Za pomocą drzew binarnych pomocą można odwzorować również drzewa, których węzły posiadają dowolną liczbę synów. IN-ORDER to zarówno postać drzewa jak i sposób chodzenia po drzewie. Drzewo IN-ORDER, to takie, dla którego dla dowolnego węzła, wszyscy lewi synowie mają wartości mniejsze niż wartość węzła a wszyscy prawi synowie mają wartości większe niż wartość węzła. Sposób przechodzenia drzewa IN-ORDER, to taki sposób, że rekurencyjnie najpierw odwiedzamy lewe poddrzewo, potem węzeł a następnie prawe poddrzewo
typedef struct drzewo int info; drzewo *lewo,*prawo; ; drzewo * dodaj_do_drzewa(drzewo *korzen, int liczba) if (korzen!=null) if (korzen->info >= liczba) korzen->lewo=dodaj_do_drzewa(korzen->lewo,liczba); else korzen->prawo=dodaj_do_drzewa(korzen->prawo,liczba); else korzen=(drzewo *)malloc(sizeof(drzewo)); korzen->info=liczba; korzen->lewo=null; korzen->prawo=null; return korzen; void wypisz_drzewo(drzewo *korzen) if (korzen==null) return; wypisz_drzewo(korzen->lewo); printf("%d\n",korzen->info); wypisz_drzewo(korzen->prawo); void usun_drzewo(drzewo *korzen) if (korzen==null) return; usun_drzewo(korzen->lewo); usun_drzewo(korzen->prawo); free(korzen); ;
Sterta(Kopiec) Kopiec inaczej zwany stogiem jest szczególnym przypadkiem drzewa binarnego, które spełnia tzw. warunek kopca tzn. każdy następnik jest niewiększy od swego poprzednika. Z warunku tego wynikają szczególne własności kopca: w korzeniu kopca znajduje się największy lub jeden z grupy największych o identycznej wartości, na ścieżkach (połączeniach między węzłami), od korzenia do liścia, elementy są posortowane nierosnąco Kopiec zupełny to kopiec będący zupełnym drzewem binarnym. Drzewo binarne jest zupełne wtedy gdy wszystkie poziomy z wyjątkiem ostatniego są całkowicie zapełnione a na ostatnim liście są spójnie ułożone od strony lewej do prawej. Sortownie przez kopiec: #define maxheapsize 50 using namespace std; int heap[maxheapsize],heapsize; void insert(int element) heap[heapsize] = element; int i = heapsize; while(heap[(i+1)/2-1] < element && i>0) heap[i] = heap[(i+1)/2-1]; i = (i+1)/2-1; heap[i] = element;
void heapify (int i) int largest; int l=2*(i+1)-1, r=(2*i)+2; if (l<heapsize && heap[l]>heap[i])largest=l; else largest=i; if (r<heapsize && heap[r]>heap[largest])largest=r; if (largest!=i) swap(heap[largest],heap[i]); heapify(largest); int main() ifstream dane("dane.csv"); string wiersz; while(getline(dane,wiersz)) cout<<wiersz<<endl; string s; stringstream ss(wiersz); while(getline(ss,s,';')) cout<<s<<endl; if(heapsize==0) heap[0]=atoi(s.c_str()); else insert(atoi(s.c_str())); heapsize++; int end=1; cout<<"drukuję KOPIEC"<<endl; for(int i=0;i<4;i++) for(int j=end-1;j<2*end-1;j++) cout<<heap[j]<<" ; "; cout<<endl; end*=2; cout<<"długość: "<<heapsize<<endl; int number_of_elements=heapsize; for (int i=heapsize-1;i>0;i--) swap(heap[i],heap[0]); heapsize--; heapify(0); cout<<"liczby Posortowane: "; for(int i= 0;i< number_of_elements;i++) cout<<heap[i]<<" "; return 0;
Tablica asocjacyjna Tablica asocjacyjna jest nazywana także tablicą skojarzeniową. Przechowuje ona dane parami, każdej wartości przyporządkowuje odpowiedni klucz. Aby uzyskać dostęp do danej wartości trzeba znać nazwę jej klucza. Najpopularniejsza implementacja : tablica mieszająca, ( haszująca ), mapa mieszająca Najpopularniejsze implementacje: STL (C++) klasa map Java klasa HashMap