Struktur Data & Algoritme (Data Structures & Algorithms) Objectives Memahami beberapa algoritme sorting dan dapat menganalisa kompleksitas-nya Sorting Denny (denny@cs.ui.ac.id) Suryana Setiawan (setiawan@cs.ui.ac.id) Fakultas Ilmu Komputer Universitas Indonesia Semester Genap - 00/005 Version.0 - Internal Use Only SDA/SORT/V.0/ Outline Beberapa algoritme untuk melakukan sorting Idea Example Running time for each algorithm Sort Sorting = pengurutan Sorted = terurut menurut kaidah tertentu Data pada umumnya disajikan dalam bentuk sorted. Why? Bayangkan bagaimana mencari telepon seorang teman dalam buku yang disimpan tidak terurut. SDA/SORT/V.0/ SDA/SORT/V.0/ Bubble Sort: idea bubble = busa/udara dalam air, so? Busa dalam air akan naik ke atas. Why? How? Ketika busa naik ke atas, maka air yang di atasnya akan turun memenuhi tempat bekas busa tersebut. Bubble Sort 1 0 1 65 0-1 58 1 0 0-1 58 65 1 0 0-1 58 65 1 0-1 0 58 65 SDA/SORT/V.0/5 Perhatikan bahwa pada setiap iterasi, dapat dipastikan satu elemen akan menempati tempat yang benar SDA/SORT/V.0/6 1
Bubble Sort 5 1 0-1 0 58 65 6 1 0-1 0 58 65 7 0-1 1 0 58 65 8-1 0 1 0 58 65 Stop here why? Bubble Sort: algorithms Algorithm (see jdk1.5.0_01\demo\applets\sortdemo) void sort(int a[]) throws Exception for (int i = a.length; --i>=0; ) boolean swapped = false; for (int j = 0; j<i; j++) if (a[j] > a[j+1]) int T = a[j]; a[j] = a[j+1]; a[j+1] = T; swapped = true; if (!swapped) return; SDA/SORT/V.0/7 SDA/SORT/V.0/8 Bubble Sort Running time: Worst case: O(n ) Best case: O(n) -- when? why? Variant: bi-directional bubble sort original bubble sort: hanya bergerak ke satu arah bi-directional bubble sort bergerak dua arah (bolak balik). see jdk1.5.0_01\demo\applets\sortdemo Selection Sort: idea Ambil yang terbaik (select) dari suatu kelompok, kemudian diletakkan di belakang barisan Lakukan terus sampai kelompok tersebut habis SDA/SORT/V.0/9 SDA/SORT/V.0/10 Selection Sort Selection Sort 0 1 65 0-1 58 0 1 0-1 58 65 0 1 0-1 58 65 0 1 0-1 58 65 0 1 0-1 58 65-1 1 0 0 58 65-1 1 0 0 58 65-1 1 0 0 58 65 SDA/SORT/V.0/11 SDA/SORT/V.0/1
Selection Sort -1 1 0 0 58 65-1 0 1 0 58 65-1 0 1 0 58 65-1 0 1 0 58 65-1 0 1 0 58 65 Selection: algoritme void sort(int a[]) throws Exception for (int i = 0; i < a.length; i++) int min = i; int j; /* Find the smallest element in the unsorted list for (j = i + 1; j < a.length; j++) if (a[j] < a[min]) min = j; SDA/SORT/V.0/1 SDA/SORT/V.0/1 Selection: algoritme () Selection Sort: analysis /* Swap the smallest unsorted element into the end of the sorted list. int T = a[min]; a[min] = a[i]; a[i] = T; Running time: Worst case: O(n ) Best case: O(n ) Based on big-oh analysis, is selection sort better than bubble sort? Does the actual running time reflect the analysis? SDA/SORT/V.0/15 SDA/SORT/V.0/16 Idea: mengurutkan kartu-kartu 0 1 65 0-1 58 1 0 65 0-1 58 0 1 65 0-1 58 1 0 65 0-1 58 1 0 65 0-1 58 1 0 65 0-1 58 SDA/SORT/V.0/17 SDA/SORT/V.0/18
1 0 0 65 58 65 1 0 65 0-1 58 1 0 65 0 58 65 58 65 0 1 0 65-1 58 1 0 65 0 65 58 65 1 0 0 65 65 58 1 0 65 0 65 58 65 58 65 SDA/SORT/V.0/19 SDA/SORT/V.0/0 : ineffecient version Insertion sort untuk mengurutkan array integer public static void insertionsort (int[] a) for (int ii = 1; ii < a.length; ii++) int jj = ii; while (( jj > 0) && (a[jj] < a[jj - 1])) int temp = a[jj]; a[jj] = a[jj - 1]; a[jj - 1] = temp; jj--; Perhatikan: ternyata nilai di a[jj] selalu sama dapat dilakukan efisiensi di sini. Insertion sort yang lebih efisien public static void insertionsort (int[] a) for (int ii = 1; ii < a.length; ii++) int temp = a[ii]; int jj = ii; while (( jj > 0) && (temp < a[jj - 1])) a[jj] = a[jj - 1]; jj--; a[jj] = temp; SDA/SORT/V.0/1 SDA/SORT/V.0/ Running time analysis: Worst case: O(n ) Best case: O(n) Is insertion sort faster than selection sort? Notice the similarity and the difference between insertion sort and selection sort. Mergesort Divide and Conquer approach Idea: Merging two sorted array takes O(n) time Split an array into two takes O(1) time 1 0 65-1 0 58 SDA/SORT/V.0/ SDA/SORT/V.0/
Mergesort: Algorithm If the number of items to sort is 0 or 1, return. Recursively sort the first and second half separately. Merge the two sorted halves into a sorted group. Mergesort 0 1 65 0-1 58 0 1 65 0-1 58 split 0 1 65 0-1 58 0 1 65 0-1 58 SDA/SORT/V.0/5 SDA/SORT/V.0/6 Mergesort Mergesort 0 1 65 0-1 58 split 1 0 65-1 0 58 1 65-1 58 1 0 65-1 0 58 merge 0 1 65 0-1 58 merge -1 0 1 0 58 6 1 0 65-1 0 58 SDA/SORT/V.0/7 SDA/SORT/V.0/8 Merge Sort: implementation Implement operation to merge two sorted arrays into one sorted array! public static void merge (int [] array, int lo, int high) // assume: // mid = (lo + high) / ; // array [lo..mid] and [mid+1..high] are sorted Merge Sort: implementation There are two ways to merge two sorted array: in place merging using extra place merging SDA/SORT/V.0/9 SDA/SORT/V.0/0 5
Merge Sort: analysis Running Time: O(n log n) Why? Quicksort Divide and Conquer approach Quicksort(S) algorithm: If the number of items in S is 0 or 1, return. Pick any element v in S. This element is called the pivot. Partition S v into two disjoint groups: L = x S v x v and R = x S v x v Return the result of Quicksort(L), followed by v, followed by Quicksort(R). SDA/SORT/V.0/1 SDA/SORT/V.0/ Quicksort: select pivot Quicksort: partition 0 58 0 65 1-1 0 0-1 58 1 65 SDA/SORT/V.0/ SDA/SORT/V.0/ Quicksort: recursive sort & merge the results Quicksort: partition algorithm 1-1 0 1 0 58 65 0 1 65 0-1 58 1 65 0-1 58 0-1 0 1 0 58 65 1 0 65 0-1 58 SDA/SORT/V.0/5 SDA/SORT/V.0/6 6
Quicksort: partition algorithm 1 Quicksort: partition algorithm 1 0 1 65 0-1 58 1-1 0 0 58 65 1 65 0-1 58 0 1 0 0-1 58 65 0 1-1 58 65-1 0 1 65-1 1 1-1 0 0 58 65 1-1 0 0 58 65-1 0 1 0 58 65 SDA/SORT/V.0/7 SDA/SORT/V.0/8 Quicksort: partition algorithm Quicksort: partition algorithm original 0 1 65 0-1 58 1 65 0-1 58 0 pivot = 0 ++ while < pivot -- while >= pivot 1 65 0-1 58 0 1-1 0 65 58 0 1 65 0-1 58 0 1-1 0 65 58 0 1 65 0-1 58 0 sort CROSSING! sort SDA/SORT/V.0/9 SDA/SORT/V.0/0 Quicksort: algoritme static void QuickSort(int a[], int lo0, int hi0) int lo = lo0; int hi = hi0; int pivot; // base case if ( hi0 <= lo0) return; pivot = a[lo0]; // loop through the array until indices cross while( lo <= hi ) /* find the first element that is greater than or equal to the partition element starting from the Index. while( ( lo < hi0 ) && ( a[lo] < pivot )) ++lo; /* find an element that is smaller than the partition element starting from the Index. while( ( hi > lo0 ) && ( a[hi] >= pivot )) --hi; SDA/SORT/V.0/1 // if the indexes have not crossed, swap if( lo <= hi ) swap(a, lo, hi); ++lo; --hi; SDA/SORT/V.0/ 7
/* If the index has not reached the side of array must now sort the partition. if (lo0 < hi) QuickSort( a, lo0, hi ); /* If the index has not reached the side of array must now sort the partition. if( lo < hi0 ) QuickSort( a, lo, hi0 ); Quicksort: analysis Partitioning takes O(n) Merging takes O(1) So, for each recursive call, the algorithm takes O(n) How many recursive calls does a quick sort need? SDA/SORT/V.0/ SDA/SORT/V.0/ Quicksort: selecting pivot Ideal pivot: median element Common pivot First element Element at the middle Median of three Shellsort Original: 0 1 65 0-1 58 5-sort: Sort setiap item yang berjarak 5: 0 1 65 0-1 58 SDA/SORT/V.0/5 SDA/SORT/V.0/6 Shellsort Original: 0 1 65 0-1 58 After 5-sort: 0 0-1 1 58 65 After -sort: 0-1 1 0 65 58 After 1-sort: 1 0 65 0 65 58 65 58 65 Performance of Shellsort Insertion Shellsort N Sort Shell's Odd Gaps Only Dividing by. 1000 1 11 11 9 000 8 6 1 000 196 61 59 5 8000 7950 15 11 11 16000 560 58 69 000 11911 869 75 575 6000 50000 091 1705 19 O(N / ) O(N 5/ ) O(N 7/6 ) SDA/SORT/V.0/7 SDA/SORT/V.0/8 8
Generic Sort Bagaimana jika diperlukan method untuk mengurutkan array dari String, array dari Lingkaran (berdasarkan radiusnya)? Apakah mungkin dibuat suatu method yang bisa dipakai untuk semua jenis object? Ternyata supaya object bisa diurutkan, harus bisa dibandingkan dengan object lainnya (mempunyai behavior bisa dibandingkan - comparable method). Solusinya: Gunakan interface yang mengandung method yang dapat membandingkan dua buah object. Generic Sort REVIEW: Suatu kelas yang meng-implements sebuah interface, berarti kelas tersebut mewarisi interface (definisi method-method) = interface inheritance, bukan implementation inheritance Dalam Java, terdapat interface java.lang.comparable method: int compareto (Object o) SDA/SORT/V.0/9 SDA/SORT/V.0/50 Other kinds of sort Heap sort. We will discuss this after tree. Postman sort / Radix Sort. etc. Further Reading http://telaga.cs.ui.ac.id/webkuliah/iki101 00/resources/animation/ Chapter 8: Sorting Algorithm SDA/SORT/V.0/51 SDA/SORT/V.0/5 What s Next Recursive (Chapter 7) SDA/SORT/V.0/5 9