ΜΑΘΗΜΑ 11 ο

33
8-1 ΜΑΘΗΜΑ 11 ο Εισαγωγή στους Αλγόριθμους Ταξινόμησης

description

ΜΑΘΗΜΑ 11 ο. Εισαγωγή στους Αλγόριθμους Ταξινόμησης. ΕΙΣΑΓΩΓΗ ΣΤΗ ΤΑΞΙΝΟΜΗΣΗ. Ένας μεγάλος αριθμός προβλημάτων και αλγορίθμων που τα επιλύουν απαιτούν την ύπαρξη δεδομένων που έχουν ταξινομηθεί κατά κάποιο τρόπο - PowerPoint PPT Presentation

Transcript of ΜΑΘΗΜΑ 11 ο

Page 1: ΜΑΘΗΜΑ  11 ο

8-1

ΜΑΘΗΜΑ 11ο

Εισαγωγή στους Αλγόριθμους

Ταξινόμησης

Page 2: ΜΑΘΗΜΑ  11 ο

8-2

ΕΙΣΑΓΩΓΗ ΣΤΗ ΤΑΞΙΝΟΜΗΣΗ

• Ένας μεγάλος αριθμός προβλημάτων και αλγορίθμων που τα

επιλύουν απαιτούν την ύπαρξη δεδομένων που έχουν ταξινομηθεί

κατά κάποιο τρόπο

• Η πιο απλή μορφή ταξινόμησης είναι τα δεδομένα να ευρίσκονται σε

αύξουσα ή φθίνουσα μορφή σύμφωνα με συγκεκριμένα κριτήρια

• Το αντικείμενο αυτής της ενότητας μαθημάτων είναι η κατανόηση και

ανάλυση βασικών αλγορίθμων ταξινόμησης

Page 3: ΜΑΘΗΜΑ  11 ο

8-3

ΑΛΓΟΡΙΘΜΟΙ ΤΑΞΙΝΟΜΗΣΗΣ

• Οι αλγόριθμοι ταξινόμησης που θα εξετάσουμε είναι:

– Insertion Sort

– Bubble Sort

– Quick Sort

– Selection Sort

– Merge Sort

Page 4: ΜΑΘΗΜΑ  11 ο

8-4

INSERTION SORT

• Η ιδέα είναι δεδομένης μίας ακολουθίας Α να υπολογίσουμε μια

σειρά από ταξινομημένες ακολουθίες S0, S1, S2, …. Sn όπου:

– Η πρώτη ακολουθία είναι η S0 = {}

– Δεδομένης της ακολουθίας Si 0 ≤ i < n, η επόμενη ακολουθία Si+1

υπολογίζεται τοποθετώντας το (i + 1)th στοιχείο της μη ταξινομημένης

ακολουθίας Α στο σωστό σημείο της Si

Page 5: ΜΑΘΗΜΑ  11 ο

8-5

Ο Αλγόριθμος INSERTION SORT

void insertionSort(int arrayData[], arraySize)

{

int a; int b; int temp;

for(a=1; a<arraySize; a++)

b = a;

while(arrayData[b] < arrayData[b-1] && b >0) {

temp = arrayData[b-1];

arrayData[b-1] = arrayData[b];

arrayData[b] = temp;

b--;

}

}

}

Page 6: ΜΑΘΗΜΑ  11 ο

8-6

ΠΑΡΑΔΕΙΓΜΑ INSERTION SORTING

void insertionSort(int arrayData[], arraySize)

{

int a; int b; int temp;

for(a=1; a<arraySize; a++)

b = a;

while(arrayData[b] < arrayData[b-1] && b >0)

{

temp = arrayData[b-1];

arrayData[b-1] = arrayData[b];

arrayData[b] = temp;

b--;

}

}

}

3 3 1 4 1 5 9 2 6 5 4

3 1 1 4 1 5 9 2 6 5 4

1 3 44 1 5 9 2 6 5 4

1 3 4 1 1 5 9 2 6 5 4

1 1 3 4 55 9 2 6 5 4

1 1 3 4 5 99 2 6 5 4

1 1 3 4 5 9 22 6 5 4

1 1 2 3 4 5 9 66 5 4

1 1 2 3 4 5 6 9 55 4

1 1 2 3 4 5 5 6 9 44

1 1 2 3 4 4 5 5 6 9

a=1

a=2

a=3

a=4

a=5

a=6

a=7

a=8

a=9

Page 7: ΜΑΘΗΜΑ  11 ο

8-7

SELECTION SORT

• Το Selection Sort δουλεύει ώς εξής:

– Δεδομένης μίας ακολουθίας Α, κατασκευάζουμε την ταξινομημένη ακολουθία Τ, ένα στοιχείο κάθε φορά

– Εισάγουμε τα νέα στοιχεία στο σωστό σημείο

– Κάθε φορά, επιλέγουμε το νέο στοιχείο από αυτά που δεν έχουμε ακόμη επιλέξει από την Α

– Δηλαδή:για κάθε i κατ’ αύξουσα σειρά

βρες το μικρότερο των στοιχείων μετά το a[i]

αντιμετάθεσέ το με το a[i]

Page 8: ΜΑΘΗΜΑ  11 ο

8-8

Ο Αλγόριθμος SELECTION SORT

void StraightSelectionSort(int arrayData[], int arraySize) {

int i, j, temp; int max=0;

for (i=arraySize; i>1; i--) {

max = 0;

for(j=1; j<i, j++) {

if(arrayData[j] > arrayData[max])

max =j;

temp = arrayData[max];

arrayData[max] = arrayData[i-1];

arrayData[i-1] = temp;

}

Page 9: ΜΑΘΗΜΑ  11 ο

8-9

ΠΑΡΑΔΕΙΓΜΑ STRAIGHT SELECTION SORTING

void StraightSelectionSort(int arrayData[],

int arraySize) {

int i, j, temp; int max=0;

for (i=arraySize; i>1; i--) {

max = 0;

for(j=1; j<i, j++) {

if(arrayData[j] > arrayData[max])

max =j;

temp = arrayData[max];

arrayData[max] = arrayData[i-1];

arrayData[i-1] = temp;

}

3 1 4 1 5 99 2 6 5 4

3 1 4 1 5 4 2 6 5 9

3 1 4 1 5 4 2 5 6 9

3 1 4 1 5 4 2 5 6 9

3 1 4 1 2 4 5 5 6 9

3 1 4 1 2 4 5 5 6 9

3 1 2 1 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

i=10

i=9

i=8

i=7

i=6

i=5

i=4

i=3

i=2

Page 10: ΜΑΘΗΜΑ  11 ο

8-10

BUBBLE SORT

void bubbleSort(int arrayData[], int arraySize)

{

int i;

int j;

int temp;

for (i= arraySize, i > 1; i--)

for (j = 0; j < i - 1; j++)

if(array[j] > array[j+1])

temp = arrayData[j];

arrayData[j] = arrayData[j+1];

arrayData[j+1] = temp;

}

Page 11: ΜΑΘΗΜΑ  11 ο

8-11

ΠΑΡΑΔΕΙΓΜΑ BUBBLE SORTING

void bubbleSort(int arrayData[], int arraySize)

{

int i; int j; int temp;

for (i= arraySize, i > 1; i--)

for (j = 0; j < i - 1; j++)

if(array[j] > array[j+1])

temp = arrayData[j];

arrayData[j] = arrayData[j+1];

arrayData[j+1] = temp;

}

3 1 4 1 5 9 2 6 5 4

1 3 1 4 5 2 6 5 4 9

1 1 3 4 2 5 5 4 6 9

1 1 3 2 4 5 4 5 6 9

1 1 2 3 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

1 1 2 3 4 4 5 5 6 9

i=10

i=9

i=8

i=7

i=6

i=5

i=4

i=3

i=2

Page 12: ΜΑΘΗΜΑ  11 ο

8-12

QUICK SORT

• Δεδομένης της ακολουθίας (διανύσματος) Α = [α1, α2, α3, ...αν], το ζητούμενο είναι να την ταξινομήσουμε π.χ. με αύξουσα σειρά. Ο αλγόριθμος σκιαγραφείται ως εξής:

– Διαλέγουμε ένα στοιχείο p το οποίο ονομάζουμε pivot και p = ακ

– Αφαιρούμε το στοιχείο p, και χωρίζουμε την ακολουθία Α σε δύο υπο-ακολουθίες L και G, τέτοιες ώστε όλα τα στοιχεία στην L είναι μικρότερα του p, και όλα τα στοιχεία στην G, είναι μεγαλύτερα του p.

– Αναδρομικά, ταξινομούμε τις υπο-ακολουθίες L και G.

Page 13: ΜΑΘΗΜΑ  11 ο

8-13

Ο Αλγόριθμος QUICK SORT void QuickSort(int arrayData[], int left, int right) {

int i, j, p, temp;

i = left; j = right; p = arrayData((left+right)/2);

do {

while(arrayData[i] < p && i < right) i++;

while(p < arrayData[j] && j > left) j--;

if(i <=j) {

temp = arrayData[i];

arrayData[i] = arrayData[j];

arrayData[j] = temp;

i++;

j--;

}

}

while i <= j);

if(left <j)

QuickSort(arrayData, left, j);

if(i < right)

QuickSort(arrayData, i, right);

}

Page 14: ΜΑΘΗΜΑ  11 ο

8-14

ΠΑΡΑΔΕΙΓΜΑ QUICK SORTING

void QuickSort(int arrayData[], int left, int right) {

int i, j, p, temp;

i = left; j = right; p = arrayData[(left+right)/2];

do {

while(arrayData[i] < p && i < right) i++;

while(p < arrayData[j] && j > left) j--;

if(i <=j) {

temp = arrayData[i];

arrayData[i] = arrayData[j];

arrayData[j] = temp;

i++;

j--;

}

} while i <= j);

if(left <j)

QuickSort(arrayData, left, j);

if(i < right)

QuickSort(arrayData, i, right);

}

3 1 4 1 1 5 9 2 6

i=0, j=7, x=1

i=0, j=3

i=2, j=0

i=2, j=7, x=5

………

3 1 4 1 1 5 9 2 6

1 1 4 3 5 9 2 6

4 3 55 9 2 61 1

4 3 2 9 5 6

4 3 2 9 5 6

2 3 4 5 9 6

2 3 4

3 42 9 65

6 9

Page 15: ΜΑΘΗΜΑ  11 ο

8-15

MERGE SORT

• Για να ταξινομήσουμε μία ακολουθία Α από κ > 1 στοιχεία

δουλεύουμε ώς εξής:

– Χωρίζουμε την ακολουθία Α σε δύο «ίσα» μέρη

– Αναδρομικά ταξινομούμε τις υπο-ακολουθίες, και

– Ενοποιούμε τις δύο ταξινομημένες υπο-ακολουθίες

Page 16: ΜΑΘΗΜΑ  11 ο

8-16

Ο Αλγόριθμος MERGE SORT

void merge_sort (float v[], int start, int end)

{

int middle; /* the middle of the subarray */

if (start == end) return;

if (start == end - 1) return;

middle = (start + end) / 2;

merge_sort (v, start, middle);

merge_sort (v, middle, end);

merge (v, start, middle, end);

}

void merge (float v[], int start, int middle, int end) void merge (float v[], int start, int middle, int end) { { int v1_n, v2_n, v1_index, v2_index, i; int v1_n, v2_n, v1_index, v2_index, i; v1_n = middle - start; v1_n = middle - start; v2_n = end - middle; v2_n = end - middle; float v1[v1_n]; float v2[v2_n]; float v1[v1_n]; float v2[v2_n];

for (i=0; i<v1_n; i++) v1[i] = v[start + i]; for (i=0; i<v1_n; i++) v1[i] = v[start + i]; for (i=0; i<v2_n; i++) v2[i] = v[middle + i]; for (i=0; i<v2_n; i++) v2[i] = v[middle + i]; v1_index = 0; v2_index = 0; v1_index = 0; v2_index = 0; for (i=0; (v1_index < v1_n) && (v2_index < v2_n); i++) for (i=0; (v1_index < v1_n) && (v2_index < v2_n); i++) { { if (v1[v1_index] <= v2[v2_index]) if (v1[v1_index] <= v2[v2_index]) v[start + i] = v1[v1_index++]; v[start + i] = v1[v1_index++]; else else v[start + i] = v2[v2_index++]; v[start + i] = v2[v2_index++]; } } for (; v1_index < v1_n; i++) for (; v1_index < v1_n; i++) [start + i] = v1[v1_index++]; [start + i] = v1[v1_index++]; for (; v2_index < v2_n; i++) for (; v2_index < v2_n; i++) v[start + i] = v2[v2_index++]; v[start + i] = v2[v2_index++]; } }

Page 17: ΜΑΘΗΜΑ  11 ο

8-17

ΠΑΡΑΔΕΙΓΜΑ MERGE SORTING - 1

1 1 3 4 5

2 4 5 6 9

1 1 2 3 4 4 5 5 6 9

k

j

i

Two-way merging

Page 18: ΜΑΘΗΜΑ  11 ο

8-18

ΠΑΡΑΔΕΙΓΜΑ MERGE SORTING

3 1 4 1 5 9 2 6 5 4

3 1 4 1 5 9 2 6 5 4

3 1 4 1 5 9 2 6 5 4

3 1 4 1 5 9 2 6 5 4

1 3 1 5 2 9 5 4

1 5 4 5

1 4 5 4 5 6

1 1 3 4 5 2 4 5 6 9

1 1 2 3 4 4 5 5 6 9

Page 19: ΜΑΘΗΜΑ  11 ο

8-19

ΑΝΑΛΥΣΗ ΑΛΓΟΡΙΘΜΩΝ ΤΑΞΙΝΟΜΗΣΗΣ

• Η Ταξινόμηση είναι ένα από τα βασικά πρoβλήματα στην επιστήμη υπολογιστών (Computer Science)

• Υπάρχουν πολλοί αλγόριθμοι ταξινόμησης άλλοι απλοί (π.χ. Bubble sort) και άλλοι πολύπλοκοι (π.χ. Quick Sort, Heap sort)

• Οι περισσότεροι αλγόριθμοι ταξινόμησης μπορούν να εμπέσουν σε δύο κατηγορίες όσον αφορά την χρονική πολυπλοκότητα τους (σχέση με ταχύτητα εκτέλεσης τους και παραγωγής αποτελέσματος):

1. Αλγόριθμοι με πολυπλοκότητα Ο(n2) (bubble, insertion, selection, shell sort)

2. Αλγόριθμοι με πολυπλοκότητα Ο(n log(n)) (heap, quick, merge sort)

• Η χρονική πολυπλοκότητα που ορίζεται με την έκφραση Ο() είναι ένα μέτρο του πόσο γρήγορα εκτελεί ένας αλγόριθμος τη λειτουργία του σαν συνάρτηση του όγκου των δεδομένων που χρειάζεται

Page 20: ΜΑΘΗΜΑ  11 ο

8-20

ΑΝΑΛΥΣΗ ΑΛΓΟΡΙΘΜΩΝ ΤΑΞΙΝΟΜΗΣΗΣ

• Όπως είπαμε η πολυπλοκότητα είναι ένα χαρακτηριστικό στοιχείο ενός αλγόριθμου. Έχουμε χρονική πολυπλοκότητα (time complexity) και πολυπλοκότητα ανάγκης σε μνήμη (space complexity)

• Η κατηγοριοποίηση της πολυπλοκότητας (χρονικής ή απαραίτητης μνήμης) σε απλές μορφές (από την καλύτερη προς τη χειρότερη) είναι:

– Ο(1): Σταθερή (constant) χρονική (ή μνήμης) πολυπλοκότητα. Ο αλγλοριθμος παίρνει τον ίδιο χρόνο (ή μνήμη) να παράγει αποτέλεσμα ανεξάρτητα από τον όγκο των δεδομένων που επεξεργάζεται

– O(log(n)): Λογαριθμική (logarithmic) χρονική (ή μνήμης) πολυπλοκότητα. Ο χρόνος εκτέλεσης (ή η ανάγκες σε μνήμη) έχει τετραγωνική λογαριθμική σχέση με τον όγκο των δεδομένων

– O(log2 (n)): Λογαριθμική (logarithmic) χρονική (ή μνήμης) πολυπλοκότητα. Ο χρόνος εκτέλεσης (ή η ανάγκες σε μνήμη) έχει λογαριθμική σχέση με τον όγκο των δεδομένων

– Ο(n): Γραμμική (linear) χρονική (ή μνήμης) πολυπλοκότητα. Ο χρόνος εκτέλεσης (ή η ανάγκες σε μνήμη) έχει γραμμική σχέση με τον όγκο των δεδομένων

– Ο(n log(n)): Γραμμικά-λογαριθμική (n log(n) ) χρονική (ή μνήμης) πολυπλοκότητα. Ο χρόνος εκτέλεσης (ή η ανάγκες σε μνήμη) έχει σχέση με τον όγκο των δεδομένων που δίδεται από τη συνάρτηση n log(n)

– Ο(n2): Τετραγωνική (quadratic) χρονική (ή μνήμης) πολυπλοκότητα. Ο χρόνος εκτέλεσης (ή η ανάγκες σε μνήμη) έχει τετραγωνική σχέση με τον όγκο των δεδομένων

– O(n3): Κυβική (cubic) χρονική (ή μνήμης) πολυπλοκότητα. Ο χρόνος εκτέλεσης (ή η ανάγκες σε μνήμη) έχει κυβική σχέση με τον όγκο των δεδομένων

– Ο(2n): Εκθετική (exponential) χρονική (ή μνήμης) πολυπλοκότητα. Ο χρόνος εκτέλεσης (ή η ανάγκες σε μνήμη) έχει εκθετική σχέση με τον όγκο των δεδομένων

Page 21: ΜΑΘΗΜΑ  11 ο

8-21

ΑΝΑΛΥΣΗ ΑΛΓΟΡΙΘΜΩΝ ΤΑΞΙΝΟΜΗΣΗΣ

• Για να δούμε τη διαφορά μεταξύ των διαφόρων κατηγοριών πολυπλοκότητας ας θεωρήσουμε ότι έχουμε να ταξινομήσουμε 100, και 1000 στοιχεία

• Ένας αλγόριθμος γραμμικής σταθερής πολυπλοκότητας θα πάρει περίπου 1 χρονική μονάδα να παράγει αποτέλεσμα και για τα 100 και για τα 1000 στοιχεία

• Ένας αλγόριθμος λογαριθμικής χρονικής πολυπλοκότητας θα πάρει περίπου 2 χρονικές μονάδες να παράγει αποτέλεσμα για τα 100 στοιχεία, και 3 χρονικές μονάδες να παράγει αποτέλεσμα για τα 1000 στοιχεία

• Ένας αλγόριθμος γραμμικής χρονικής πολυπλοκότητας θα πάρει περίπου 100 χρονικές μονάδες να παράγει αποτέλεσμα για τα 100 στοιχεία και 1000 μονάδες για τα 1000 στοιχεία

• Ένας αλγόριθμος τετραγωνικής χρονικής πολυπλοκότητας θα πάρει περίπου 10.000 χρονικές μονάδες να παράγει αποτέλεσμα για τα 100 στοιχεία και 1.000.000 για τα 1000 στοιχεία

• Ένας αλγόριθμος κυβικής χρονικής πολυπλοκότητας θα πάρει περίπου 1.000.000 χρονικές μονάδες να παράγει αποτέλεσμα για τα 100 στοιχεία και 1.000.000.000 για τα 1000 στοιχεία

• Ένας αλγόριθμος εκθετικής πολυπλοκότητας θα πάρει περίπου 1.267.650.600.228.229.401.496.703.205.376 χρονικές μονάδες να παράγει αποτέλεσμα για τα 100 στοιχεία και 1.07150860718626732094842504906e+301 για 1000 στοιχεία

• Εάν ένας αλγόριθμος παίρνει πάνω από ένα τύπο δεδομένων σαν είσοδο μπορούμε να έχουμε εκφράσεις πολυπλοκότητας της μορφής Ο(n m) ή O(n logm) όπου n, m είναι το πλήθος των δύο τύπων των δεδομένων αντίστοιχα

Page 22: ΜΑΘΗΜΑ  11 ο

8-22

ΕΜΠΕΙΡΙΚΑ ΔΕΔΟΜΕΝΑ

Αλγόριθμοι Ταξινόμησης με τετραγωνική Πολυπλοκότητα (O n2)

Αλγόριθμοι Ταξινόμησης με γραμμικά λογαριθμικήΠολυπλοκότητα O(n log(n))

Page 23: ΜΑΘΗΜΑ  11 ο

8-23

Insertion Sort

• Γενικά: Ο αλγόριθμος βάζει σε

κάθε βήμα ένα στοιχείο από την

αρχική (μη ταξινομημένη) λίστα στη

σωστή του θέση στη τελική

ταξινομημένη λίστα

• Υπέρ: Εύκολος στην υλοποίηση

• Κατά: Αργός για μεγάλες λίστες

Page 24: ΜΑΘΗΜΑ  11 ο

8-24

Insertion Sort

• Χρήση: Είναι ένας αλγόριθμος «μέσης-λύσης» που είναι καλός για ταξινόμηση μερικών χιλιάδων δεδομένων. Ο insertion sort είναι περίπου δύο φορές πιο γρήγορος από τον bubble sort και περίπου 40% πιο γρήγορος από τον selection sort. O insertion sort δεν ενδείκνυται να χρησιμοποιείται για την ταξινόμηση περισσότερων από δύο χιλιάδες στοιχεία ή για την διαδοχική και επαναληπτική ταξινόμηση λιστών με περισσότερα από μερικές εκατοντάδες στοιχείων

Page 25: ΜΑΘΗΜΑ  11 ο

8-25

Selection Sort

• Γενικά: Ο αλγόριθμος βάζει σε κάθε βήμα βρίσκει το μικρότερο (ή μεγαλύτερο) στοιχείο που έχει μείνει στην αρχική λίστα, και το βάζει σαν επόμενο στοιχείο στην τελική λίστα

• Υπέρ: Εύκολος στην υλοποίηση

• Κατά: Αργός για μεγάλες λίστες

• Χρήση: Είναι ένας αλγόριθμος πολύ παρόμοιος με τον insertion sort, αλλά πιο αργός οπότε ο insertion sort είναι καλύτερη επιλογή. Ο selection sort είναι περίπου 60% πιο γρήγορος από τον bubble sort (όμως θυμηθείτε ότι ο insertion sort είναι 100% πιο γρήγορος από τον bubble sort). Γενικά δεν υπάρχει καλός λόγος να προτιμήσουμε τον selection sort αλλά εάν θελήσουμε να τον χρησιμοποιήσουμε δεν πρέπει να τον χρησιμοποιήσουμε για ταξινόμηση περισσότερων από 1000 στοιχεία ή γα την επαναλυπτική ταξονόμηση λιστών με περισσότερα από 200 στοιχεία.

Page 26: ΜΑΘΗΜΑ  11 ο

8-26

Bubble Sort

• Γενικά: Ο αλγόριθμος βάζει σε κάθε βήμα βρίσκει ελέγχει εάν το επόμενό του στοιχείο είναι μικρότερο (ή μεγαλύτερο) και εναλλάσσονται εάν χρειάζεται

• Υπέρ: Εύκολος στην υλοποίηση

• Κατά: Πολύ αργός για μεσαίες και μεγάλες λίστες.

• Χρήση: Είναι ένας αλγόριθμος πολύ αργός εκτός και εάν η λίστα δεν είναι πολύ μεγάλη και ήδη σχεδόν ή κατα το πλείστον ταξινομημένη Ο(n)!. Δεν πρέπει να τον χρησιμοποιήσουμε για ταξινόμηση περισσότερων από 100 στοιχεία ,ή για την επαναληπτική ταξινόμηση λιστών με περισσότερα από μερικές δεκάδες στοιχείων.

Page 27: ΜΑΘΗΜΑ  11 ο

8-27

Quick Sort

• Γενικά: O Αλγόριθμος είναι ένας «Διαίρει και Βασίλευε» τύπος αλγόριθμου. Είναι μία πιο γρήγορη παραλλαγή του merge sort. Ο αλγόριθμος έχει τέσσερα βήματα:

1. Εάν η λίστα έχει ένα στοιχείο επιστρέφει το στοιχείο

2. Αλλιώς, διαλέγει ένα στοιχείο (pivot)

3. Χωρίζει τη λίστα σε δύο υπο-λίστες μία με στοιχεία μικρότερα ή ίσα του pivot, και μία με στοιχεία μεγαλύτερα του pivot

4. Ταξινομεί αναδρομικά τις δύο υπο-λίστες

• Γενικά η ταχύτητα του αλγόριθμου επηρεάζεται από την επιλογή του pivot. Η χειρότερη περίπτωση O(n2) είναι όταν η αρχική λίστα είναι ήδη ταξινομημένη και το πρώτο στοιχείο επιλέγεται σαν pivot. Εάν η επιλογή του pivot γίνει τυχαία τότε ο αλγόριθμος έχει μέση χρονική πολυπλοκότητα O(n log(n)), όπου n είναι το πλήθος των στοιχείων της λίστας που θέλουμε να ταξινομήσουμε

Page 28: ΜΑΘΗΜΑ  11 ο

8-28

Quick Sort

• Υπέρ: Πολύ γρήγορος

• Κατά: Σχετικά μεγάλη κατανάλωση μνήμης λόγω αναδρομής. Κακή σχετικά ταχύτητα όταν η αρχική λίστα είναι ήδη ταξινομημένη

• Χρήση: Είναι γενικά ένας πολύ καλός αλγόριθμος από άποψη ταχύτητας. Καλός να χρησιμοποιείται για μέτρια και μεγάλα δεδομένα τα οποία δεν είναι ήδη ταξινομημένα. Δεν έχει κάποιο πλεονέκτημα εάν χρησιμοποιηθεί για πολύ μικρές λίστες (μέχρι 100 στοιχεία). Ο quick sort είναι λίγο-πολύ η πρώτη μας επιλογή για μεγάλα δεδομένα τα οποία δεν είναι ήδη ταξινομημένα και εάν δεν θέλουμε να χρησιμοποιήσουμε άλλους αλγόριθμους π.χ. heap sort

Page 29: ΜΑΘΗΜΑ  11 ο

8-29

Merge Sort

• Γενικά: Ο αλγόριθμος χωρίζει τη μη ταξινομημένη λίστα σε δύο ίσες υπο-λίστες και ταξινομεί αναδρομικά την κάθε μια. Στο τέλος συνδυάζει τις δύο ταξινομημένες υπο-λίστες σε μία.

• Υπέρ: Σχετικά γρήγορος

• Κατά: Σχετικά μεγάλη κατανάλωση μνήμης λόγω αναδρομής

• Χρήση: Είναι σχετικά πιο γρήγορος για μεγάλα δεδομένα από το heap sort αλλά απαιτεί διπλάσια μνήμη. Ο heap sort είναι καλύτερο όμως από τον merge sort για πολύ μεγάλα δεδομένα. Γενικά ο merge sort είναι χειρότερος από τον quick sort και είναι κακή επιλογή όταν η μνήμη είναι περιορισμένη

Page 30: ΜΑΘΗΜΑ  11 ο

8-30

Παράδειγμα Ταξινόμηση φυσαλίδας με Χρήση Δεικτών Συνάρτησης (i)

• Τα δεδομένα:

– void * a πού βρίσκονται

– int n πόσα είναι

– int size τί μέγεθος έχει καθένα

– comparison f πώς γίνεται η σύγκριση

• Η σύγκριση των δεδομένων

typedef int (*comparison) (void * x,

void * y);

Page 31: ΜΑΘΗΜΑ  11 ο

8-31

Ταξινόμηση φυσαλίδας (ii)

void bsort (void * a, int n,

comparison f, int size)

{

int i, j;

for (i = 0; i < n; i++)

for (j = n-1; j > i; j--) {

unsigned char * px =

(unsigned char *) a +

(j-1) * size;

unsigned char * py =

(unsigned char *) a +

j * size;

Page 32: ΜΑΘΗΜΑ  11 ο

8-32

Ταξινόμηση φυσαλίδας (iii)

• (συνέχεια)

if (f(px, py) > 0) {

int k;

for (k = 0; k < size; k++) {

unsigned char temp = *px;

*px++ = *py;

*py++ = temp;

}

}

}

}

Page 33: ΜΑΘΗΜΑ  11 ο

8-33

Ταξινόμηση φυσαλίδας (iv)

• Συνάρτηση σύγκρισης για ακέραιους

int intcompare (void * x, void * y)

{

return *((int *) x) - *((int *) y);

}

• Κλήση για πίνακα ακεραίων

int x[] = { 44, 55, 12, 42, ... };

...

bsort(x, n, intcompare, sizeof(int));