From 5dad3b7df58c0eb74e0c8fa799a9e23f2c2c7c0f Mon Sep 17 00:00:00 2001 From: Sunny Pate Date: Sat, 13 Oct 2018 12:21:44 +1100 Subject: [PATCH 1/7] Merge Sort without Slicing Basically in merge sort we use slice function so the above code is similat to quick sort which helps merge sort to use without slicing --- .DS_Store | Bin 0 -> 6148 bytes sorting/MergesortWithoutSlicing.py | 60 +++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 .DS_Store create mode 100644 sorting/MergesortWithoutSlicing.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1944ae096e08d1ea5c636e3be00d6df20475c8cb GIT binary patch literal 6148 zcmeHKO>Wab6n@jD#0~PY`xshY&^cqBr03y!VYWpXC`35wZR(>=Ctz$bt)Ow9x#*L|*us zZRj46WO9s@d>Z2ykCL@&(_s`a3jAvdh zN%v?(2Q;Jytv(0$-FI-#(}cvoXwqzvPZ zX$BNgia4Si+$o*bxL<4BCh9m?1!kYpakW~``F&;1mFi%gPqjjygJ}}yMYsEfZEQBS z&NVHoWwkD}UU(Be_X@w5<$XVUCaxa(#U#-2W6qNwu^&8%qxoU`@&Qi^KTe}elH)K! z$@8ai8uEFc&(biL<9I4zS+->#ws#hby<68i&TjAKvg0iF_q!cuZ}-M>XGR(;5Yg0#yYz)n!}k|HI#(|EnZ(WfU+9{8tLF#=sl& zF(tjXu1!wtwGR9UE=<&w3MB=N-i~D;w&ESQG~^r+09}oxLiE7Qhk%s9G)95Hs=#+I COrW3u literal 0 HcmV?d00001 diff --git a/sorting/MergesortWithoutSlicing.py b/sorting/MergesortWithoutSlicing.py new file mode 100644 index 0000000..7883024 --- /dev/null +++ b/sorting/MergesortWithoutSlicing.py @@ -0,0 +1,60 @@ + +# coding: utf-8 + +# In[1]: + + +#Merge Slot Without Slicing +#start is the index of the first item +#end is the index past the the last item +def indexMergeSort(alist, start = None, end = None): + if start == None: + start = 0 + if end == None: + end = len(alist) + #note that the print operations still use slicing for convenience + #print("Input: ",alist[start:end]) + + length = end - start + if length > 1: + #print("Splitting ",alist[start:end]) + mid = start + length//2 + + indexMergeSort(alist, start, mid) + indexMergeSort(alist, mid, end) + + i=start # index for the left part of the list + j=mid # index for the right part of the list + #we use a temporary list + templist = [None] * (length) + k = 0 #index for the temp list + while i < mid and j < end: + if alist[i] < alist[j]: + templist[k] = alist[i] + i=i+1 + else: + #we swap + templist[k] = alist[j] + j=j+1 + k=k+1 + + while i < mid: + templist[k] = alist[i] + i=i+1 + k=k+1 + + while j < end: + templist[k]=alist[j] + j=j+1 + k=k+1 + + #we copy the results + for k in range(length): + alist[start+k] = templist[k] + + #print("Merging ",alist[start:mid], alist[mid:end]) + +alist = [54,26,93,17,77,31,44,55,20] +indexMergeSort(alist) +print(alist) + From 72a1d835dffaa3d62fbe8ff7c36119cee3b33e53 Mon Sep 17 00:00:00 2001 From: Sunny Pate Date: Sat, 13 Oct 2018 12:46:26 +1100 Subject: [PATCH 2/7] Bubble Sort Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in wrong order. --- .DS_Store | Bin 6148 -> 6148 bytes sorting/BubbleSort.py | 17 +++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 sorting/BubbleSort.py diff --git a/.DS_Store b/.DS_Store index 1944ae096e08d1ea5c636e3be00d6df20475c8cb..3e6c0892aebfe69925431265db575a1e33683f03 100644 GIT binary patch delta 21 ccmZoMXffDunU%xHz(hyE*uZ@AZB|Vo07~8lLjV8( delta 21 ccmZoMXffDunU%xD(o{#m*wAA0ZB|Vo084xZQ2+n{ diff --git a/sorting/BubbleSort.py b/sorting/BubbleSort.py new file mode 100644 index 0000000..9c10e42 --- /dev/null +++ b/sorting/BubbleSort.py @@ -0,0 +1,17 @@ + +# coding: utf-8 + +# In[43]: + + +alist = [54,26,93,17,77,31,44,55,20] +def bubbleSort(alist): + for passnum in range(len(alist)-1,0,-1): + for i in range(passnum): + if alist[i]>alist[i+1]: + temp = alist[i] + alist[i] = alist[i+1] + alist[i+1] = temp + return alist +print(bubbleSort(alist)) + From 5cfce3ba4c07e375cd03dab1abe252e4afc10e00 Mon Sep 17 00:00:00 2001 From: Sunny Pate Date: Sat, 13 Oct 2018 12:56:34 +1100 Subject: [PATCH 3/7] QuickBubblesortwithgood complexity --- .DS_Store | Bin 6148 -> 6148 bytes sorting/QuickBublesort.py | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 sorting/QuickBublesort.py diff --git a/.DS_Store b/.DS_Store index 3e6c0892aebfe69925431265db575a1e33683f03..dbcb8b0a6268a37fe669710bee4524a91f965eff 100644 GIT binary patch delta 20 bcmZoMXffDug_YgHKu5vY%y{!{R!t!QMWY56 delta 20 bcmZoMXffDug_YgFL`T8cz 0 and exchanges: + exchanges = False + for i in range(passnum): + if alist[i]>alist[i+1]: + exchanges = True + temp = alist[i] + alist[i] = alist[i+1] + alist[i+1] = temp + passnum = passnum-1 + return alist +print(shortBubbleSort(alist)) + From 83c55b8e46222d408868f11d3e99113e505ad489 Mon Sep 17 00:00:00 2001 From: Sunny Pate Date: Sat, 13 Oct 2018 13:07:15 +1100 Subject: [PATCH 4/7] SelectionSort The selection sort algorithm sorts an array by repeatedly finding the minimum element (considering ascending order) from unsorted part and putting it at the beginning. The algorithm maintains two subarrays in a given array. 1) The subarray which is already sorted. 2) Remaining subarray which is unsorted. In every iteration of selection sort, the minimum element (considering ascending order) from the unsorted subarray is picked and moved to the sorted subarray. --- sorting/selectionSort.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 sorting/selectionSort.py diff --git a/sorting/selectionSort.py b/sorting/selectionSort.py new file mode 100644 index 0000000..78b4e36 --- /dev/null +++ b/sorting/selectionSort.py @@ -0,0 +1,21 @@ + +# coding: utf-8 + +# In[50]: + + +alist = [54,26,93,17,77,31,44,55,20] +def selectionSort(alist): + for fillslot in range(len(alist)-1,0,-1): + positionOfMax=0 + for location in range(1,fillslot+1): + if alist[location]>alist[positionOfMax]: + positionOfMax = location + + temp = alist[fillslot] + alist[fillslot] = alist[positionOfMax] + alist[positionOfMax] = temp + return alist + +print(shortBubbleSort(alist)) + From 10ebf884613524018eac709a9175f8ec74c5c130 Mon Sep 17 00:00:00 2001 From: Sunny Patel Date: Sat, 13 Oct 2018 13:19:27 +1100 Subject: [PATCH 5/7] UpdateselectionSort.py minor changes --- sorting/selectionSort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorting/selectionSort.py b/sorting/selectionSort.py index 78b4e36..2de5d91 100644 --- a/sorting/selectionSort.py +++ b/sorting/selectionSort.py @@ -17,5 +17,5 @@ def selectionSort(alist): alist[positionOfMax] = temp return alist -print(shortBubbleSort(alist)) +print(selectionSort(alist)) From 143302129a4bf0065d4329fec1ee28ff0e85adbb Mon Sep 17 00:00:00 2001 From: Sunny Pate Date: Sat, 13 Oct 2018 13:37:58 +1100 Subject: [PATCH 6/7] shell sort --- sorting/shellSort.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 sorting/shellSort.py diff --git a/sorting/shellSort.py b/sorting/shellSort.py new file mode 100644 index 0000000..f0d38e5 --- /dev/null +++ b/sorting/shellSort.py @@ -0,0 +1,28 @@ + +# coding: utf-8 + +# In[2]: + + +alist = [54,26,93,17,77,31,44,55,20] +def shellSort(alist): + sublistcount = len(alist)//2 + while sublistcount > 0: + for startposition in range(sublistcount): + gapInsertionSort(alist,startposition,sublistcount) + sublistcount = sublistcount // 2 + return alist + +def gapInsertionSort(alist,start,gap): + for i in range(start+gap,len(alist),gap): + + currentvalue = alist[i] + position = i + + while position>=gap and alist[position-gap]>currentvalue: + alist[position]=alist[position-gap] + position = position-gap + + alist[position]=currentvalue +print(shellSort(alist)) + From 71301f21786fa54665475161ad84d3c040560c00 Mon Sep 17 00:00:00 2001 From: Sunny Pate Date: Sat, 13 Oct 2018 15:16:01 +1100 Subject: [PATCH 7/7] sortingalgoswithit'scomputingtime --- sorting/Sortingalgoswithcomputing time.py | 439 ++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 sorting/Sortingalgoswithcomputing time.py diff --git a/sorting/Sortingalgoswithcomputing time.py b/sorting/Sortingalgoswithcomputing time.py new file mode 100644 index 0000000..165422a --- /dev/null +++ b/sorting/Sortingalgoswithcomputing time.py @@ -0,0 +1,439 @@ + +# coding: utf-8 + +# # 1 Best cases + +# **1.1** Bubble sort + +# The short version of Bubble sort is given in the online book: +# https://runestone.academy/runestone/static/FIT5211/SortSearch/TheBubbleSort.html +# At every iteration, it detects whether an exchange has been made, and only continues iteration if that is the case. Given a sorted list, the first iteration will make no exchange, thus no other iteration will be performed, and only the inner loop will actually iterate over the entire list. The running time in that case is thus $O(n)$. + +# **1.2** Selection sort + +# After every pass of selection sort, the only thing we know is that one more item is now in place. The algorithm has no way of knowing and thus using the fact that the list is already sorted. The algorithm will thus perform the whole $O(n^2)$ operations, as in the worst case. + +# **1.3** Merge sort + +# Merge splits the input list into two, without looking at its contents. the contents are only looked at upon merging, after every item in the list has been split into a sublist of size 1. At this point, all merging operations still need to happen. In this case, the running time is thus also $O(n \log{n})$. + +# # 2 Merge sort without slicing + +# In[1]: + + +#start is the index of the first item +#end is the index past the the last item +def indexMergeSort(alist, start = None, end = None): + if start == None: + start = 0 + if end == None: + end = len(alist) + #note that the print operations still use slicing for convenience + #print("Input: ",alist[start:end]) + + length = end - start + if length > 1: + #print("Splitting ",alist[start:end]) + mid = start + length//2 + + indexMergeSort(alist, start, mid) + indexMergeSort(alist, mid, end) + + i=start # index for the left part of the list + j=mid # index for the right part of the list + #we use a temporary list + templist = [None] * (length) + k = 0 #index for the temp list + while i < mid and j < end: + if alist[i] < alist[j]: + templist[k] = alist[i] + i=i+1 + else: + #we swap + templist[k] = alist[j] + j=j+1 + k=k+1 + + while i < mid: + templist[k] = alist[i] + i=i+1 + k=k+1 + + while j < end: + templist[k]=alist[j] + j=j+1 + k=k+1 + + #we copy the results + for k in range(length): + alist[start+k] = templist[k] + + #print("Merging ",alist[start:mid], alist[mid:end]) + +alist = [54,26,93,17,77,31,44,55,20] +indexMergeSort(alist) +print(alist) + + +# # 3 Benchmarking sorting algorithms + +# In[2]: + + +import random + +def generatelist(n, lower = 0, upper = 1000, seed = 0): + #https://docs.python.org/3/library/random.html + random.seed(seed) + l = [None] * n + for i in range(0,n): + l[i] = random.randrange(lower, upper) + return l + + +# In[3]: + + +print(generatelist(10)) + + +# Below we have copied the sorting functions from the online book: + +# In[4]: + + +def bubbleSort(alist): + for passnum in range(len(alist)-1,0,-1): + for i in range(passnum): + if alist[i]>alist[i+1]: + temp = alist[i] + alist[i] = alist[i+1] + alist[i+1] = temp + + +# In[5]: + + +def shortBubbleSort(alist): + exchanges = True + passnum = len(alist)-1 + while passnum > 0 and exchanges: + exchanges = False + for i in range(passnum): + if alist[i]>alist[i+1]: + exchanges = True + temp = alist[i] + alist[i] = alist[i+1] + alist[i+1] = temp + passnum = passnum-1 + + +# In[6]: + + +def selectionSort(alist): + for fillslot in range(len(alist)-1,0,-1): + positionOfMax=0 + for location in range(1,fillslot+1): + if alist[location]>alist[positionOfMax]: + positionOfMax = location + + temp = alist[fillslot] + alist[fillslot] = alist[positionOfMax] + alist[positionOfMax] = temp + + +# In[7]: + + +def insertionSort(alist): + for index in range(1,len(alist)): + + currentvalue = alist[index] + position = index + + while position>0 and alist[position-1]>currentvalue: + alist[position]=alist[position-1] + position = position-1 + + alist[position]=currentvalue + + +# In[8]: + + +def shellSort(alist): + sublistcount = len(alist)//2 + while sublistcount > 0: + + for startposition in range(sublistcount): + gapInsertionSort(alist,startposition,sublistcount) + + #print("After increments of size",sublistcount, + # "The list is",alist) + + sublistcount = sublistcount // 2 + +def gapInsertionSort(alist,start,gap): + for i in range(start+gap,len(alist),gap): + + currentvalue = alist[i] + position = i + + while position>=gap and alist[position-gap]>currentvalue: + alist[position]=alist[position-gap] + position = position-gap + + alist[position]=currentvalue + + +# In[9]: + + +def mergeSort(alist): + #print("Splitting ",alist) + if len(alist)>1: + mid = len(alist)//2 + lefthalf = alist[:mid] + righthalf = alist[mid:] + + mergeSort(lefthalf) + mergeSort(righthalf) + + i=0 + j=0 + k=0 + while i < len(lefthalf) and j < len(righthalf): + if lefthalf[i] < righthalf[j]: + alist[k]=lefthalf[i] + i=i+1 + else: + alist[k]=righthalf[j] + j=j+1 + k=k+1 + + while i < len(lefthalf): + alist[k]=lefthalf[i] + i=i+1 + k=k+1 + + while j < len(righthalf): + alist[k]=righthalf[j] + j=j+1 + k=k+1 + #print("Merging ",alist) + + +# In[10]: + + +def quickSort(alist): + quickSortHelper(alist,0,len(alist)-1) + +def quickSortHelper(alist,first,last): + if first= pivotvalue and rightmark >= leftmark: + rightmark = rightmark -1 + + if rightmark < leftmark: + done = True + else: + temp = alist[leftmark] + alist[leftmark] = alist[rightmark] + alist[rightmark] = temp + + temp = alist[first] + alist[first] = alist[rightmark] + alist[rightmark] = temp + + + return rightmark + + +# Now we benchmark them: + +# In[11]: + + +sorting_algorithms = [bubbleSort, shortBubbleSort, selectionSort, insertionSort, shellSort, mergeSort, indexMergeSort, quickSort] +#matplotlib.org/gallery/lines_bars_and_markers/line_styles_reference.html +styles = {} +styles[bubbleSort] = "r-" +styles[shortBubbleSort] = "r:" +styles[selectionSort] = "y-" +styles[insertionSort] = "g-" +styles[shellSort] = "g:" +styles[mergeSort] = "b--" +styles[indexMergeSort] = "b:" +styles[quickSort] = "y--" + + +# In[19]: + + +from timeit import default_timer as timer +import datetime +# matplotlib may need to be installed separately +import matplotlib.pyplot as plt + +def computeandplot(sorting_algorithms): + step = 100 + nsamples = 100 + samples = range(0, nsamples) + timelimit = 0.05 #seconds, per run + totaltime = 0 + print("Maximum computing time:", str(datetime.timedelta(seconds= timelimit*nsamples*len(sorting_algorithms)))) + for sortalgo in sorting_algorithms: + attimelimit = False + times = [timelimit for _ in samples] + for i in samples: + if i == 0: + times[i] = 0 + continue + n = step * i + if attimelimit == False: + l = generatelist(n) + start = timer() + sortalgo(l) + end = timer() + times[i] = end - start + totaltime += times[i] + if times[i] > timelimit: + times[i] = timelimit + attimelimit = True + + plt.plot(samples, times, styles[sortalgo], label=sortalgo.__name__) + print("Actual computing time:", str(datetime.timedelta(seconds=int(totaltime)))) + plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) + plt.xlabel("list size / {}".format(step)) + plt.ylabel("time in seconds") + plt.show() + +computeandplot(sorting_algorithms) + + +# # 4 Sorting small integers + +# **4.1** + +# In[13]: + + +def countsort(alist): + maxv = max(alist) + l = [0]*(maxv+1) + for i in alist: + l[i] += 1 + + k = 0 + for i in range(0, len(alist)): + while l[k] == 0: + k += 1 # we count the number of values = k in alist + alist[i] = k + l[k] -= 1 + + +# In[14]: + + +alist = [54,26,93,17,77,31,44,55,20] +countsort(alist) +print(alist) + + +# **4.2** + +# In[15]: + + + +import math + +DEFAULT_BUCKET_SIZE = 5 + +def bucketsort(array=alist, bucketSize=DEFAULT_BUCKET_SIZE): + if len(array) == 0: + return array + + # Determine minimum and maximum values + minValue = array[0] + maxValue = array[0] + for i in range(1, len(array)): + if array[i] < minValue: + minValue = array[i] + elif array[i] > maxValue: + maxValue = array[i] + + # Initialize buckets + bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1 + buckets = [] + for i in range(0, bucketCount): + buckets.append([]) + + # Distribute input array values into buckets + for i in range(0, len(array)): + buckets[math.floor((array[i] - minValue) / bucketSize)].append(array[i]) + + # Sort buckets and place back into input array + array = [] + for i in range(0, len(buckets)): + insertion_sort(buckets[i]) + for j in range(0, len(buckets[i])): + array.append(buckets[i][j]) + + return array + + +# In[16]: + + +def default_compare(a, b): + if a < b: + return -1 + elif a > b: + return 1 + return 0 + + +# In[17]: + + + +def insertion_sort(array): + for i in range(1, len(array)): + item = array[i] + indexHole = i + while indexHole > 0 and default_compare(array[indexHole - 1], item) > 0: + array[indexHole] = array[indexHole - 1] + indexHole -= 1 + array[indexHole] = item + return array + + +# In[18]: + + +new_sorting_algorithms = [bucketsort, indexMergeSort, quickSort] +styles[bucketsort] = "g--" +computeandplot(new_sorting_algorithms) +