├── .gitattributes ├── .gitignore ├── MergeSort.py ├── QuickSort.py └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /MergeSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Coursera: Stanford Algotithm Part I 3 | Programming Question 1: Merge Sort and Count Number Inversions 4 | Author: Jihong 5 | Date: March 2015 6 | ''' 7 | 8 | 9 | def loadData(filename): 10 | with open(filename) as f: 11 | lines = [x.split() for x in f] # a list of lists 12 | f.close() 13 | 14 | tempList = zip(*lines) # a list of tuples := transposed lines 15 | tempList = list(tempList[0]) # a list of strings 16 | A = map(int,tempList) # a list of integers 17 | 18 | return A 19 | 20 | 21 | def mergeSort(A): 22 | if len(A) == 1: 23 | sortedA = A 24 | elif len(A)>1: 25 | LH = A[:len(A)//2] 26 | sortedLH = mergeSort(LH) 27 | RH = A[len(A)//2:] 28 | sortedRH = mergeSort(RH) 29 | sortedA = [0]*len(A) # initialise a list of length n 30 | # Merge 31 | i = 0 # mark of sortedLH 32 | j = 0 # mark of sortedRH 33 | k = 0 # mark of sortedA 34 | # both sortedLH and sortedRH are ergodic 35 | while isortedRH[j]: 77 | sortedA[k]=sortedRH[j] 78 | j=j+1 79 | numInv = numInv + len(sortedLH)-i 80 | k=k+1 81 | 82 | 83 | while i1: 100 | LH = A[:n//2] 101 | RH = A[n//2:] 102 | (B,x) = Count(LH,len(LH)) 103 | (C,y) = Count(RH,len(RH)) 104 | (D,z) = CountSplitInv(A,n) 105 | return (D,x+y+z) 106 | 107 | 108 | def main(): 109 | # unit tests 110 | # A = loadData('test.txt') 111 | # print 'orginal: ', A 112 | # A = mergeSort(A) 113 | # print 'sorted: ', A 114 | 115 | A = loadData('IntegerArray.txt') 116 | (A,numInv) = Count(A, len(A)) 117 | print 'Number inversions: %d' % numInv 118 | 119 | 120 | 121 | if __name__ == "__main__": 122 | main() 123 | -------------------------------------------------------------------------------- /QuickSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Coursera: Stanford Algotithm Part I 3 | Programming Question 2: Quick Sort 4 | Author: Jihong 5 | Date: March 2015 6 | ''' 7 | 8 | def loadData(fileName): 9 | with open(fileName) as f: 10 | lines = [x.split() for x in f] # a list of lists 11 | f.close() 12 | 13 | tempList = zip(*lines) # a list of tuples := transposed lines 14 | tempList = list(tempList[0]) # a list of strings 15 | A = map(int,tempList) # a list of integers 16 | 17 | return A 18 | 19 | 20 | def choosePivot(alist,first,last,pivotID): 21 | if pivotID == 'first': 22 | pass 23 | 24 | if pivotID == 'last': 25 | (alist[first], alist[last]) = (alist[last], alist[first]) 26 | 27 | elif pivotID == 'middle': 28 | mid = (last-first)//2 + first 29 | listTemp = [alist[first], alist[last], alist[mid]] 30 | listTemp.sort() 31 | if listTemp[1] == alist[first]: 32 | pivotIndex = first 33 | elif listTemp[1] == alist[last]: 34 | pivotIndex = last 35 | else: 36 | pivotIndex = mid 37 | (alist[first], alist[pivotIndex]) = (alist[pivotIndex], alist[first]) 38 | 39 | 40 | 41 | def partition(alist, first, last): 42 | pivotVal = alist[first] # initialise pivot as the first element 43 | leftmark = first+1 44 | for rightmark in range(first+1,last+1): 45 | if alist[rightmark] < pivotVal: 46 | (alist[leftmark],alist[rightmark]) = (alist[rightmark],alist[leftmark]) 47 | leftmark = leftmark + 1 48 | (alist[leftmark-1],alist[first]) = (alist[first],alist[leftmark-1]) 49 | 50 | return leftmark-1 # partition point := where pivot finally occupies 51 | 52 | 53 | 54 | def quickSort(alist,first,last,pivotID): 55 | numComp = last -first 56 | if last <= first: 57 | return (alist, 0) 58 | else: 59 | choosePivot(alist,first,last,pivotID) 60 | splitpoint = partition(alist,first,last) 61 | (Lsorted,numCompL) = quickSort(alist, first, splitpoint-1, pivotID) 62 | (Rsorted,numCompR) = quickSort(alist, splitpoint+1, last, pivotID) 63 | numComp = numComp + numCompL + numCompR 64 | return (alist, numComp) 65 | 66 | 67 | def main(fileName): 68 | pivotList = ['first', 'middle', 'last'] 69 | 70 | for pivotID in pivotList: 71 | A = loadData(fileName) 72 | (A, n) = quickSort(A,0,len(A)-1,pivotID) 73 | print "number of comparisons: %d", n 74 | 75 | 76 | 77 | if __name__ == '__main__': 78 | # unit test 79 | # main('test.txt') 80 | main('QuickSort.txt') 81 | 82 | 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms 2 | Design and Analysis (Standford) 3 | Programming Question-1 4 | 5 | Question 1 6 | Download the text file here. (Right click and save link as) 7 | This file contains all of the 100,000 integers between 1 and 100,000 (inclusive) in some order, with no integer repeated. 8 | Your task is to compute the number of inversions in the file given, where the ith row of the file indicates the ith entry of an array. 9 | Because of the large size of this array, you should implement the fast divide-and-conquer algorithm covered in the video lectures. The numeric answer for the given input file should be typed in the space below. 10 | So if your answer is 1198233847, then just type 1198233847 in the space provided without any space / commas / any other punctuation marks. You can make up to 5 attempts, and we'll use the best one for grading. 11 | (We do not require you to submit your code, so feel free to use any programming language you want --- just type the final numeric answer in the following space.) 12 | [TIP: before submitting, first test the correctness of your program on some small test files or your own devising. Then post your best test cases to the discussion forums to help your fellow students!] 13 | Answer for Question 1 14 | 2407905288 15 | 16 | 17 | 18 | Programming Question-2 19 | 20 | Question 1 21 | GENERAL DIRECTIONS: 22 | Download the text file here. 23 | The file contains all of the integers between 1 and 10,000 (inclusive, with no repeats) in unsorted order. The integer in the ith row of the file gives you the ith entry of an input array. 24 | Your task is to compute the total number of comparisons used to sort the given input file by QuickSort. As you know, the number of comparisons depends on which elements are chosen as pivots, so we'll ask you to explore three different pivoting rules. 25 | You should not count comparisons one-by-one. Rather, when there is a recursive call on a subarray of length m, you should simply add m−1 to your running total of comparisons. (This is because the pivot element is compared to each of the other m−1 elements in the subarray in this recursive call.) 26 | WARNING: The Partition subroutine can be implemented in several different ways, and different implementations can give you differing numbers of comparisons. For this problem, you should implement the Partition subroutine exactly as it is described in the video lectures (otherwise you might get the wrong answer). 27 | DIRECTIONS FOR THIS PROBLEM: 28 | For the first part of the programming assignment, you should always use the first element of the array as the pivot element. 29 | HOW TO GIVE US YOUR ANSWER: 30 | Type the numeric answer in the space provided. 31 | So if your answer is 1198233847, then just type 1198233847 in the space provided without any space / commas / other punctuation marks. You have 5 attempts to get the correct answer. 32 | (We do not require you to submit your code, so feel free to use the programming language of your choice, just type the numeric answer in the following space.) 33 | Answer for Question 1 34 | 162085 35 | 36 | Question 2 37 | GENERAL DIRECTIONS AND HOW TO GIVE US YOUR ANSWER: 38 | See the first question. 39 | DIRECTIONS FOR THIS PROBLEM: 40 | Compute the number of comparisons (as in Problem 1), always using the final element of the given array as the pivot element. Again, be sure to implement the Partition subroutine exactly as it is described in the video lectures. Recall from the lectures that, just before the main Partition subroutine, you should exchange the pivot element (i.e., the last element) with the first element. 41 | Answer for Question 2 42 | 164123 43 | 44 | Question 3 45 | GENERAL DIRECTIONS AND HOW TO GIVE US YOUR ANSWER: 46 | See the first question. 47 | DIRECTIONS FOR THIS PROBLEM: 48 | Compute the number of comparisons (as in Problem 1), using the "median-of-three" pivot rule. [The primary motivation behind this rule is to do a little bit of extra work to get much better performance on input arrays that are nearly sorted or reverse sorted.] In more detail, you should choose the pivot as follows. Consider the first, middle, and final elements of the given array. (If the array has odd length it should be clear what the "middle" element is; for an array with even length 2k, use the kth element as the "middle" element. So for the array 4 5 6 7, the "middle" element is the second one ---- 5 and not 6!) Identify which of these three elements is the median (i.e., the one whose value is in between the other two), and use this as your pivot. As discussed in the first and second parts of this programming assignment, be sure to implement Partition exactly as described in the video lectures (including exchanging the pivot element with the first element just before the main Partition subroutine). 49 | EXAMPLE: For the input array 8 2 4 5 7 1 you would consider the first (8), middle (4), and last (1) elements; since 4 is the median of the set {1,4,8}, you would use 4 as your pivot element. 50 | SUBTLE POINT: A careful analysis would keep track of the comparisons made in identifying the median of the three candidate elements. You should NOT do this. That is, as in the previous two problems, you should simply add m−1 to your running total of comparisons every time you recurse on a subarray with length m. 51 | Answer for Question 3 52 | 138382 53 | 54 | --------------------------------------------------------------------------------