370 likes | 379 Views
קורס תכנות. שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב. Today’s class. Data The importance of fast access to data How can it be achieved? Preprocessing followed by fast retrieval The most basic data structure: arrays Preprocessing sorting fast retrieval searching
E N D
קורס תכנות שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב
Today’s class Data The importance of fast access to data How can it be achieved? Preprocessing followed by fast retrieval The most basic data structure: arrays Preprocessing sorting fast retrieval searching Time complexity 2
2 5 1 8 9 13 67 Sorting • A sorted array is an array that its elements are arranged in descending/ascending order • One of the most common application on arrays • An example of a sorted array:
What is Sorting Good For? • Finding a number in an array • Consider a large array (of length n) and multiple queries on whether a given number exists in the array (and what is its position in it) • Naive solution: given a number, traverse the array and search for it • Not efficient ~ n/2 steps for each search operation • Can we do better? • Sort the array as a preliminary step. Now search can be performed much faster!
Search in a Non-Sorted Array • Search for value in array • If value is not in array return -1 • Traverse the elements by the array’s order intregular_search(intarray[], int size, int value) { inti; for (i = 0; i < size; i++) { if (array[i] == value) return i; } return -1; {
Binary Search • Input: • A sorted array of integers A • An integer query q • Output: • -1 if q is not a member of A • The index of q in A otherwise • Algorithm: • Check the middle element of A • If it is equal to q, return its index • If it is >= q, search for q in A[0,…,middle-1] • If it is < q, search for q in A[middle+1,...,end]
4 5 index 7 8 0 1 2 3 6 9 An Example value
Code – Binary Search int binarySearchRec(int arr[], int quary, int start, int end) { int middle; if (start > end) return -1; middle = (start + end) / 2; if (arr[middle] == quary) return middle; if (arr[middle] > quary) return binarySearchRec(arr,quary,start,middle-1); else return binarySearchRec(arr,quary,middle+1,end); }
Code – Main int a [] = {-5,-3,0,4,8,11,22,56,57,97}; printf("%d\n",binarySearch(a,SIZE,0)); printf("%d\n",binarySearch(a,SIZE,-4)); printf("%d\n",binarySearch(a,SIZE,8)); printf("%d\n",binarySearch(a,SIZE,1)); printf("%d\n",binarySearch(a,SIZE,-5)); printf("%d\n",binarySearch(a,SIZE,9)); printf("%d\n",binarySearch(a,SIZE,7)); int binarySearch(int arr[], int size, int quary) { return binarySearchRec(arr,quary,0,size-1); }
Output int a [] = {-5,-3,0,4,8,11,22,56,57,97}; printf("%d\n",binarySearch(a,SIZE,0)); printf("%d\n",binarySearch(a,SIZE,-4)); printf("%d\n",binarySearch(a,SIZE,8)); printf("%d\n",binarySearch(a,SIZE,1)); printf("%d\n",binarySearch(a,SIZE,-5)); printf("%d\n",binarySearch(a,SIZE,9)); printf("%d\n",binarySearch(a,SIZE,7));
So, How Fast is it? • Worst case analysis • Size of the inspected array: n n/2 n/4 ….. 1 • Each step is very fast (a small constant number of operations) • There are log2(n) such steps • So it takes ~ log2(n) steps per search • Much faster then ~ n • If n = 1,000,000 it will take ~ 20 step (instead of ~milion)
A Word About Time Complexity Two common resources are space, measured by the number of deferred operations, and time, measured by the number of primitive steps What matters? Small instances are not “interesting” Quick operations are considered as constant What matters is the order of times that constant operations are performed Assume we have an array of size n = 1 million: Order of n2 ~ constant * trillion (Tera) Order of n = constant * million (Mega) Order of log(n) = constant * 20 13
Binary Search Using Pointers int binarySearchRec(int quary, int * start, int * end) { int * middle; if (start > end) return -1; middle = (start + end) / 2; if (*middle == quary) return middle - start; if (*middle > quary) return binarySearchRec(quary,start,middle-1); else return binarySearchRec(quary,middle+1,end); } int binarySearch(int * arr, int size, int quary) { return binarySearchRec(quary,arr,arr+size-1); } 14
Iterative Binary Search int binarySearch(int arr [], int size, int quary){ int start= 0, end = size - 1; int middle; while (start <= end){ middle = (start + end) / 2; if (quary == arr [middle]) return middle; if (quary < arr [middle]) end = middle - 1; if (quary > arr [middle]) start = middle + 1; } return -1; }
Add an Element to a Sorted Array /* * Requires: * 1. The elements of the array are sorted in ascending order. * 2. length < capacity * length is the current number of elements in the array * capacity is the maximum number of elements array */ void array_add(int array[], int length, int value) { inti, j; for (i = 0; i < length && array[i] <= value; i++); for (j = length; j > i; j--) array[j] = array[j - 1]; array[i] = value; {
?10< ?10< ?10< ?10< ?10< ?10< Add an Element to a Sorted Array • קלט לפונקציה - המערך והמספר 10 • שלב אחרי שלב: 2 5 1 8 9 13 67 2 5 10 13 67 67 1 8 9 13
Add an Element to a Sorted Array ?10< ?10< ?10< ?10< ?10< ?10< 2 5 1 8 9 13 67 2 5 10 67 13 67 1 8 9 13 • Input: input array and the value 10 • Step by step: 18
Cons and Pros of Arrays • Direct access (random access) • Fast search (for sorted arrays) • Fast access • Less appropriate for dynamic operations • Add element • Remove element • Update element (remove + add) • We will study data structure that have the second bullet properties later in the course
Bubble Sort • Repeatedly stepping through the array to be sorted, comparing each pair of adjacent items and swapping them if they are in the wrong order • The pass through the array is repeated until no swaps are needed the array is sorted • “Bubbles” the correct elements to the top of the array 20
2 2 7 2 2 2 2 2 2 2 2 2 2 5 4 2 4 7 7 7 4 7 7 5 5 7 4 8 8 5 5 5 8 5 5 5 4 7 5 8 4 5 7 5 5 4 7 4 7 4 7 7 8 8 8 8 8 8 4 4 8 4 4 8 8 2 5 4 7 8 Bubble Sort Example (done)
Bubble Sort Code void bubbleSort(int arr[], int size) { int i,j; for (i = size - 1; i > 0; --i) for (j = 0; j < i; ++j) if (arr[j] > arr[j+1]) { // swap (with trick) arr[j] = arr[j] + arr[j+1]; arr[j+1] = arr[j] - arr[j+1]; arr[j] = arr[j] - arr[j+1]; } }
Bubble Sort Code int main() { int i, a [] = {7,2,8,5,4}; bubbleSort(a,SIZE); for (i = 0; i < SIZE; ++i) printf("%d ",a[i]); printf("\n"); return 0; }
Bubble Sort Time ComplexityArray of size n constant void bubbleSort(int arr[], int size) { int i,j; for (i = size - 1; i > 0; --i) for (j = 0; j < i; ++j) if (arr[j] > arr[j+1]) { // swap (with trick) arr[j] = arr[j] + arr[j+1]; arr[j+1] = arr[j] - arr[j+1]; arr[j] = arr[j] - arr[j+1]; } } n iterations i iterations (n-1 + n-2 + n-3 + …. + 1) * const ~ ½ * n2
Time Complexity Examples • Find a maximum in a general array • Find the maximum in a sorted array • Find the 5th largest element in a sorted array • Answer n Fibonacci quarries, each limited by MAX • Find an element in a general array • Find an element in a sorted array
The Idea Behind Merge Sort • A small list will take fewer steps to sort than a large list • Fewer steps are required to construct a sorted list from two sorted lists than two unsorted lists
Merge Sort Algorithm • If the array is of length 0 or 1, then it is already sorted. Otherwise: • Divide the unsorted array into two sub-arrays of about half the size • Sort each sub-array recursively by re-applying merge sort • Merge the two sub-arrays back into one sorted array
Merge Sort Code פתוח?
Merge Sort Time Complexity n + n + … + n = (n+1) * log(n) log(n) +1 • If the array is of length 0 or 1, then it is already sorted. Otherwise: • Divide the unsorted array into two sub-arrays of about half the size • Sort each sub-array recursively by re-applying merge sort • Merge the two sub-arrays back into one sorted array n + 2 * (n/2) + 22 * n/22 + 23 * n/23 + … + 2log(n) * n/2log(n) =
Bucket Sort • Linear-time sorting algorithm! • • But: restrictions on data – bounded integers…
Sorting Strings • So far we only sorted numbers • How would we sort strings? • Lexicographical order (מילוני) • To be continued in tirgul…
“Generic” Sort • Sort an array ofint/long/double/float/char in descending/ascending order • What is the difference between these cases? • Algorithmically the same! • Code duplication
The Idea Behind“Generic” Sort (Cont.) • Sort an array ofint/long/double/float/char in descending/ascending order • What are the parameters? • Array type • Comparison between array elements • Sort (array type arr, comperatorcomp) { • … • if (comp(arr[i],arr[j]) < 0) swap • … • }
Implementation Sketch in C Comperator code array Memory
לתרגול – אחד מהשניים (והשני לשיעורי בית) • http://en.wikipedia.org/wiki/Selection_sort • http://en.wikipedia.org/wiki/Insertion_sort
לתרגול http://en.wikipedia.org/wiki/Quicksort
רעיונות לחומר לתרגול מילון - מיון של מילים חיפוש במילון... אפשר לתת כמה קטעי קוד לדבר על זמני ריצה, לדוגמא: חיפוש על מערך שבכל שלב מגרילים אינדקס רנדומי פיבונאצ'י רקורסיבי עם זיכרון (memoization) – למתי יש את הקוד, לאסף חש כמה שקפים רלוונטיים