odmierzanie czasu - przykład

Podobne dokumenty
Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

dynamiczny przydział pamięci calloc() memset() memcpy( ) (wskaźniki!! )

WYKŁAD 10. Zmienne o złożonej budowie Statyczne i dynamiczne struktury danych: lista, kolejka, stos, drzewo. Programy: c5_1.c, c5_2, c5_3, c5_4, c5_5

Uzupełnienie dot. przekazywania argumentów

Programowanie Proceduralne

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Wskaźniki. Programowanie Proceduralne 1

Wstęp. #define include include include include include include

Instrukcja wyboru, pętle. 2 wykład. Podstawy programowania - Paskal

Tablice, funkcje - wprowadzenie

WYKŁAD 9. Algorytmy sortowania elementów zbioru (tablic) Programy: c4_1.c... c4_3.c. Tomasz Zieliński

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Analiza algorytmów zadania podstawowe

Wstęp do programowania 1

Podstawy programowania w języku C++

Stałe i zmienne znakowe. Stała znakowa: znak

Języki programowania - podstawy

nowe operatory &. (kropka) * operator rzutowy ->, (przecinek) sizeof

WYKŁAD 8. Funkcje i algorytmy rekurencyjne Proste przykłady. Programy: c3_1.c..., c3_6.c. Tomasz Zieliński

Funkcja (podprogram) void

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.

Wykład 7 Abstrakcyjne typy danych słownik (lista symboli)

DYNAMICZNE PRZYDZIELANIE PAMIECI

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

Wykład 6_1 Abstrakcyjne typy danych stos Realizacja tablicowa i za pomocą rekurencyjnych typów danych

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Podstawowe algorytmy i ich implementacje w C. Wykład 9

funkcje rekurencyjne Wykład 12. Podstawy programowania (język C) Funkcje rekurencyjne (1) Funkcje rekurencyjne (2)

Pliki. Informacje ogólne. Obsługa plików w języku C

Język ludzki kod maszynowy

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

Struktury dynamiczne

Tablice w argumentach funkcji. Tablicy nie są przekazywane po wartości Tablicy są przekazywane przez referencje lub po wskaźniku

Wstęp do Programowania, laboratorium 02

Algorytm selekcji Hoare a. Łukasz Miemus

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

Wykład X. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2016 Janusz Słupik

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Podstawy Programowania C++

Laboratorium 6: Dynamiczny przydział pamięci. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Struktury czyli rekordy w C/C++

Dynamiczny przydział pamięci w języku C. Dynamiczne struktury danych. dr inż. Jarosław Forenc. Metoda 1 (wektor N M-elementowy)

Programowanie w VB Proste algorytmy sortowania

Zmienne, stałe i operatory

Pobieranie argumentów wiersza polecenia

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Programowanie Procedurale

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Termin Egzaminu (Język C): !!! >> CZWARTEK, 7 LUTEGO << GODZ

wykład II uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - funkcje, tablice i wskaźniki wykład II dr Jarosław Mederski Spis

Język C zajęcia nr 5

Wykład 5. Sortowanie w czasie liniowologarytmicznym

Zadanie 04 Ktory z ponizszych typow danych w jezyku ANSI C jest typem zmiennoprzecinkowym pojedynczej precyzji?

Programowanie w języku C++

Powyższe wyrażenie alokuje 200 lub 400 w zależności od rozmiaru int w danym systemie. Wskaźnik wskazuje na adres pierwszego bajtu pamięci.

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Programowanie i struktury danych

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania skrót z wykładów:

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

Programowanie strukturalne i obiektowe

Podstawy algorytmiki i programowania - wykład 3 Funkcje rekurencyjne Wyszukiwanie liniowe i binarne w tablicy

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

4. Tablica dwuwymiarowa to jednowymiarowa tablica wskaźników do jednowymiarowych tablic danego typu.

Podstawy algorytmiki i programowania - wykład 6 Sortowanie- algorytmy

Rozwiązanie. #include <cstdlib> #include <iostream> using namespace std;

iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

Wykład 1

Struktury. Przykład W8_1

Zmienne i struktury dynamiczne

Co nie powinno być umieszczane w plikach nagłówkowych:

ECLIPSE wnioski z dwóch pierwszych laboratoriów

Rekurencja. Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)!

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Algorytmy i. Wykład 5: Drzewa. Dr inż. Paweł Kasprowski

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Podstawy programowania. Wykład: 5. Instrukcje sterujące c.d. Stałe, Typy zmiennych c.d. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Podstawy programowania komputerów

int tab[5]; tab[1]; ciągły obszar pamięci, w którym umieszczone są elementy tego samego typu macierz [ ] - dwuargumentowy operator indeksowania

Wskaźniki w C. Anna Gogolińska

tablica: dane_liczbowe

Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Ćwiczenie 1. Podstawy. Wprowadzenie do programowania w języku C. Katedra Metrologii AGH

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Ćwiczenie nr 6. Poprawne deklaracje takich zmiennych tekstowych mogą wyglądać tak:

Podstawy Programowania Podstawowa składnia języka C++

Sortowanie - wybrane algorytmy

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

Dynamiczne struktury danych

Pliki. Informacje ogólne. Obsługa plików w języku C

Transkrypt:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <sys/times.h> #include <math.h> odmierzanie czasu - przykład int main() {int n; n=time(null); printf("\n n=%d\n",n); printf("\n ctime %s\n", ctime( (const time_t *) &n ) ); } /* koniec main */ 1

odmierzanie czasu - przykład n=1511227738 ctime Tue Nov 21 02:28:58 2017 2

errno kod błędu Większość funkcji bibliotecznych zwraca szczególną wartość dla zaznaczenia, że zawiodły. np. 1, zerowy wskaźnik NULL, stałą jak EOF itp.. Mówi to jednak tylko, że zdażył się błąd. Jaki? należy skontrolować jaki kod błędu został zapisany w errno. Zmienna erno jest zadeklarowana w errno.h. Kody błędu są przedstawione w opisach funkcji. Funkcje nie zmieniają wartości errno jeśli błędu nie było. Tym samym wartość errno po udanym zawołaniu funkcji niekoniecznie jest zero! Oczywiście po tym jak funkcja zakończyła się błędnie, można sprawdzić, co zapisane jest w errno; można także wyzerować errno przed zawołaniem funkcji. 3

errno #include <stdio.h> #include <stdlib.h> #include <errno.h> int n; main() { /* rmdir("testowa_kartoteka"); */ n=mkdir("testowa_kartoteka",0774); if(errno==eexist) printf("\n!! EEXIST=%d\n",EEXIST); printf("\n n=%d\n",n); exit(0); } /* koniec funkcji main*/ 4

errno #include <stdio.h> #include <stdlib.h> #include <errno.h> int main () { int k; k=unlink("out"); if(k == -1) perror ("unlink!!"); exit(0); } /* koniec funkcji main */ 5

void perror (const char *s); errno funkcja perror wypisuje komunikat na pliku stderr. Najpierw wypisany zostaje łańcuch znakowy s, następnie dwukropek i spacja. Następnie wypisywany jest komunikat, jest on zakończony znakiem \n (czyli znakiem nowej linii). 6

funkcja sync W nowoczesnych systemach operacyjnych operacje WE/WY nie są wykonywane synchronicznie, tzn. nawet jeśli np. write się skończyło, nie znaczy to,że dane zostały fizycznie zapisane na dysku. jeśli synchronizacja jest konieczna, można użyc specjalnych funkcji które powodują, że dane zostają zapisane np.. na dysku. #include <unistd.h> int sync (void) Po wywołaniu funkcji sterowanie nie zostanie zwrócone tak długo, jak długo dane nie zostaną zapisane na urządzeniu. Funkcja zwraca zero, jeśli nie było błędu. Oczywiście, nie wiadomo ile czasu sync będzie musiała zużyć na synchronizację danych. 7

funkcja fsync #include <unistd.h> int fsync (int deskryptor_pliku) Użycie funkcji fsync powoduje, że wszystkie dane związane z otwartym plikiem o deskryptorze deskryptor_pliku zastają zapisane na urządzeniu. Funkcja nie zwraca sterowania do miejsca skąd została wywołana, dopóki nie zakończy pozytywnie synchronizacji lub dopóki nie nastąpi błąd.funkcja zwraca zero jeśli nie było błędu, -1 jeśli był błąd. Ustawia zmienną errno w przypadku błędu. EBADF deskryptor pliku jest niepoprawny EINVAL synchronizacja nie jest możliwa gdyż system tego nie przewiduje 8

funkcje fstat i stat Te dwie funkcje umożliwiają uzyskanie informacji o pliku. Można np. odczytać jak wielki jest plik czy kiedy został utworzony. Prototypy tych funkcji są w <sys/stat.h> int stat(char *path, struct stat *buf), int fstat(int fd, struct stat *buf) stat(..) uzyskuje informacje o pliku którego nazwa jest wskazana przez path. fstat(..) czyni to samo, jako pierwszego argumentu używa deskryptora pliku taki jaki jest otrzymywany przy użyciu funkcji open (open otwiera plik do operacji niebuforowanych na nim) Obie funkcje zwracają wartość 0 w przypadku sukcesu, -1 w przypadku błedu (ustawiają także kody błędu w errno) 9

funkcje fstat i stat struct stat { off_t st_size; /* rozmiar pliku w bajtach pliku*/ time_t st_atime; /* czas ostatniego dostępu pliku*/ time_t st_mtime; /* czas ostatniej modyfikacji pliku*/ time_t st_ctime; /* czas ostatniej zmiany statusu pliku */ /* czas mierzony w sekundach od 00:01:00 UTC, Jan. 1, 1970 */ blkcnt_t st_blocks; /* liczba zaalokowanych bloków po 512 b*/ } 10

struktury danych wskaźnik zerowy NULL NULL 11

struktury danych lista jednokierunkowa 12

struktury danych drzewo lista jednokierunkowa węzeł główny, węzeł, rodzic, dziecko, liść, współczynnik rozgałęzienia 13

struktury danych-lista1 /* */ /* Przyklad: dynamiczne struktury danych w C */ #include <stdio.h> #define FALSE 0 typedef struct { int dataitem; struct listelement *link; } listelement; 14

struktury danych-lista2 void Menu (int *choice); listelement * Add (listelement * listpointer, int data); listelement * Remove (listelement * listpointer); void PrintQueue (listelement * listpointer); void ClearQueue (listelement * listpointer); 15

struktury danych-lista3 int main () { /* początek funkcji main */ listelement listmember, *listpointer; int data, choice; listpointer = NULL; 16

do { struktury danych-lista4 Menu (&choice); switch (choice) { case 1: printf ("Enter data item value to add "); scanf ("%d", &data); listpointer = Add (listpointer, data); break ; 17

struktury danych-lista5 case 2: if (listpointer == NULL) printf ("Queue empty!\n"); else listpointer = Remove (listpointer); break; 18

case 3: struktury danych-lista6 PrintQueue (listpointer); break; case 4: break; default: printf ("Invalid menu choice - try again\n"); break; } } while (choice!= 4); 19

ClearQueue (listpointer); struktury danych-lista7 } /* koniec funkcji main */ 20

struktury danych-lista8 void Menu (int *choice) { char local; printf ("\nenter\t1 to add item,\n\t2 to remove item\n\ \t3 to print queue\n\t4 to quit\n"); do { local = getchar (); if ((isdigit (local) == FALSE) && (local!= '\n')) { printf ("\nyou must enter an integer.\n"); } printf ("Enter 1 to add, 2 to remove, 3 to print, 4 to quit\n"); } while (isdigit ((unsigned char) local) == FALSE); *choice = (int) local - '0'; } /* koniec funkcji Menu */ 21

struktury danych-lista9 listelement * Add (listelement * listpointer, int data) { listelement * lp = listpointer; if (listpointer!= NULL) { while (listpointer -> link!= NULL) listpointer = (listelement *) listpointer -> link; listpointer -> link = (struct listelement *) malloc (sizeof (listelement)); listpointer = (listelement *) listpointer -> link; listpointer -> link = NULL; listpointer -> dataitem = data; } return lp; 22

struktury danych-lista10 else { listpointer = (listelement *) malloc (sizeof (listelement)); listpointer -> link = NULL; listpointer -> dataitem = data; return listpointer; } } /* koniec funkcji Add */ 23

struktury danych-lista11 listelement * Remove (listelement * listpointer) { listelement * tempp; printf ("Element removed is %d\n", listpointer -> dataitem); tempp = (listelement *) listpointer -> link; free (listpointer); return tempp; } /* koniec funkcji Remove */ 24

struktury danych-lista12 void PrintQueue (listelement * listpointer) { if (listpointer == NULL) printf ("queue is empty!\n"); else while (listpointer!= NULL) { printf ("%d\t", listpointer -> dataitem); listpointer = (listelement *) listpointer -> link; } printf ("\n"); } /* koniec funkcji PrintQueue */ 25

struktury danych-lista13 void ClearQueue (listelement * listpointer) { while (listpointer!= NULL) { listpointer = Remove (listpointer); } /* koniec pętli while */ } /* koniec funkcji ClearQueue */ 26

cechy struktur danych Mówiąc o strukturach danych ma się na myśli określone działania, czyli operacje, które można na nich wykonywać; przykładowo dla listy są to operacje wstawiania, usuwania, przeglądania i zliczania elementów listy. Struktura danych wraz z podstawowymi na niej operacjami nazywana jest abstrakcyjnym typem danych (listy, stosy, kolejki, drzewa, sterty...) 27

Algorytmy - wykorzystanie giętkości języka programowania -algorytmy pozwalają oderwać się od kodu, gdyż wiele złożonych problemów można podzielic na mniejsze części, dla których już istnieją przetestowane algorytmy postępowania (sortowanie, kodowanie,wyszukiwanie...) -błędnie uważa się, że postępowanie skomplikowane jest bardzo mądre; tymczasem najlepsze algorytmy zwykle są najprostsze. Niestety zwykle te najprostsze rozwiązania, algorytmy najtrudniej jest znaleźć...(na szczęście jest literatura) 28

Algorytmy Klasyfikacja algorytmów na osobnym zbiorze algorytmy.klasyfikacja.rtf 29

Sortowanie pęcherzykowe czyli bubble sort przykład: users.uj.edu.pl/~ufrudy/bubble1.c zdanie niektórych osób:...if you know what bubble sort is, wipe it from your mind; if you do not know, make a point of never finding out!... 30

bubble sort void bubblesort(int numbers[], int array_size) { int i, j, temp; for (i = (array_size - 1); i >= 0; i--) { for (j = 1; j <= i; j++) } { if (numbers[j-1] > numbers[j]) { temp = numbers[j-1]; } numbers[j-1] = numbers[j]; numbers[j] = temp; } } /* koniec funkcji bubblesort */ 31

Sortowanie przez wstawienie Sortowanie przez wstawianie jest jednym z najprostszych algorytmów sortowania. Nieodpowiedni w przypadku dużych zbiorów, gdyż określenie miejsca kolejnych elementów w zbiorze może wymagać wielokrotnego przejrzenia wszystkich elementów tam umieszczonych. Ale: ważną zaletą sortowania przez wstawianie jest to, że wstawienie pojedynczego elementu do już posortowanego pliku wymaga tylko jednokrotnego przejrzenia elementów, a nie powtórzenia całego algorytmu. Z tego powodu sortowanie przez wstawianie jest dobrym rozwiązaniem w przypadku sortowania przyrostowego. Przykład: rezerwacja miejsc w dużym hotelu. Przy zastosowaniu sortowania przez wstawianie wystarczy jeden raz przejrzeć listę. 32

#include <stdlib.h> #include <string.h> Sortowanie przez wstawienie (program) int issort(void *data, int size, int esize, int (*compare)(const void *key1, const void *key2)); /* wskaźnik do danych, ilość danych, rozmiar pojedynczej danej, nazwa funkcji która będzie porównywała pojedyncze dane */ int compare (const void * x, const void * y); 33

Sortowanie przez wstawienie (program) int issort(void *data, int size, int esize, int (*compare)(const void *key1, const void *key2)) { char *a = data; void int i, j; *key; /* Alokacja pamięci na element key. */ if ((key = (char *)malloc(esize)) == NULL) return -1; 34

Sortowanie przez wstawienie (program) /* Kolejne wstawianie elementu key między elementy posortowane.*/ for (j = 1; j < size; j++) { memcpy(key, &a[j * esize], esize); i = j - 1; /* Określenie polożenia, gdzie należy wstawić element key. */ while (i >= 0 && compare(&a[i * esize], key) > 0) { memcpy(&a[(i + 1) * esize], &a[i * esize], esize); i--; } memcpy(&a[(i + 1) * esize], key, esize); } 35

Sortowanie przez wstawienie (program) /* Zwolnienie pamięci zaalokowanej na potrzeby sortowania. */ free(key); return 0; } /* koniec funkcji issort */ 36

Sortowanie przez wstawienie (program) int compare (const void * x, const void * y) { int *a, *b; a=(int *) x; b=(int *) y; if( (*a) > (*b) ) return(1); else return(-1); } /* koniec funkcji compare */ 37

Sortowanie przez wstawienie (program) int main () { int n; int bak[6]={3,5,1,2,4,0}; for(n=0;n<6;++n) printf(" %d ", *(bak+n) ); printf("\n"); issort( bak, 6,4,compare); for(n=0;n<6;++n) printf(" %d ", *(bak+n) ); printf("\n"); } /* koniec funkcji main */ 38

Dziel Rządź - Złącz 39

sort złączenia ( Merge Sort ) cz. 1 #include <stdlib.h> #include <string.h> int mgsort(void *data, int size, int esize, int i, int k, int (*compare) (const void *key1, const void *key2)); static int merge(void *data, int esize, int i, int j, int k, int (*compare) (const void *key1, const void *key2)) { 40

sort złączenia ( Merge Sort ) cz. 2 char *a = data, *m; int ipos, jpos, mpos; /* inicjalizacja liczników złączania */ ipos = i; jpos = j + 1; mpos = 0; /* Rezerwacja pamięci na złączane elementy */ 41

sort złączenia ( Merge Sort ) cz. 3 if ((m = (char *) malloc(esize * ((k - i) + 1))) == NULL) return -1; /* Działamy, póki którakolwiek część ma elementy do złączania */ while (ipos <= j jpos <= k) { if (ipos > j) {/* W lewej części nie ma już elementów do złączania */ while (jpos <= k) { memcpy(&m[mpos * esize], &a[jpos * esize], esize); jpos++; mpos++; } 42

sort złączenia ( Merge Sort ) cz. 4 continue; } else if (jpos > k) {/* w prawej części nie ma już elementów do złączania */ while (ipos <= j) { } memcpy(&m[mpos * esize], &a[ipos * esize], esize); ipos++; mpos++; continue; } 43

sort złączenia ( Merge Sort ) cz. 5 /* Dołączenie do złączonych elementów następnego elementu */ if (compare(&a[ipos * esize], &a[jpos * esize]) < 0) { memcpy(&m[mpos * esize], &a[ipos * esize], esize); ipos++; mpos++; } 44

sort złączenia ( Merge Sort ) cz. 6 else { memcpy(&m[mpos * esize], &a[jpos * esize], esize); jpos++; mpos++; } } 45

sort złączenia ( Merge Sort ) cz. 7 /* Przygotowanie do przekazania z powrotem złączonych danych */ memcpy(&a[i * esize], m, esize * ((k - i) + 1)); /* Zwolnienie pamięci używanej na złączanie. */ free(m); return 0; } /* koniec funkcji merge */ 46

sort złączenia ( Merge Sort ) cz. 8 int mgsort(void *data, int size, int esize, int i, int k, int (*compare) (const void *key1, const void *key2)) { int j; /* Koniec rekurencji, kiedy niemożliwe są dalsze podziały */ if (i < k) { /* Ustalenie, gdzie należy podzielić elementy. */ j = (int)(((i + k - 1)) / 2); 47

sort złączenia ( Merge Sort ) cz. 9 /* Rekurencyjne sortowanie dwóch części */ if (mgsort(data, size, esize, i, j, compare) < 0) return -1; if (mgsort(data, size, esize, j + 1, k, compare) < 0) return -1; /* Złączanie dwóch posortowanych części w jeden zbiór posortowany */ } if (merge(data, esize, i, j, k, compare) < 0) return -1; return 0; } 48

sort złączenia ( Merge Sort ) cz. 10 int compare (const void * x, const void * y) { int *a, *b; a=(int *) x; b=(int *) y; if( (*a) > (*b) ) return(1); else return(-1); } /* koniec funkcji compare */ 49

sort złączenia ( Merge Sort ) cz. 11 /* program glówny testuje funkcję mgsort */ int main() { int a[5]; int n; int ktrl=-99;; srand(getpid()); for(n=0;n<5;++n) { a[n]=rand()%100; printf(" %d", *(a+n)); } 50

sort złączenia ( Merge Sort ) cz. 12 ktrl=mgsort(a, 5, sizeof(int), 0,4,compare); /* sortowanie!! */ printf("\n ktrl=%d",ktrl); printf("\n\n"); for(n=0;n<5;++n) { printf(" %d", *(a+n)); /* to elementy posortowane */ } exit(0); }/* koniec funkcji main */ 51

sort złączenia ( Merge Sort ) cz. 13 users.uj.edu.pl/~ufrudy/mgsorttest.c 52

algorytm sortowania QUICKSORT - algorytm Mergesort ma pewną wadę... - statystycznie dobrany punkt podziału - QUICKSORT - wady QUICKSORT; co jeśli punkt podziału jest dobrany niefortunnie? 53

QUICKSORT-1 #include <stdlib.h> #include <string.h> int issort(void *data, int size, int esize, int (*compare)(const void *key1, const void *key2));/* issort to sort przez wstawienie */ int compare (const void * x, const void * y); 54

QUICKSORT-2 static int compare(const void *int1, const void *int2) { /* Porównanie dwóch liczb całkowitych */ if (*(const int *)int1 > *(const int *)int2) return 1; else if (*(const int *)int1 < *(const int *)int2) return -1; else return 0; }/* koniec funkcji compare */ 55

QUICKSORT-3 static int partition(void *data, int esize, int i, int k, int (*compare) (const void *key1, const void *key2)) { char *a = data; void int *pval, *temp; r[3]; /* rezerwacja pamieci na wartosc podzialu i zamiane wartosci miejscami */ 56

QUICKSORT-4 if ((pval = malloc(esize)) == NULL) return -1; if ((temp = malloc(esize)) == NULL) { free(pval); return -1; } 57

QUICKSORT-5 /* Znalezienie wartosci podziału metodą potrójnej mediany */ r[0] = (rand() % (k - i + 1)) + i; r[1] = (rand() % (k - i + 1)) + i; r[2] = (rand() % (k - i + 1)) + i; issort(r, 3, sizeof(int), compare); /* sortowanie przez wstawienie */ memcpy(pval, &a[r[1] * esize], esize); 58

QUICKSORT-6 /* Utworzenie dwóch części wokół wartości podziału */ i--; k++; while (1) { /* Przechodzimy w lewo, aż znajdziemy element znajdujący się w niewłaściwej części */ do { k--; } while (compare(&a[k * esize], pval) > 0); 59

QUICKSORT-7 /* Przechodzimy w prawo, aż znajdziemy element znajdujący się w niewłaściwej części */ do { i++; } while (compare(&a[i * esize], pval) < 0); if (i >= k) { */ Koniec dzielenia, kiedy zetkną się liczniki lewy i prawy. */ break; } 60

QUICKSORT-8 else { /* Zamiana miejscami elementów z lewego i prawego licznika */ memcpy(temp, &a[i * esize], esize); memcpy(&a[i * esize], &a[k * esize], esize); memcpy(&a[k * esize], temp, esize); } } 61

QUICKSORT-9 /* Zwolnienie pamięci zarezerwowanej na podział */ free(pval); free(temp); /* Zwrócenie położenia dzielącego części */ return k; } /* koniec funkcji partition */ 62

QUICKSORT-10 int quicksort(void *data, int size, int esize, int i, int k, int (*compare) (const void *key1, const void *key2)) { int j; /* Jeśli niemożliwe dalsze podziały, koniec rekurencji */ if (i < k) { 63

QUICKSORT-11 /* Sprawdzenie, gdzie należy dokonać podziału */ if ((j = partition(data, esize, i, k, compare)) < 0) return -1; 64

QUICKSORT-12 /* Rekurencyjne sortowanie lewej części */ if (quicksort(data, size, esize, i, j, compare) < 0) return -1; /* Rekurencyjne sortowanie prawej części */ if (quicksort(data, size, esize, j + 1, k, compare) < 0) return -1; } return 0; }/* koniec funkcji quicksort */ 65

złożoność algorytmu (jak rośnie czas) sortowanie bąbelkowe O(n*n) sortowanie przez wstawienie O(n*n) sort złączenia O(n*log(n) ) quicksort O(n*log(n) ) sortowanie na stercie O(n*log(n) ) sortowanie ze zliczaniem O(n+k) (k-to największa liczba powiększona o jeden) sortowanie na bazie O(pn + pk) (k to baza, p to liczba cyfr w liczbach) 66

sortowanie ze zliczaniem szybki algorytm sortowania, który opiera się na zliczaniu wystąpień poszczególnych elementów w zbiorze. niestety, ma ograniczenia dotyczące danych a)sortować można jedynie liczby całkowite i dane dające się jako takie wyrazić b)trzeba znać największą liczbę występująca w danych (rezerwuje się odpowiednio dużą tablicę) 67

sortowanie ze zliczaniem - 1 #include <stdlib.h> #include <string.h> int ctsort(int *data, int size, int k) { /* size ile elementów, k największa wartość */ int *counts, *temp; int i, j; 68

sortowanie ze zliczaniem - 2 /* Alokacja pamięci na liczniki. */ if ((counts = (int *) malloc(k * sizeof(int))) == NULL) return -1; /* Alokacja pamięci na posortowane elementy. */ if ((temp = (int *)malloc(size * sizeof(int))) == NULL) return -1; 69

sortowanie ze zliczaniem - 3 /* Inicjalizacja liczników. */ for (i = 0; i < k; i++) counts[i] = 0; /* Zliczanie wystąpień poszczególnych elementów. */ for (j = 0; j < size; j++) counts[data[j]] = counts[data[j]] + 1; /* ++counts[ *(data+j) ]; */ /* ++(*( counts + (*(data+j)) )) ; */ 70

sortowanie ze zliczaniem - 4 /* Korekta poszczególnych liczników, aby zawierały liczbę poprzedzających je elementów */ for (i = 1; i < k; i++) counts[i] = counts[i] + counts[i - 1]; /* Użycie counts do położenia poszczególnych elementów w odpowiednie miejsca.*/ for (j = size - 1; j >= 0; j--) { temp[counts[data[j]] - 1] = data[j]; /* tu temp[] użyte */ } counts[data[j]] = counts[data[j]] - 1; 71

sortowanie ze zliczaniem - 5 /* Przygotowanie posortowanych danych do zwrócenia*/ memcpy(data, temp, size * sizeof(int));/* /*Zwolnienie pamięci użytej do sortowania */ return 0; free(counts); free(temp); } /* koniec funkcji ctsort */ 72

sortowanie ze zliczaniem - 6 int main() {int a[5]; int n; int ktrl=-99;; srand(getpid()); for(n=0;n<5;++n) { a[n]=rand()%100; printf(" %d", *(a+n)); /* wartości niesortowane */ } 73

sortowanie ze zliczaniem - 7 ktrl=ctsort(a, 5, 100); /* wywołanie f. sortującej */ printf("\n ktrl=%d",ktrl); printf("\n\n"); for(n=0;n<5;++n) { printf(" %d", *(a+n)); /* po przesortowaniu */ } }/* koniec funkcji main */ 74

sortowanie ze zliczaniem - 8 sortowanie ze zliczaniem to szybki algorytm sortowania czasu liniowego (chodzi o to, że jego tzw. złożoność jest O(n+k), gdzie n jest liczbą sortowanych liczb całkowitych, a k jest największą z tych liczb powiększoną o jeden 75

sortowanie ze zliczaniem - 9 Adres strony: users.uj.edu.pl/~ufrudy/ctsorttest.c 76

Sortowanie na bazie polega na sortowaniu fragmentów danych, ciągów cyfr, od cyfry najmniej znaczącej do najbardziej znaczącej; jeśli np. sortujemy zbiór liczb zapisanych w systemie dziesiętnym [15,12,49,16,36,40] po posortowaniu cyfr najmniej znaczących otrzymuje się [40,12,15,16,36,49] po posortowaniu cyfr bardziej znaczących [12,15,16,36,40,49] 77

Sortowanie na bazie w sortowaniu na bazie korzysta się z sortowania ze zliczeniem, dzięki czemu algorytm jest szybki 78

Sortowanie na stercie Heap Sort Zbiór n liczb tworzy stertę ( heap ), jeżeli jego elementy spełniają następujący związek: aj/2 a j/2 a j dla 1 j/2 < j n (j/2 oznacza dzielenie całkowitoprzecinkowe) 79

Sortowanie na stercie Heap Sort Kopiowanie na stercie - algorytm ten najpierw buduje stertę a następnie zdejmuje element ze szczytu sterty, powoduje to szereg awansów, następnie znowu zdejmuje element ze szczytu sterty, i tak dalej aż wszystkie elementy zostaną zdjęte czyli posortowane 80