From ae6fad986405a1d9ad36dbb9a0c47caa6aa18137 Mon Sep 17 00:00:00 2001 From: hustcc Date: Fri, 20 Jan 2017 14:01:54 +0800 Subject: [PATCH 01/52] update --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c06cb01..6f19756 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,8 @@ ---- -本书内容来源于: - - [https://wowphp.com/post/komxdx8qe862.html](https://wowphp.com/post/komxdx8qe862.html) - - [http://www.jcodecraeer.com/a/chengxusheji/shejimoshi/2015/0527/2941.html](http://www.jcodecraeer.com/a/chengxusheji/shejimoshi/2015/0527/2941.html) +本书内容几乎完全来源于网络。 -开源项目地址:[https://github.com/hustcc/JS-Sorting-Algorithm](https://github.com/hustcc/JS-Sorting-Algorithm) by [hustcc](https://github.com/hustcc) +开源项目地址:[https://github.com/hustcc/JS-Sorting-Algorithm](https://github.com/hustcc/JS-Sorting-Algorithm),整理人 [hustcc](https://github.com/hustcc)。 -GitHook 在线阅读地址:[https://sort.hust.cc/](https://sort.hust.cc/) \ No newline at end of file +GitHook 在线阅读地址:[https://sort.hust.cc/](https://sort.hust.cc/)。 \ No newline at end of file From 4a672429ba3e2d9b460845fcd0d10ab2d0887544 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:03:04 +0800 Subject: [PATCH 02/52] Add Python --- 1.bubbleSort.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/1.bubbleSort.md b/1.bubbleSort.md index d3871e0..f14d595 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -47,4 +47,16 @@ function bubbleSort(arr) { } return arr; } -``` \ No newline at end of file +``` + + +## 5. Python 代码实现 + +```python +def bubbleSort(arr): + for i in range(1, len(arr)): + for j in range(0, len(arr)-i): + if arr[j] > arr[j+1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + return arr +``` From 7834c2699ea129a3fbaa8a60991f859aa2ae1c91 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:05:42 +0800 Subject: [PATCH 03/52] Add Python --- 2.selectionSort.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/2.selectionSort.md b/2.selectionSort.md index b9011c1..e471732 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -36,4 +36,15 @@ function selectionSort(arr) { } return arr; } -``` \ No newline at end of file +``` + +## 4. Python 代码实现 + +```python +def selectionSort(arr): + for i in range(len(arr)-1): + for j in range(i+1, len(arr)): + if arr[j] < arr[i]: + arr[i], arr[j] = arr[j], arr[i] + return arr +``` From 9d302a208c180b2e9d6dfd037f300916666d7c47 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:07:03 +0800 Subject: [PATCH 04/52] Update 3.insertionSort.md --- 3.insertionSort.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/3.insertionSort.md b/3.insertionSort.md index a5f6e61..3a66a0f 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -34,4 +34,18 @@ function insertionSort(arr) { } return arr; } -``` \ No newline at end of file +``` + +## 3. Python 代码实现 + +```python +def insertionSort(arr): + for i in range(len(arr)): + preIndex = i-1 + current = arr[i] + while preIndex >= 0 and arr[preIndex] > current: + arr[preIndex+1] = arr[preIndex] + preIndex-=1 + arr[preIndex+1] = current +    return arr +''' From d41475ab7cdcc0fb178bad7ef630f07f08c4b800 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:07:56 +0800 Subject: [PATCH 05/52] Add Python --- 4.shellSort.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/4.shellSort.md b/4.shellSort.md index 4e9647e..ca07d5e 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -40,4 +40,25 @@ function shellSort(arr) { } return arr; } -``` \ No newline at end of file +``` + +## 2. Python 代码实现 + +```python +def shellSort(arr): + import math + gap=1 + while(gap < len(arr)/3): + gap = gap*3+1 + while gap > 0: + for i in range(gap,len(arr)): + temp = arr[i] + j = i-gap + while j >=0 and arr[j] > temp: + arr[j+gap]=arr[j] + j-=gap + arr[j+gap] = temp + gap = math.floor(gap/3) + return arr +} +``` From f3e55d5109e17ff3398a8d218b61882506c23390 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:09:25 +0800 Subject: [PATCH 06/52] Add Python --- 5.mergeSort.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/5.mergeSort.md b/5.mergeSort.md index c3d5c5e..8fabb83 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -70,4 +70,30 @@ function merge(left, right) return result; } -``` \ No newline at end of file +``` + +## 4. Python 代码实现 + +```python +def mergeSort(arr): + import math + if(len(arr)<2): + return arr + middle = math.floor(len(arr)/2) + left = arr[0:middle] + right = arr[middle:] + return merge(mergeSort(left), mergeSort(right)) + +def merge(left,right): + result = [] + while left and right: + if left[0] <= right[0]: + result.append(left.pop(0)); + else: + result.append(right.pop(0)); + while left: + result.append(left.pop(0)); + while right: + result.append(right.pop(0)); + return result +``` From cbc9a8ca49f2de0bbf6d55b058a0206788204290 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:15:16 +0800 Subject: [PATCH 07/52] Fix --- 5.mergeSort.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/5.mergeSort.md b/5.mergeSort.md index 8fabb83..1e71e09 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -72,7 +72,7 @@ function merge(left, right) } ``` -## 4. Python 代码实现 +## 5. Python 代码实现 ```python def mergeSort(arr): @@ -80,8 +80,7 @@ def mergeSort(arr): if(len(arr)<2): return arr middle = math.floor(len(arr)/2) - left = arr[0:middle] - right = arr[middle:] + left, right = arr[0:middle], arr[middle:] return merge(mergeSort(left), mergeSort(right)) def merge(left,right): From 25b3d4e02c6752bd0d1b92dfba5ca73bb2e73e76 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:15:56 +0800 Subject: [PATCH 08/52] Fix --- 4.shellSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4.shellSort.md b/4.shellSort.md index ca07d5e..802fe0d 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -42,7 +42,7 @@ function shellSort(arr) { } ``` -## 2. Python 代码实现 +## 3. Python 代码实现 ```python def shellSort(arr): From 1eb34183ad87342e45b1b0116eed27aae5d33e35 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 21:16:15 +0800 Subject: [PATCH 09/52] Update 3.insertionSort.md --- 3.insertionSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3.insertionSort.md b/3.insertionSort.md index 3a66a0f..be48d76 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -36,7 +36,7 @@ function insertionSort(arr) { } ``` -## 3. Python 代码实现 +## 4. Python 代码实现 ```python def insertionSort(arr): From e832ecef28ea4100e03c2dc365dceef44e95f2f8 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 22:57:10 +0800 Subject: [PATCH 10/52] Add Python --- 6.quickSort.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/6.quickSort.md b/6.quickSort.md index 4bdd11e..d5201ba 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -62,4 +62,34 @@ function swap(arr, i, j) { arr[i] = arr[j]; arr[j] = temp; } -``` \ No newline at end of file +``` + + +## 4. Python 代码实现 + +```python +def quickSort(arr, left=None, right=None): + left = 0 if not isinstance(left,(int, float)) else left + right = len(arr)-1 if not isinstance(right,(int, float)) else right + print(left,right) + if left < right: + partitionIndex = partition(arr, left, right) + quickSort(arr, left, partitionIndex-1) + quickSort(arr, partitionIndex+1, right) + return arr + +def partition(arr, left, right): + pivot = left + index = pivot+1 + i = index + while i <= right: + if arr[i] < arr[pivot]: + swap(arr, i, index) + index+=1 + i+=1 + swap(arr,pivot,index-1) + return index-1 + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] +``` From bb97a1e2005582f6973fa195832c82823c9be0d8 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 23:58:59 +0800 Subject: [PATCH 11/52] Add Python --- 7.heapSort.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/7.heapSort.md b/7.heapSort.md index f6e7e76..2b42e06 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -71,4 +71,38 @@ function heapSort(arr) { } return arr; } -``` \ No newline at end of file +``` +## 4. Python 代码实现 + +```python +def buildMaxHeap(arr): + import math + for i in range(math.floor(len(arr)/2),-1,-1): + heapify(arr,i) + +def heapify(arr, i): + left = 2*i+1 + right = 2*i+2 + largest = i + if left < arrLen and arr[left] > arr[largest]: + largest = left + if right < arrLen and arr[right] > arr[largest]: + largest = right + + if largest != i: + swap(arr, i, largest) + heapify(arr, largest) + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] + +def heapSort(arr): + global arrLen + arrLen = len(arr) + buildMaxHeap(arr) + for i in range(len(arr)-1,0,-1): + swap(arr,0,i) + arrLen -=1 + heapify(arr, 0) +    return arr +``` From d29ac91eec825cbd369a1e9b07febe9bf0a900e4 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sat, 21 Jan 2017 23:59:22 +0800 Subject: [PATCH 12/52] Fix --- 6.quickSort.md | 1 - 1 file changed, 1 deletion(-) diff --git a/6.quickSort.md b/6.quickSort.md index d5201ba..23f2881 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -71,7 +71,6 @@ function swap(arr, i, j) { def quickSort(arr, left=None, right=None): left = 0 if not isinstance(left,(int, float)) else left right = len(arr)-1 if not isinstance(right,(int, float)) else right - print(left,right) if left < right: partitionIndex = partition(arr, left, right) quickSort(arr, left, partitionIndex-1) From 4b2c21ffa7e23efaa10eca72ea059514708727f9 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sun, 22 Jan 2017 00:56:30 +0800 Subject: [PATCH 13/52] Add Python --- 8.countingSort.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/8.countingSort.md b/8.countingSort.md index c73909a..3beec64 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -32,4 +32,23 @@ function countingSort(arr, maxValue) { return arr; } -``` \ No newline at end of file +``` +## 3. JavaScript 代码实现 + +```python +def countingSort(arr, maxValue): + bucketLen = maxValue+1 + bucket = [0]*bucketLen + sortedIndex =0 + arrLen = len(arr) + for i in range(arrLen): + if not bucket[arr[i]]: + bucket[arr[i]]=0 + bucket[arr[i]]+=1 + for j in range(bucketLen): + while bucket[j]>0: + arr[sortedIndex] = j + sortedIndex+=1 + bucket[j]-=1 + return arr +``` From 76b6e0353dba0505daa7ba5e50c32fd969d4a1ca Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sun, 22 Jan 2017 13:04:17 +0800 Subject: [PATCH 14/52] Create pythonSortTest.py --- pythonSortTest.py | 165 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 pythonSortTest.py diff --git a/pythonSortTest.py b/pythonSortTest.py new file mode 100644 index 0000000..eb5b137 --- /dev/null +++ b/pythonSortTest.py @@ -0,0 +1,165 @@ +''' +# Create by LokiSharp(loki.sharp#gmail) at 2017-1-22 +''' + +TOTAL=5000 + +def sortTest(func, total=1000): + import random, copy, operator, math, time + arrList = [i for i in range(-math.floor(total/2),math.ceil(total/2))] + arrListR = copy.deepcopy(arrList) + while operator.eq(arrList,arrListR): + random.shuffle(arrListR) + #print("--- [Origin List]", arrList, "Use", func.__name__,"with Total:", len(arrList)) + #print("--> [Random List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) + start = time.clock() + arrListR = func(arrListR) + end = time.clock() + runtime = end-start + #print("--> [Sorted List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) + if operator.eq(arrList, arrListR): + print("[Success]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) + return True + else: + print("[Fail]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) + return False + +def bubbleSort(arr): + for i in range(1, len(arr)): + for j in range(0, len(arr)-i): + if arr[j] > arr[j+1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + return arr + +def selectionSort(arr): + for i in range(len(arr)-1): + for j in range(i+1, len(arr)): + if arr[j] < arr[i]: + arr[i], arr[j] = arr[j], arr[i] + return arr + +def insertionSort(arr): + for i in range(len(arr)): + preIndex = i-1 + current = arr[i] + while preIndex >= 0 and arr[preIndex] > current: + arr[preIndex+1] = arr[preIndex] + preIndex-=1 + arr[preIndex+1] = current + return arr + +def shellSort(arr): + import math + gap=1 + while(gap < len(arr)/3): + gap = gap*3+1 + while gap > 0: + for i in range(gap,len(arr)): + temp = arr[i] + j = i-gap + while j >=0 and arr[j] > temp: + arr[j+gap]=arr[j] + j-=gap + arr[j+gap] = temp + gap = math.floor(gap/3) + return arr + +def mergeSort(arr): + import math + if(len(arr)<2): + return arr + middle = math.floor(len(arr)/2) + left, right = arr[0:middle], arr[middle:] + return merge(mergeSort(left), mergeSort(right)) + +def merge(left,right): + result = [] + while left and right: + if left[0] <= right[0]: + result.append(left.pop(0)); + else: + result.append(right.pop(0)); + while left: + result.append(left.pop(0)); + while right: + result.append(right.pop(0)); + return result + +def quickSort(arr, left=None, right=None): + left = 0 if not isinstance(left,(int, float)) else left + right = len(arr)-1 if not isinstance(right,(int, float)) else right + if left < right: + partitionIndex = partition(arr, left, right) + quickSort(arr, left, partitionIndex-1) + quickSort(arr, partitionIndex+1, right) + return arr + +def partition(arr, left, right): + pivot = left + index = pivot+1 + i = index + while i <= right: + if arr[i] < arr[pivot]: + swap(arr, i, index) + index+=1 + i+=1 + swap(arr,pivot,index-1) + return index-1 + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] + +def buildMaxHeap(arr): + import math + for i in range(math.floor(len(arr)/2),-1,-1): + heapify(arr,i) + +def heapify(arr, i): + left = 2*i+1 + right = 2*i+2 + largest = i + if left < arrLen and arr[left] > arr[largest]: + largest = left + if right < arrLen and arr[right] > arr[largest]: + largest = right + + if largest != i: + swap(arr, i, largest) + heapify(arr, largest) + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] + +def heapSort(arr): + global arrLen + arrLen = len(arr) + buildMaxHeap(arr) + for i in range(len(arr)-1,0,-1): + swap(arr,0,i) + arrLen -=1 + heapify(arr, 0) + return arr + +def countingSort(arr, maxValue=None): + bucketLen = maxValue+1 + bucket = [0]*bucketLen + sortedIndex =0 + arrLen = len(arr) + for i in range(arrLen): + if not bucket[arr[i]]: + bucket[arr[i]]=0 + bucket[arr[i]]+=1 + for j in range(bucketLen): + while bucket[j]>0: + arr[sortedIndex] = j + sortedIndex+=1 + bucket[j]-=1 + return arr + +sortTest(bubbleSort, TOTAL) +sortTest(selectionSort, TOTAL) +sortTest(insertionSort, TOTAL) +sortTest(shellSort, TOTAL) +sortTest(mergeSort, TOTAL) +sortTest(quickSort, TOTAL) +sortTest(heapSort, TOTAL) From 06626459852bace797d201ed5e42273addd072f2 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sun, 22 Jan 2017 13:04:50 +0800 Subject: [PATCH 15/52] Update 3.insertionSort.md --- 3.insertionSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3.insertionSort.md b/3.insertionSort.md index be48d76..008bbd1 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -48,4 +48,4 @@ def insertionSort(arr): preIndex-=1 arr[preIndex+1] = current    return arr -''' +``` From 17fd2649f61043a4ff24040f54056683a26b3177 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sun, 22 Jan 2017 14:33:46 +0800 Subject: [PATCH 16/52] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E7=9A=84=20Python=20=E5=AE=9E=E7=8E=B0=EF=BC=881~5=EF=BC=89=20?= =?UTF-8?q?(#2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Python * Add Python * Update 3.insertionSort.md * Add Python * Add Python * Fix * Fix * Update 3.insertionSort.md * Add Python * Add Python * Fix * Add Python * Create pythonSortTest.py * Update 3.insertionSort.md --- 1.bubbleSort.md | 14 +++- 2.selectionSort.md | 13 +++- 3.insertionSort.md | 16 ++++- 4.shellSort.md | 23 ++++++- 5.mergeSort.md | 27 +++++++- 6.quickSort.md | 31 ++++++++- 7.heapSort.md | 36 +++++++++- 8.countingSort.md | 21 +++++- pythonSortTest.py | 165 +++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 338 insertions(+), 8 deletions(-) create mode 100644 pythonSortTest.py diff --git a/1.bubbleSort.md b/1.bubbleSort.md index d3871e0..f14d595 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -47,4 +47,16 @@ function bubbleSort(arr) { } return arr; } -``` \ No newline at end of file +``` + + +## 5. Python 代码实现 + +```python +def bubbleSort(arr): + for i in range(1, len(arr)): + for j in range(0, len(arr)-i): + if arr[j] > arr[j+1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + return arr +``` diff --git a/2.selectionSort.md b/2.selectionSort.md index b9011c1..e471732 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -36,4 +36,15 @@ function selectionSort(arr) { } return arr; } -``` \ No newline at end of file +``` + +## 4. Python 代码实现 + +```python +def selectionSort(arr): + for i in range(len(arr)-1): + for j in range(i+1, len(arr)): + if arr[j] < arr[i]: + arr[i], arr[j] = arr[j], arr[i] + return arr +``` diff --git a/3.insertionSort.md b/3.insertionSort.md index a5f6e61..008bbd1 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -34,4 +34,18 @@ function insertionSort(arr) { } return arr; } -``` \ No newline at end of file +``` + +## 4. Python 代码实现 + +```python +def insertionSort(arr): + for i in range(len(arr)): + preIndex = i-1 + current = arr[i] + while preIndex >= 0 and arr[preIndex] > current: + arr[preIndex+1] = arr[preIndex] + preIndex-=1 + arr[preIndex+1] = current +    return arr +``` diff --git a/4.shellSort.md b/4.shellSort.md index 4e9647e..802fe0d 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -40,4 +40,25 @@ function shellSort(arr) { } return arr; } -``` \ No newline at end of file +``` + +## 3. Python 代码实现 + +```python +def shellSort(arr): + import math + gap=1 + while(gap < len(arr)/3): + gap = gap*3+1 + while gap > 0: + for i in range(gap,len(arr)): + temp = arr[i] + j = i-gap + while j >=0 and arr[j] > temp: + arr[j+gap]=arr[j] + j-=gap + arr[j+gap] = temp + gap = math.floor(gap/3) + return arr +} +``` diff --git a/5.mergeSort.md b/5.mergeSort.md index c3d5c5e..1e71e09 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -70,4 +70,29 @@ function merge(left, right) return result; } -``` \ No newline at end of file +``` + +## 5. Python 代码实现 + +```python +def mergeSort(arr): + import math + if(len(arr)<2): + return arr + middle = math.floor(len(arr)/2) + left, right = arr[0:middle], arr[middle:] + return merge(mergeSort(left), mergeSort(right)) + +def merge(left,right): + result = [] + while left and right: + if left[0] <= right[0]: + result.append(left.pop(0)); + else: + result.append(right.pop(0)); + while left: + result.append(left.pop(0)); + while right: + result.append(right.pop(0)); + return result +``` diff --git a/6.quickSort.md b/6.quickSort.md index 4bdd11e..23f2881 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -62,4 +62,33 @@ function swap(arr, i, j) { arr[i] = arr[j]; arr[j] = temp; } -``` \ No newline at end of file +``` + + +## 4. Python 代码实现 + +```python +def quickSort(arr, left=None, right=None): + left = 0 if not isinstance(left,(int, float)) else left + right = len(arr)-1 if not isinstance(right,(int, float)) else right + if left < right: + partitionIndex = partition(arr, left, right) + quickSort(arr, left, partitionIndex-1) + quickSort(arr, partitionIndex+1, right) + return arr + +def partition(arr, left, right): + pivot = left + index = pivot+1 + i = index + while i <= right: + if arr[i] < arr[pivot]: + swap(arr, i, index) + index+=1 + i+=1 + swap(arr,pivot,index-1) + return index-1 + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] +``` diff --git a/7.heapSort.md b/7.heapSort.md index f6e7e76..2b42e06 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -71,4 +71,38 @@ function heapSort(arr) { } return arr; } -``` \ No newline at end of file +``` +## 4. Python 代码实现 + +```python +def buildMaxHeap(arr): + import math + for i in range(math.floor(len(arr)/2),-1,-1): + heapify(arr,i) + +def heapify(arr, i): + left = 2*i+1 + right = 2*i+2 + largest = i + if left < arrLen and arr[left] > arr[largest]: + largest = left + if right < arrLen and arr[right] > arr[largest]: + largest = right + + if largest != i: + swap(arr, i, largest) + heapify(arr, largest) + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] + +def heapSort(arr): + global arrLen + arrLen = len(arr) + buildMaxHeap(arr) + for i in range(len(arr)-1,0,-1): + swap(arr,0,i) + arrLen -=1 + heapify(arr, 0) +    return arr +``` diff --git a/8.countingSort.md b/8.countingSort.md index c73909a..3beec64 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -32,4 +32,23 @@ function countingSort(arr, maxValue) { return arr; } -``` \ No newline at end of file +``` +## 3. JavaScript 代码实现 + +```python +def countingSort(arr, maxValue): + bucketLen = maxValue+1 + bucket = [0]*bucketLen + sortedIndex =0 + arrLen = len(arr) + for i in range(arrLen): + if not bucket[arr[i]]: + bucket[arr[i]]=0 + bucket[arr[i]]+=1 + for j in range(bucketLen): + while bucket[j]>0: + arr[sortedIndex] = j + sortedIndex+=1 + bucket[j]-=1 + return arr +``` diff --git a/pythonSortTest.py b/pythonSortTest.py new file mode 100644 index 0000000..eb5b137 --- /dev/null +++ b/pythonSortTest.py @@ -0,0 +1,165 @@ +''' +# Create by LokiSharp(loki.sharp#gmail) at 2017-1-22 +''' + +TOTAL=5000 + +def sortTest(func, total=1000): + import random, copy, operator, math, time + arrList = [i for i in range(-math.floor(total/2),math.ceil(total/2))] + arrListR = copy.deepcopy(arrList) + while operator.eq(arrList,arrListR): + random.shuffle(arrListR) + #print("--- [Origin List]", arrList, "Use", func.__name__,"with Total:", len(arrList)) + #print("--> [Random List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) + start = time.clock() + arrListR = func(arrListR) + end = time.clock() + runtime = end-start + #print("--> [Sorted List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) + if operator.eq(arrList, arrListR): + print("[Success]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) + return True + else: + print("[Fail]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) + return False + +def bubbleSort(arr): + for i in range(1, len(arr)): + for j in range(0, len(arr)-i): + if arr[j] > arr[j+1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + return arr + +def selectionSort(arr): + for i in range(len(arr)-1): + for j in range(i+1, len(arr)): + if arr[j] < arr[i]: + arr[i], arr[j] = arr[j], arr[i] + return arr + +def insertionSort(arr): + for i in range(len(arr)): + preIndex = i-1 + current = arr[i] + while preIndex >= 0 and arr[preIndex] > current: + arr[preIndex+1] = arr[preIndex] + preIndex-=1 + arr[preIndex+1] = current + return arr + +def shellSort(arr): + import math + gap=1 + while(gap < len(arr)/3): + gap = gap*3+1 + while gap > 0: + for i in range(gap,len(arr)): + temp = arr[i] + j = i-gap + while j >=0 and arr[j] > temp: + arr[j+gap]=arr[j] + j-=gap + arr[j+gap] = temp + gap = math.floor(gap/3) + return arr + +def mergeSort(arr): + import math + if(len(arr)<2): + return arr + middle = math.floor(len(arr)/2) + left, right = arr[0:middle], arr[middle:] + return merge(mergeSort(left), mergeSort(right)) + +def merge(left,right): + result = [] + while left and right: + if left[0] <= right[0]: + result.append(left.pop(0)); + else: + result.append(right.pop(0)); + while left: + result.append(left.pop(0)); + while right: + result.append(right.pop(0)); + return result + +def quickSort(arr, left=None, right=None): + left = 0 if not isinstance(left,(int, float)) else left + right = len(arr)-1 if not isinstance(right,(int, float)) else right + if left < right: + partitionIndex = partition(arr, left, right) + quickSort(arr, left, partitionIndex-1) + quickSort(arr, partitionIndex+1, right) + return arr + +def partition(arr, left, right): + pivot = left + index = pivot+1 + i = index + while i <= right: + if arr[i] < arr[pivot]: + swap(arr, i, index) + index+=1 + i+=1 + swap(arr,pivot,index-1) + return index-1 + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] + +def buildMaxHeap(arr): + import math + for i in range(math.floor(len(arr)/2),-1,-1): + heapify(arr,i) + +def heapify(arr, i): + left = 2*i+1 + right = 2*i+2 + largest = i + if left < arrLen and arr[left] > arr[largest]: + largest = left + if right < arrLen and arr[right] > arr[largest]: + largest = right + + if largest != i: + swap(arr, i, largest) + heapify(arr, largest) + +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] + +def heapSort(arr): + global arrLen + arrLen = len(arr) + buildMaxHeap(arr) + for i in range(len(arr)-1,0,-1): + swap(arr,0,i) + arrLen -=1 + heapify(arr, 0) + return arr + +def countingSort(arr, maxValue=None): + bucketLen = maxValue+1 + bucket = [0]*bucketLen + sortedIndex =0 + arrLen = len(arr) + for i in range(arrLen): + if not bucket[arr[i]]: + bucket[arr[i]]=0 + bucket[arr[i]]+=1 + for j in range(bucketLen): + while bucket[j]>0: + arr[sortedIndex] = j + sortedIndex+=1 + bucket[j]-=1 + return arr + +sortTest(bubbleSort, TOTAL) +sortTest(selectionSort, TOTAL) +sortTest(insertionSort, TOTAL) +sortTest(shellSort, TOTAL) +sortTest(mergeSort, TOTAL) +sortTest(quickSort, TOTAL) +sortTest(heapSort, TOTAL) From 0097c9f201cf7a32aba7c053c20e3a14781d996a Mon Sep 17 00:00:00 2001 From: hustcc Date: Sun, 22 Jan 2017 18:38:43 +0800 Subject: [PATCH 17/52] add markdown hint test --- .travis.yml | 21 +++++++++++++++++++++ README.md | 2 +- pythonSortTest.py => test/pythonSortTest.py | 0 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 .travis.yml rename pythonSortTest.py => test/pythonSortTest.py (100%) diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..228b57e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +sudo: required +language: python +python: + - "2.7" +before_install: + - pip install flake8 + - pip install hint +script: + - flake8 + - hint README.md + - hint SUMMARY.md + - hint 1.bubbleSort.md + - hint 2.selectionSort.md + - hint 3.insertionSort.md + - hint 4.shellSort.md + - hint 5.mergeSort.md + - hint 6.quickSort.md + - hint 7.heapSort.md + - hint 8.countingSort.md + - hint 9.bucketSort.md + - hint 10.radixSort.md \ No newline at end of file diff --git a/README.md b/README.md index 6f19756..bbab7d6 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ **Out-place**:占用额外内存 -**稳定性**:排序后2个相等键值的顺序和排序之前它们的顺序相同 +**稳定性**:排序后 2 个相等键值的顺序和排序之前它们的顺序相同 ---- diff --git a/pythonSortTest.py b/test/pythonSortTest.py similarity index 100% rename from pythonSortTest.py rename to test/pythonSortTest.py From ce15295ae49cca181f1ba09076b6b791eeaace0d Mon Sep 17 00:00:00 2001 From: hustcc Date: Sun, 22 Jan 2017 18:49:09 +0800 Subject: [PATCH 18/52] fixed markdown typo --- 1.bubbleSort.md | 4 ++-- 10.radixSort.md | 2 +- 4.shellSort.md | 6 +++--- 5.mergeSort.md | 6 +++--- 6.quickSort.md | 4 ++-- 7.heapSort.md | 2 +- 9.bucketSort.md | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/1.bubbleSort.md b/1.bubbleSort.md index f14d595..684efd6 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -28,7 +28,7 @@ ## 4. 什么时候最慢 -当输入的数据是反序时(写一个for循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗)。 +当输入的数据是反序时(写一个 for 循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗)。 ## 5. JavaScript 代码实现 @@ -50,7 +50,7 @@ function bubbleSort(arr) { ``` -## 5. Python 代码实现 +## 6. Python 代码实现 ```python def bubbleSort(arr): diff --git a/10.radixSort.md b/10.radixSort.md index 009f856..5f40ea7 100644 --- a/10.radixSort.md +++ b/10.radixSort.md @@ -14,7 +14,7 @@ - 桶排序:每个桶存储一定范围的数值; -## 2. LSD基数排序动图演示 +## 2. LSD 基数排序动图演示 ![动图演示](res/radixSort.gif) diff --git a/4.shellSort.md b/4.shellSort.md index 802fe0d..a41c1eb 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -4,15 +4,15 @@ 希尔排序是基于插入排序的以下两点性质而提出改进方法的: - - 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率 - - 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位 + - 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率 + - 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。 ## 1. 算法步骤 -1. 选择一个增量序列t1,t2,…,tk,其中 ti > tj,tk=1; +1. 选择一个增量序列 t1,t2,…,tk,其中 ti > tj,tk=1; 2. 按增量序列个数 k,对序列进行 k 趟排序; diff --git a/5.mergeSort.md b/5.mergeSort.md index 1e71e09..f9eb090 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -3,10 +3,10 @@ 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法: - - 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第2种方法); + - 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法); - 自下而上的迭代; -在《数据结构与算法JavaScript描述》中,作者给出了自下而上的迭代方法。但是对于递归法,作者却认为: +在《数据结构与算法 JavaScript 描述》中,作者给出了自下而上的迭代方法。但是对于递归法,作者却认为: > However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle. > @@ -26,7 +26,7 @@ 3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置; -4. 重复步骤3直到某一指针达到序列尾; +4. 重复步骤 3 直到某一指针达到序列尾; 5. 将另一序列剩下的所有元素直接复制到合并序列尾。 diff --git a/6.quickSort.md b/6.quickSort.md index 23f2881..01f410d 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -6,9 +6,9 @@ 快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。 -快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高! 它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了N多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案: +快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高! 它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案: -> 快速排序的最坏运行情况是O(n²),比如说顺序数列的快排。但它的平摊期望时间是O(n log n) ,且O(n log n)记号中隐含的常数因子很小,比复杂度稳定等于O(n log n)的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。 +> 快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。 ## 1. 算法步骤 diff --git a/7.heapSort.md b/7.heapSort.md index 2b42e06..a6a91d8 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -5,7 +5,7 @@ 1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列; 2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列; -堆排序的平均时间复杂度为Ο(nlogn) 。 +堆排序的平均时间复杂度为 Ο(nlogn)。 ## 1. 算法步骤 diff --git a/9.bucketSort.md b/9.bucketSort.md index 5e45f36..30966f4 100644 --- a/9.bucketSort.md +++ b/9.bucketSort.md @@ -3,7 +3,7 @@ 桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点: 1. 在额外空间充足的情况下,尽量增大桶的数量 -2. 使用的映射函数能够将输入的N个数据均匀的分配到K个桶中 +2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中 同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。 From 1a3b1e6c4926a6b70e6670a6855f5c2c7298a672 Mon Sep 17 00:00:00 2001 From: hustcc Date: Sun, 22 Jan 2017 18:51:07 +0800 Subject: [PATCH 19/52] rm flake8 --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 228b57e..7b5d4e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,8 @@ language: python python: - "2.7" before_install: - - pip install flake8 - pip install hint script: - - flake8 - hint README.md - hint SUMMARY.md - hint 1.bubbleSort.md From b02b51601f9395bf28d5a83e0ed0318c6e95e404 Mon Sep 17 00:00:00 2001 From: hustcc Date: Sun, 22 Jan 2017 18:55:14 +0800 Subject: [PATCH 20/52] add build status --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bbab7d6..d8df556 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # 十大经典排序算法 +[![Build Status](https://travis-ci.org/hustcc/JS-Sorting-Algorithm.svg?branch=master)](https://travis-ci.org/hustcc/JS-Sorting-Algorithm) + 排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:**插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序**等。用一张图概括: From 1367764e7ae6586fa5ed04c9a1f74ef6df9853e2 Mon Sep 17 00:00:00 2001 From: LokiSharp Date: Sun, 22 Jan 2017 20:46:50 +0800 Subject: [PATCH 21/52] Update 8.countingSort.md --- 8.countingSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8.countingSort.md b/8.countingSort.md index 3beec64..a88c7d9 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -33,7 +33,7 @@ function countingSort(arr, maxValue) { return arr; } ``` -## 3. JavaScript 代码实现 +## 3. Python 代码实现 ```python def countingSort(arr, maxValue): From 937d26d0a0bc43c9e77f33c0766b26ab9886a01e Mon Sep 17 00:00:00 2001 From: hustcc Date: Mon, 23 Jan 2017 13:08:09 +0800 Subject: [PATCH 22/52] =?UTF-8?q?update=20hint=20=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 13 +------------ 1.bubbleSort.md | 1 - 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b5d4e3..b2b108c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,15 +5,4 @@ python: before_install: - pip install hint script: - - hint README.md - - hint SUMMARY.md - - hint 1.bubbleSort.md - - hint 2.selectionSort.md - - hint 3.insertionSort.md - - hint 4.shellSort.md - - hint 5.mergeSort.md - - hint 6.quickSort.md - - hint 7.heapSort.md - - hint 8.countingSort.md - - hint 9.bucketSort.md - - hint 10.radixSort.md \ No newline at end of file + - hint . \ No newline at end of file diff --git a/1.bubbleSort.md b/1.bubbleSort.md index 0e8b758..e73bce5 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -53,7 +53,6 @@ function bubbleSort(arr) { ## 6. Python 代码实现 - ```python def bubbleSort(arr): for i in range(1, len(arr)): From 7dfc58af6649f2465781b07ba88aacb3bd48e7a7 Mon Sep 17 00:00:00 2001 From: BONFY Date: Mon, 6 Feb 2017 18:25:28 +0800 Subject: [PATCH 23/52] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86Go=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=881-6=EF=BC=89=20(#5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add go code 1-6 * add 7&8 --- 1.bubbleSort.md | 16 +++ 2.selectionSort.md | 18 ++++ 3.insertionSort.md | 16 +++ 4.shellSort.md | 25 +++++ 5.mergeSort.md | 42 +++++++- 6.quickSort.md | 35 +++++++ 7.heapSort.md | 41 ++++++++ 8.countingSort.md | 26 +++++ goSortTest.go | 240 +++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 458 insertions(+), 1 deletion(-) create mode 100755 goSortTest.go diff --git a/1.bubbleSort.md b/1.bubbleSort.md index e73bce5..49805e7 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -61,3 +61,19 @@ def bubbleSort(arr): arr[j], arr[j + 1] = arr[j + 1], arr[j] return arr ``` + +## 7. Go 代码实现 + +```go +func bubbleSort(arr []int) []int { + length := len(arr) + for i := 0; i < length; i++ { + for j := 0; j < length-1-i; j++ { + if arr[j] > arr[j+1] { + arr[j], arr[j+1] = arr[j+1], arr[j] + } + } + } + return arr +} +``` diff --git a/2.selectionSort.md b/2.selectionSort.md index e471732..5364bc5 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -48,3 +48,21 @@ def selectionSort(arr): arr[i], arr[j] = arr[j], arr[i] return arr ``` + +## 5. Go 代码实现 + +```go +func selectionSort(arr []int) []int { + length := len(arr) + for i := 0; i < length-1; i++ { + min := i + for j := i + 1; j < length; j++ { + if arr[min] > arr[j] { + min = j + } + } + arr[i], arr[min] = arr[min], arr[i] + } + return arr +} +``` diff --git a/3.insertionSort.md b/3.insertionSort.md index 008bbd1..11ed672 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -49,3 +49,19 @@ def insertionSort(arr): arr[preIndex+1] = current    return arr ``` + +## 5. Go 代码实现 +```go +func insertionSort(arr []int) []int { + for i := range arr { + preIndex := i - 1 + current := arr[i] + for preIndex >= 0 && arr[preIndex] > current { + arr[preIndex+1] = arr[preIndex] + preIndex -= 1 + } + arr[preIndex+1] = current + } + return arr +} +``` diff --git a/4.shellSort.md b/4.shellSort.md index a41c1eb..97de9c0 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -62,3 +62,28 @@ def shellSort(arr): return arr } ``` + +## 4. Go 代码实现 + +```go +func shellSort(arr []int) []int { + length := len(arr) + gap := 1 + for gap < gap/3 { + gap = gap*3 + 1 + } + for gap > 0 { + for i := gap; i < length; i++ { + temp := arr[i] + j := i - gap + for j >= 0 && arr[j] > temp { + arr[j+gap] = arr[j] + j -= gap + } + arr[j+gap] = temp + } + gap = gap / 3 + } + return arr +} +``` diff --git a/5.mergeSort.md b/5.mergeSort.md index f9eb090..ea82d6c 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -9,7 +9,7 @@ 在《数据结构与算法 JavaScript 描述》中,作者给出了自下而上的迭代方法。但是对于递归法,作者却认为: > However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle. -> +> > 然而,在 JavaScript 中这种方式不太可行,因为这个算法的递归深度对它来讲太深了。 @@ -96,3 +96,43 @@ def merge(left,right): result.append(right.pop(0)); return result ``` + +## 6. Go 代码实现 + +```go +func mergeSort(arr []int) []int { + length := len(arr) + if length < 2 { + return arr + } + middle := length / 2 + left := arr[0:middle] + right := arr[middle:] + return merge(mergeSort(left), mergeSort(right)) +} + +func merge(left []int, right []int) []int { + var result []int + for len(left) != 0 && len(right) != 0 { + if left[0] <= right[0] { + result = append(result, left[0]) + left = left[1:] + } else { + result = append(result, right[0]) + right = right[1:] + } + } + + for len(left) != 0 { + result = append(result, left[0]) + left = left[1:] + } + + for len(right) != 0 { + result = append(result, right[0]) + right = right[1:] + } + + return result +} +``` diff --git a/6.quickSort.md b/6.quickSort.md index 01f410d..11696e6 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -92,3 +92,38 @@ def partition(arr, left, right): def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i] ``` + +## 5. Go 代码实现 + +```go +func quickSort(arr []int) []int { + return _quickSort(arr, 0, len(arr)-1) +} + +func _quickSort(arr []int, left, right int) []int { + if left < right { + partitionIndex := partition(arr, left, right) + _quickSort(arr, left, partitionIndex-1) + _quickSort(arr, partitionIndex+1, right) + } + return arr +} + +func partition(arr []int, left, right int) int { + pivot := left + index := pivot + 1 + + for i := index; i <= right; i++ { + if arr[i] < arr[pivot] { + swap(arr, i, index) + index += 1 + } + } + swap(arr, pivot, index-1) + return index - 1 +} + +func swap(arr []int, i, j int) { + arr[i], arr[j] = arr[j], arr[i] +} +``` diff --git a/7.heapSort.md b/7.heapSort.md index a6a91d8..7ce6ade 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -106,3 +106,44 @@ def heapSort(arr): heapify(arr, 0)    return arr ``` + +## 5. Go 代码实现 + +```go +func heapSort(arr []int) []int { + arrLen := len(arr) + buildMaxHeap(arr, arrLen) + for i := arrLen - 1; i >= 0; i-- { + swap(arr, 0, i) + arrLen -= 1 + heapify(arr, 0, arrLen) + } + return arr +} + +func buildMaxHeap(arr []int, arrLen int) { + for i := arrLen / 2; i >= 0; i-- { + heapify(arr, i, arrLen) + } +} + +func heapify(arr []int, i, arrLen int) { + left := 2*i + 1 + right := 2*i + 2 + largest := i + if left < arrLen && arr[left] > arr[largest] { + largest = left + } + if right < arrLen && arr[right] > arr[largest] { + largest = right + } + if largest != i { + swap(arr, i, largest) + heapify(arr, largest, arrLen) + } +} + +func swap(arr []int, i, j int) { + arr[i], arr[j] = arr[j], arr[i] +} +``` diff --git a/8.countingSort.md b/8.countingSort.md index 4d8f41b..164d3ac 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -54,3 +54,29 @@ def countingSort(arr, maxValue): bucket[j]-=1 return arr ``` + +## 4. Go 代码实现 + +```go +func countingSort(arr []int, maxValue int) []int { + bucketLen := maxValue + 1 + bucket := make([]int, bucketLen) // 初始为0的数组 + + sortedIndex := 0 + length := len(arr) + + for i := 0; i < length; i++ { + bucket[arr[i]] += 1 + } + + for j := 0; j < bucketLen; j++ { + for bucket[j] > 0 { + arr[sortedIndex] = j + sortedIndex += 1 + bucket[j] -= 1 + } + } + + return arr +} +``` diff --git a/goSortTest.go b/goSortTest.go new file mode 100755 index 0000000..3738cf0 --- /dev/null +++ b/goSortTest.go @@ -0,0 +1,240 @@ +package main + +import ( + "fmt" + "math/rand" + "time" +) + +/* global varialbe for heapsort*/ +var arrLen int + +// 初始化 array with num +func initArray(num int) []int { + if num < 1 { + panic("num must bigger than 1") + } + + arr := make([]int, num) + middle := num / 2 + // fmt.Println("middle :", middle) + for i, _ := range arr { + arr[i] = i - middle + } + return arr +} + +// 比较 sort 前后数组是否相同 +func compare(arr1 []int, arr2 []int) bool { + if len(arr1) != len(arr2) { + return false + } + + for i, _ := range arr1 { + if arr1[i] != arr2[i] { + return false + } + } + + return true +} + +// 测试 sort func 是否有效 +func test_func(num int, sort func(arr []int) []int) { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + src := initArray(num) + dest := make([]int, len(src)) + perm := r.Perm(len(src)) + for i, v := range perm { + dest[v] = src[i] + } + + // fmt.Println(src) + // fmt.Println(dest) + result := sort(dest) + // fmt.Println(result) + + if compare(src, result) { + fmt.Println("Test passed") + } else { + fmt.Println("Test failed") + } +} + +// bubble sort +func bubbleSort(arr []int) []int { + length := len(arr) + for i := 0; i < length; i++ { + for j := 0; j < length-1-i; j++ { + if arr[j] > arr[j+1] { + arr[j], arr[j+1] = arr[j+1], arr[j] + } + } + } + return arr +} + +// selection sort +func selectionSort(arr []int) []int { + length := len(arr) + for i := 0; i < length-1; i++ { + min := i + for j := i + 1; j < length; j++ { + if arr[min] > arr[j] { + min = j + } + } + arr[i], arr[min] = arr[min], arr[i] + } + return arr +} + +// insertion sort +func insertionSort(arr []int) []int { + for i := range arr { + preIndex := i - 1 + current := arr[i] + for preIndex >= 0 && arr[preIndex] > current { + arr[preIndex+1] = arr[preIndex] + preIndex -= 1 + } + arr[preIndex+1] = current + } + return arr +} + +// shellsort +func shellSort(arr []int) []int { + length := len(arr) + gap := 1 + for gap < gap/3 { + gap = gap*3 + 1 + } + for gap > 0 { + for i := gap; i < length; i++ { + temp := arr[i] + j := i - gap + for j >= 0 && arr[j] > temp { + arr[j+gap] = arr[j] + j -= gap + } + arr[j+gap] = temp + } + gap = gap / 3 + } + return arr +} + +// merge sort +func mergeSort(arr []int) []int { + length := len(arr) + if length < 2 { + return arr + } + middle := length / 2 + left := arr[0:middle] + right := arr[middle:] + return merge(mergeSort(left), mergeSort(right)) +} + +func merge(left []int, right []int) []int { + var result []int + for len(left) != 0 && len(right) != 0 { + if left[0] <= right[0] { + result = append(result, left[0]) + left = left[1:] + } else { + result = append(result, right[0]) + right = right[1:] + } + } + + for len(left) != 0 { + result = append(result, left[0]) + left = left[1:] + } + + for len(right) != 0 { + result = append(result, right[0]) + right = right[1:] + } + + return result +} + +// quicksort +func quickSort(arr []int) []int { + return _quickSort(arr, 0, len(arr)-1) +} + +func _quickSort(arr []int, left, right int) []int { + if left < right { + partitionIndex := partition(arr, left, right) + _quickSort(arr, left, partitionIndex-1) + _quickSort(arr, partitionIndex+1, right) + } + return arr +} + +func partition(arr []int, left, right int) int { + pivot := left + index := pivot + 1 + + for i := index; i <= right; i++ { + if arr[i] < arr[pivot] { + swap(arr, i, index) + index += 1 + } + } + swap(arr, pivot, index-1) + return index - 1 +} + +// heap sort +func heapSort(arr []int) []int { + arrLen := len(arr) + buildMaxHeap(arr, arrLen) + for i := arrLen - 1; i >= 0; i-- { + swap(arr, 0, i) + arrLen -= 1 + heapify(arr, 0, arrLen) + } + return arr +} + +func buildMaxHeap(arr []int, arrLen int) { + for i := arrLen / 2; i >= 0; i-- { + heapify(arr, i, arrLen) + } +} + +func heapify(arr []int, i, arrLen int) { + left := 2*i + 1 + right := 2*i + 2 + largest := i + if left < arrLen && arr[left] > arr[largest] { + largest = left + } + if right < arrLen && arr[right] > arr[largest] { + largest = right + } + if largest != i { + swap(arr, i, largest) + heapify(arr, largest, arrLen) + } +} + +func swap(arr []int, i, j int) { + arr[i], arr[j] = arr[j], arr[i] +} + +func main() { + num := 5000 + test_func(num, bubbleSort) + test_func(num, selectionSort) + test_func(num, insertionSort) + test_func(num, shellSort) + test_func(num, mergeSort) + test_func(num, quickSort) + test_func(num, heapSort) +} From 523336f0e7305c1b6fbf280502a00f4533799d8e Mon Sep 17 00:00:00 2001 From: hustcc Date: Mon, 6 Feb 2017 18:33:43 +0800 Subject: [PATCH 24/52] fixed markdown error with hint --- 4.shellSort.md | 6 +++--- 5.mergeSort.md | 2 +- 6.quickSort.md | 6 +++--- 7.heapSort.md | 2 +- README.md | 2 +- goSortTest.go => src/goSortTest.go | 0 pythonSortTest.py => src/pythonSortTest.py | 0 7 files changed, 9 insertions(+), 9 deletions(-) rename goSortTest.go => src/goSortTest.go (100%) mode change 100755 => 100644 rename pythonSortTest.py => src/pythonSortTest.py (100%) diff --git a/4.shellSort.md b/4.shellSort.md index 97de9c0..0406030 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -4,15 +4,15 @@ 希尔排序是基于插入排序的以下两点性质而提出改进方法的: - - 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率 - - 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位 + - 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率; + - 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位; 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。 ## 1. 算法步骤 -1. 选择一个增量序列 t1,t2,…,tk,其中 ti > tj,tk=1; +1. 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1; 2. 按增量序列个数 k,对序列进行 k 趟排序; diff --git a/5.mergeSort.md b/5.mergeSort.md index ea82d6c..e1e1479 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -10,7 +10,7 @@ > However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle. > -> 然而,在 JavaScript 中这种方式不太可行,因为这个算法的递归深度对它来讲太深了。 +> 然而,在 JavaScript 中这种方式不太可行,因为这个算法的递归深度对它来讲太深了。 说实话,我不太理解这句话。意思是 JavaScript 编译器内存太小,递归太深容易造成内存溢出吗?还望有大神能够指教。 diff --git a/6.quickSort.md b/6.quickSort.md index 11696e6..31f4d2b 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -6,7 +6,7 @@ 快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。 -快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高! 它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案: +快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案: > 快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。 @@ -15,9 +15,9 @@ 1. 从数列中挑出一个元素,称为 “基准”(pivot); -2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作; +2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作; -3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序; +3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序; 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 diff --git a/7.heapSort.md b/7.heapSort.md index 7ce6ade..d4bfa49 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -10,7 +10,7 @@ ## 1. 算法步骤 -1. 创建一个堆 H[0..n-1]; +1. 创建一个堆 H[0……n-1]; 2. 把堆首(最大值)和堆尾互换; diff --git a/README.md b/README.md index d8df556..ec691a6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ **关于时间复杂度**: 1. 平方阶 (O(n2)) 排序 - 各类简单排序:直接插入、直接选择和冒泡排序。 + 各类简单排序:直接插入、直接选择和冒泡排序。 2. 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序; 3. O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 diff --git a/goSortTest.go b/src/goSortTest.go old mode 100755 new mode 100644 similarity index 100% rename from goSortTest.go rename to src/goSortTest.go diff --git a/pythonSortTest.py b/src/pythonSortTest.py similarity index 100% rename from pythonSortTest.py rename to src/pythonSortTest.py From 29392413f04d0c67e0b6408bab30e7e80d8d65f1 Mon Sep 17 00:00:00 2001 From: wanglinzhizhi Date: Wed, 8 Feb 2017 01:50:29 -0600 Subject: [PATCH 25/52] Update 6.quickSort.md (#6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update 6.quickSort.md update 基于严蔚敏版的js快排, C++版.优化掉swap的操作 * Update 6.quickSort.md * update lagyout 唔,其实我想表达的重点是优化掉swap这个交换,这里(swap)会增加同排序数量级(O(nlgn))的比较次数和交换次数操作,有点浪费:) * Update 6.quickSort.md --- 6.quickSort.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/6.quickSort.md b/6.quickSort.md index 31f4d2b..1c81c59 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -62,6 +62,31 @@ function swap(arr, i, j) { arr[i] = arr[j]; arr[j] = temp; } +functiion paritition2(arr, low, high) { + let pivot = arr[low]; + while (low < high) { + while (low < high && arr[high] > pivot) { + --high; + } + arr[low] = arr[high]; + while (low < high && arr[low] <= pivot) { + ++low; + } + arr[high] = arr[low]; + } + arr[low] = pivot; + return low; +} + +function quickSort2(arr, low, high) { + if (low < high) { + let pivot = paritition2(arr, low, high); + quickSort2(arr, low, pivot - 1); + quickSort2(arr, pivot + 1, high); + } + return arr; +} + ``` @@ -127,3 +152,34 @@ func swap(arr []int, i, j int) { arr[i], arr[j] = arr[j], arr[i] } ``` + +## 6. C++版 + + +```C++ + //严蔚敏《数据结构》标准分割函数 + Paritition1(int A[], int low, int high) { + int pivot = A[low]; + while (low < high) { + while (low < high && A[high] >= pivot) { + --high; + } + A[low] = A[high]; + while (low < high && A[low] <= pivot) { + ++low; + } + A[high] = A[low]; + } + A[low] = pivot; + return low; + } + + void QuickSort(int A[], int low, int high) //快排母函数 + { + if (low < high) { + int pivot = Paritition1(A, low, high); + QuickSort(A, low, pivot - 1); + QuickSort(A, pivot + 1, high); + } + } +``` From 2032ebd1bb64f2db9a4aab13c4f3f8a52944df05 Mon Sep 17 00:00:00 2001 From: hustcc Date: Thu, 9 Feb 2017 12:30:55 +0800 Subject: [PATCH 26/52] fixed type --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec691a6..a14f9c1 100644 --- a/README.md +++ b/README.md @@ -62,4 +62,6 @@ 开源项目地址:[https://github.com/hustcc/JS-Sorting-Algorithm](https://github.com/hustcc/JS-Sorting-Algorithm),整理人 [hustcc](https://github.com/hustcc)。 -GitHook 在线阅读地址:[https://sort.hust.cc/](https://sort.hust.cc/)。 \ No newline at end of file +GitBook 在线阅读地址:[https://sort.hust.cc/](https://sort.hust.cc/)。 + +本项目使用 [hint](https://github.com/hustcc/hint) 进行中文 Markdown 文件的格式检查,务必在提交 Pr 之前,保证 Markdown 格式正确。 From b8c5e86c2797c55b6771d323d4e8ff37ea440132 Mon Sep 17 00:00:00 2001 From: AnHongpeng Date: Tue, 21 Feb 2017 09:37:45 +0800 Subject: [PATCH 27/52] fix bubbleSort.md (#9) --- 1.bubbleSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1.bubbleSort.md b/1.bubbleSort.md index 49805e7..e53a38d 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -36,7 +36,7 @@ ```js function bubbleSort(arr) { var len = arr.length; - for (var i = 0; i < len; i++) { + for (var i = 0; i < len - 1; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]) { // 相邻元素两两对比 var temp = arr[j+1]; // 元素交换 From dcd47455e542bacdcda29232a26ce72054e4f768 Mon Sep 17 00:00:00 2001 From: AnHongpeng Date: Mon, 27 Feb 2017 21:59:08 +0800 Subject: [PATCH 28/52] fix 2.selectionSort.md (#10) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix bubbleSort.md * fix 2.selectionSort.md 使用选择排序,待排序队列中的相同元素可能在排序后位置互换,因此选择排序是不稳定排序。这里的“是表现最稳定的排序算法之一”有歧义 --- 2.selectionSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2.selectionSort.md b/2.selectionSort.md index 5364bc5..1c3ddbc 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -1,6 +1,6 @@ # 选择排序 -选择排序是一种简单直观的排序算法,是表现最稳定的排序算法之一,因为无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。 +选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。 ## 1. 算法步骤 From 1862c044b7e012ea0a058eb99b2e71e56e946d0b Mon Sep 17 00:00:00 2001 From: lty96117 Date: Thu, 21 Dec 2017 23:54:05 +0800 Subject: [PATCH 29/52] fixed a typo in quickSort --- 6.quickSort.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/6.quickSort.md b/6.quickSort.md index 1c81c59..d08b28f 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -62,7 +62,7 @@ function swap(arr, i, j) { arr[i] = arr[j]; arr[j] = temp; } -functiion paritition2(arr, low, high) { +function partition2(arr, low, high) { let pivot = arr[low]; while (low < high) { while (low < high && arr[high] > pivot) { @@ -80,7 +80,7 @@ functiion paritition2(arr, low, high) { function quickSort2(arr, low, high) { if (low < high) { - let pivot = paritition2(arr, low, high); + let pivot = partition2(arr, low, high); quickSort2(arr, low, pivot - 1); quickSort2(arr, pivot + 1, high); } From 85ec055f8915551797ccff800b53a2478efe7fec Mon Sep 17 00:00:00 2001 From: CorningSun Date: Wed, 3 Jan 2018 11:45:00 +0800 Subject: [PATCH 30/52] =?UTF-8?q?python=20selectionSort=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- 2.selectionSort.md | 13 +++- src/pythonSortTest.py | 150 +++++++++++++++++++++---------------- test/pythonSortTest.py | 165 ----------------------------------------- 4 files changed, 97 insertions(+), 234 deletions(-) delete mode 100644 test/pythonSortTest.py diff --git a/.gitignore b/.gitignore index 1a366fb..7297f31 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ _book # eBook build output *.epub *.mobi -*.pdf \ No newline at end of file +*.pdf +\.idea/ diff --git a/2.selectionSort.md b/2.selectionSort.md index 1c3ddbc..6e3b3a4 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -42,10 +42,15 @@ function selectionSort(arr) { ```python def selectionSort(arr): - for i in range(len(arr)-1): - for j in range(i+1, len(arr)): - if arr[j] < arr[i]: - arr[i], arr[j] = arr[j], arr[i] + for i in range(len(arr) - 1): + # 记录最小数的索引 + minIndex = i + for j in range(i + 1, len(arr)): + if arr[j] < arr[minIndex]: + minIndex = j + # i 不是最小数时,将 i 和最小数进行交换 + if i != minIndex: + arr[i], arr[minIndex] = arr[minIndex], arr[i] return arr ``` diff --git a/src/pythonSortTest.py b/src/pythonSortTest.py index eb5b137..ea765d2 100644 --- a/src/pythonSortTest.py +++ b/src/pythonSortTest.py @@ -2,77 +2,89 @@ # Create by LokiSharp(loki.sharp#gmail) at 2017-1-22 ''' -TOTAL=5000 +TOTAL = 5000 + def sortTest(func, total=1000): import random, copy, operator, math, time - arrList = [i for i in range(-math.floor(total/2),math.ceil(total/2))] + arrList = [i for i in range(-math.floor(total / 2), math.ceil(total / 2))] arrListR = copy.deepcopy(arrList) - while operator.eq(arrList,arrListR): + while operator.eq(arrList, arrListR): random.shuffle(arrListR) - #print("--- [Origin List]", arrList, "Use", func.__name__,"with Total:", len(arrList)) - #print("--> [Random List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) + # print("--- [Origin List]", arrList, "Use", func.__name__,"with Total:", len(arrList)) + # print("--> [Random List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) start = time.clock() arrListR = func(arrListR) end = time.clock() - runtime = end-start - #print("--> [Sorted List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) + runtime = end - start + # print("--> [Sorted List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) if operator.eq(arrList, arrListR): - print("[Success]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) + print("[Success]", func.__name__, "with Total:", len(arrList), "in %.5fs" % runtime) return True else: - print("[Fail]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) + print("[Fail]", func.__name__, "with Total:", len(arrList), "in %.5fs" % runtime) return False + def bubbleSort(arr): for i in range(1, len(arr)): - for j in range(0, len(arr)-i): - if arr[j] > arr[j+1]: + for j in range(0, len(arr) - i): + if arr[j] > arr[j + 1]: arr[j], arr[j + 1] = arr[j + 1], arr[j] return arr + def selectionSort(arr): - for i in range(len(arr)-1): - for j in range(i+1, len(arr)): - if arr[j] < arr[i]: - arr[i], arr[j] = arr[j], arr[i] + for i in range(len(arr) - 1): + # 记录最小数的索引 + minIndex = i + for j in range(i + 1, len(arr)): + if arr[j] < arr[minIndex]: + minIndex = j + # i 不是最小数时,将 i 和最小数进行交换 + if i != minIndex: + arr[i], arr[minIndex] = arr[minIndex], arr[i] return arr + def insertionSort(arr): for i in range(len(arr)): - preIndex = i-1 + preIndex = i - 1 current = arr[i] while preIndex >= 0 and arr[preIndex] > current: - arr[preIndex+1] = arr[preIndex] - preIndex-=1 - arr[preIndex+1] = current + arr[preIndex + 1] = arr[preIndex] + preIndex -= 1 + arr[preIndex + 1] = current return arr + def shellSort(arr): import math - gap=1 - while(gap < len(arr)/3): - gap = gap*3+1 + gap = 1 + while (gap < len(arr) / 3): + gap = gap * 3 + 1 while gap > 0: - for i in range(gap,len(arr)): + for i in range(gap, len(arr)): temp = arr[i] - j = i-gap - while j >=0 and arr[j] > temp: - arr[j+gap]=arr[j] - j-=gap - arr[j+gap] = temp - gap = math.floor(gap/3) + j = i - gap + while j >= 0 and arr[j] > temp: + arr[j + gap] = arr[j] + j -= gap + arr[j + gap] = temp + gap = math.floor(gap / 3) return arr + def mergeSort(arr): import math - if(len(arr)<2): + if (len(arr) < 2): return arr - middle = math.floor(len(arr)/2) + middle = math.floor(len(arr) / 2) left, right = arr[0:middle], arr[middle:] return merge(mergeSort(left), mergeSort(right)) -def merge(left,right): + +def merge(left, right): result = [] while left and right: if left[0] <= right[0]: @@ -85,38 +97,43 @@ def merge(left,right): result.append(right.pop(0)); return result + def quickSort(arr, left=None, right=None): - left = 0 if not isinstance(left,(int, float)) else left - right = len(arr)-1 if not isinstance(right,(int, float)) else right + left = 0 if not isinstance(left, (int, float)) else left + right = len(arr) - 1 if not isinstance(right, (int, float)) else right if left < right: partitionIndex = partition(arr, left, right) - quickSort(arr, left, partitionIndex-1) - quickSort(arr, partitionIndex+1, right) + quickSort(arr, left, partitionIndex - 1) + quickSort(arr, partitionIndex + 1, right) return arr + def partition(arr, left, right): pivot = left - index = pivot+1 + index = pivot + 1 i = index - while i <= right: + while i <= right: if arr[i] < arr[pivot]: swap(arr, i, index) - index+=1 - i+=1 - swap(arr,pivot,index-1) - return index-1 + index += 1 + i += 1 + swap(arr, pivot, index - 1) + return index - 1 + def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i] + def buildMaxHeap(arr): import math - for i in range(math.floor(len(arr)/2),-1,-1): - heapify(arr,i) + for i in range(math.floor(len(arr) / 2), -1, -1): + heapify(arr, i) + def heapify(arr, i): - left = 2*i+1 - right = 2*i+2 + left = 2 * i + 1 + right = 2 * i + 2 largest = i if left < arrLen and arr[left] > arr[largest]: largest = left @@ -127,39 +144,44 @@ def heapify(arr, i): swap(arr, i, largest) heapify(arr, largest) + def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i] + def heapSort(arr): global arrLen arrLen = len(arr) buildMaxHeap(arr) - for i in range(len(arr)-1,0,-1): - swap(arr,0,i) - arrLen -=1 + for i in range(len(arr) - 1, 0, -1): + swap(arr, 0, i) + arrLen -= 1 heapify(arr, 0) return arr + def countingSort(arr, maxValue=None): - bucketLen = maxValue+1 - bucket = [0]*bucketLen - sortedIndex =0 + bucketLen = maxValue + 1 + bucket = [0] * bucketLen + sortedIndex = 0 arrLen = len(arr) for i in range(arrLen): if not bucket[arr[i]]: - bucket[arr[i]]=0 - bucket[arr[i]]+=1 + bucket[arr[i]] = 0 + bucket[arr[i]] += 1 for j in range(bucketLen): - while bucket[j]>0: + while bucket[j] > 0: arr[sortedIndex] = j - sortedIndex+=1 - bucket[j]-=1 + sortedIndex += 1 + bucket[j] -= 1 return arr -sortTest(bubbleSort, TOTAL) -sortTest(selectionSort, TOTAL) -sortTest(insertionSort, TOTAL) -sortTest(shellSort, TOTAL) -sortTest(mergeSort, TOTAL) -sortTest(quickSort, TOTAL) -sortTest(heapSort, TOTAL) + +if __name__ == '__main__': + sortTest(bubbleSort, TOTAL) + sortTest(selectionSort, TOTAL) + sortTest(insertionSort, TOTAL) + sortTest(shellSort, TOTAL) + sortTest(mergeSort, TOTAL) + sortTest(quickSort, TOTAL) + sortTest(heapSort, TOTAL) diff --git a/test/pythonSortTest.py b/test/pythonSortTest.py deleted file mode 100644 index eb5b137..0000000 --- a/test/pythonSortTest.py +++ /dev/null @@ -1,165 +0,0 @@ -''' -# Create by LokiSharp(loki.sharp#gmail) at 2017-1-22 -''' - -TOTAL=5000 - -def sortTest(func, total=1000): - import random, copy, operator, math, time - arrList = [i for i in range(-math.floor(total/2),math.ceil(total/2))] - arrListR = copy.deepcopy(arrList) - while operator.eq(arrList,arrListR): - random.shuffle(arrListR) - #print("--- [Origin List]", arrList, "Use", func.__name__,"with Total:", len(arrList)) - #print("--> [Random List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) - start = time.clock() - arrListR = func(arrListR) - end = time.clock() - runtime = end-start - #print("--> [Sorted List]", arrListR, "Use", func.__name__,"with Total:", len(arrList)) - if operator.eq(arrList, arrListR): - print("[Success]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) - return True - else: - print("[Fail]", func.__name__,"with Total:", len(arrList),"in %.5fs" % runtime) - return False - -def bubbleSort(arr): - for i in range(1, len(arr)): - for j in range(0, len(arr)-i): - if arr[j] > arr[j+1]: - arr[j], arr[j + 1] = arr[j + 1], arr[j] - return arr - -def selectionSort(arr): - for i in range(len(arr)-1): - for j in range(i+1, len(arr)): - if arr[j] < arr[i]: - arr[i], arr[j] = arr[j], arr[i] - return arr - -def insertionSort(arr): - for i in range(len(arr)): - preIndex = i-1 - current = arr[i] - while preIndex >= 0 and arr[preIndex] > current: - arr[preIndex+1] = arr[preIndex] - preIndex-=1 - arr[preIndex+1] = current - return arr - -def shellSort(arr): - import math - gap=1 - while(gap < len(arr)/3): - gap = gap*3+1 - while gap > 0: - for i in range(gap,len(arr)): - temp = arr[i] - j = i-gap - while j >=0 and arr[j] > temp: - arr[j+gap]=arr[j] - j-=gap - arr[j+gap] = temp - gap = math.floor(gap/3) - return arr - -def mergeSort(arr): - import math - if(len(arr)<2): - return arr - middle = math.floor(len(arr)/2) - left, right = arr[0:middle], arr[middle:] - return merge(mergeSort(left), mergeSort(right)) - -def merge(left,right): - result = [] - while left and right: - if left[0] <= right[0]: - result.append(left.pop(0)); - else: - result.append(right.pop(0)); - while left: - result.append(left.pop(0)); - while right: - result.append(right.pop(0)); - return result - -def quickSort(arr, left=None, right=None): - left = 0 if not isinstance(left,(int, float)) else left - right = len(arr)-1 if not isinstance(right,(int, float)) else right - if left < right: - partitionIndex = partition(arr, left, right) - quickSort(arr, left, partitionIndex-1) - quickSort(arr, partitionIndex+1, right) - return arr - -def partition(arr, left, right): - pivot = left - index = pivot+1 - i = index - while i <= right: - if arr[i] < arr[pivot]: - swap(arr, i, index) - index+=1 - i+=1 - swap(arr,pivot,index-1) - return index-1 - -def swap(arr, i, j): - arr[i], arr[j] = arr[j], arr[i] - -def buildMaxHeap(arr): - import math - for i in range(math.floor(len(arr)/2),-1,-1): - heapify(arr,i) - -def heapify(arr, i): - left = 2*i+1 - right = 2*i+2 - largest = i - if left < arrLen and arr[left] > arr[largest]: - largest = left - if right < arrLen and arr[right] > arr[largest]: - largest = right - - if largest != i: - swap(arr, i, largest) - heapify(arr, largest) - -def swap(arr, i, j): - arr[i], arr[j] = arr[j], arr[i] - -def heapSort(arr): - global arrLen - arrLen = len(arr) - buildMaxHeap(arr) - for i in range(len(arr)-1,0,-1): - swap(arr,0,i) - arrLen -=1 - heapify(arr, 0) - return arr - -def countingSort(arr, maxValue=None): - bucketLen = maxValue+1 - bucket = [0]*bucketLen - sortedIndex =0 - arrLen = len(arr) - for i in range(arrLen): - if not bucket[arr[i]]: - bucket[arr[i]]=0 - bucket[arr[i]]+=1 - for j in range(bucketLen): - while bucket[j]>0: - arr[sortedIndex] = j - sortedIndex+=1 - bucket[j]-=1 - return arr - -sortTest(bubbleSort, TOTAL) -sortTest(selectionSort, TOTAL) -sortTest(insertionSort, TOTAL) -sortTest(shellSort, TOTAL) -sortTest(mergeSort, TOTAL) -sortTest(quickSort, TOTAL) -sortTest(heapSort, TOTAL) From 6954cf83fed5e0e010d80131e51cd81a82d3031b Mon Sep 17 00:00:00 2001 From: Corning Sun Date: Mon, 8 Jan 2018 12:59:28 +0800 Subject: [PATCH 31/52] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20Java=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=20(#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 增加 Java 实现 * 精简Java代码目录结构,去掉包名 --- .gitignore | 4 + 1.bubbleSort.md | 33 ++++ 10.radixSort.md | 87 ++++++++++- 2.selectionSort.md | 34 +++++ 3.insertionSort.md | 34 +++++ 4.shellSort.md | 33 ++++ 5.mergeSort.md | 50 ++++++ 6.quickSort.md | 47 +++++- 7.heapSort.md | 56 +++++++ 8.countingSort.md | 46 ++++++ 9.bucketSort.md | 71 ++++++++- src/java/main/BubbleSort.java | 33 ++++ src/java/main/BucketSort.java | 69 +++++++++ src/java/main/CountingSort.java | 46 ++++++ src/java/main/HeapSort.java | 56 +++++++ src/java/main/IArraySort.java | 14 ++ src/java/main/InsertSort.java | 34 +++++ src/java/main/MergeSort.java | 50 ++++++ src/java/main/QuickSort.java | 45 ++++++ src/java/main/RadixSort.java | 83 ++++++++++ src/java/main/SelectionSort.java | 34 +++++ src/java/main/ShellSort.java | 33 ++++ src/java/pom.xml | 70 +++++++++ src/java/target/maven-archiver/pom.properties | 5 + src/java/target/sort-1.0-SNAPSHOT.jar | Bin 0 -> 1873 bytes src/java/test/ArraySortTest.java | 142 ++++++++++++++++++ 26 files changed, 1206 insertions(+), 3 deletions(-) create mode 100644 src/java/main/BubbleSort.java create mode 100644 src/java/main/BucketSort.java create mode 100644 src/java/main/CountingSort.java create mode 100644 src/java/main/HeapSort.java create mode 100644 src/java/main/IArraySort.java create mode 100644 src/java/main/InsertSort.java create mode 100644 src/java/main/MergeSort.java create mode 100644 src/java/main/QuickSort.java create mode 100644 src/java/main/RadixSort.java create mode 100644 src/java/main/SelectionSort.java create mode 100644 src/java/main/ShellSort.java create mode 100644 src/java/pom.xml create mode 100644 src/java/target/maven-archiver/pom.properties create mode 100644 src/java/target/sort-1.0-SNAPSHOT.jar create mode 100644 src/java/test/ArraySortTest.java diff --git a/.gitignore b/.gitignore index 7297f31..f6cbc5f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ _book *.mobi *.pdf \.idea/ + +*.iml + +src/javaSortTest/target/ diff --git a/1.bubbleSort.md b/1.bubbleSort.md index e53a38d..621314f 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -77,3 +77,36 @@ func bubbleSort(arr []int) []int { return arr } ``` + +## 8. Java 代码实现 + +```java +public class BubbleSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + for (int i = 1; i < arr.length; i++) { + // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。 + boolean flag = true; + + for (int j = 0; j < arr.length - i; j++) { + if (arr[j] > arr[j + 1]) { + int tmp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = tmp; + + flag = false; + } + } + + if (flag) { + break; + } + } + return arr; + } +} +``` diff --git a/10.radixSort.md b/10.radixSort.md index 5f40ea7..39b0a64 100644 --- a/10.radixSort.md +++ b/10.radixSort.md @@ -47,4 +47,89 @@ function radixSort(arr, maxDigit) { } return arr; } -``` \ No newline at end of file +``` + +## 4. Java 代码实现 + +```java +/** + * 基数排序 + * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN/q/e98fa9 + */ +public class RadixSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int maxDigit = getMaxDigit(arr); + return radixSort(arr, maxDigit); + } + + /** + * 获取最高位数 + */ + private int getMaxDigit(int[] arr) { + int maxValue = getMaxValue(arr); + return getNumLenght(maxValue); + } + + private int getMaxValue(int[] arr) { + int maxValue = arr[0]; + for (int value : arr) { + if (maxValue < value) { + maxValue = value; + } + } + return maxValue; + } + + protected int getNumLenght(long num) { + if (num == 0) { + return 1; + } + int lenght = 0; + for (long temp = num; temp != 0; temp /= 10) { + lenght++; + } + return lenght; + } + + private int[] radixSort(int[] arr, int maxDigit) { + int mod = 10; + int dev = 1; + + for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { + // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10) + int[][] counter = new int[mod * 2][0]; + + for (int j = 0; j < arr.length; j++) { + int bucket = ((arr[j] % mod) / dev) + mod; + counter[bucket] = arrayAppend(counter[bucket], arr[j]); + } + + int pos = 0; + for (int[] bucket : counter) { + for (int value : bucket) { + arr[pos++] = value; + } + } + } + + return arr; + } + + /** + * 自动扩容,并保存数据 + * + * @param arr + * @param value + */ + private int[] arrayAppend(int[] arr, int value) { + arr = Arrays.copyOf(arr, arr.length + 1); + arr[arr.length - 1] = value; + return arr; + } +} +``` diff --git a/2.selectionSort.md b/2.selectionSort.md index 6e3b3a4..ae7350f 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -71,3 +71,37 @@ func selectionSort(arr []int) []int { return arr } ``` + +## 6. Java 代码实现 + +```java +public class SelectionSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + // 总共要经过 N-1 轮比较 + for (int i = 0; i < arr.length - 1; i++) { + int min = i; + + // 每轮需要比较的次数 N-i + for (int j = i + 1; j < arr.length; j++) { + if (arr[j] < arr[min]) { + // 记录目前能找到的最小值元素的下标 + min = j; + } + } + + // 将找到的最小值和i位置所在的值进行交换 + if (i != min) { + int tmp = arr[i]; + arr[i] = arr[min]; + arr[min] = tmp; + } + + } + return arr; + } +} +``` diff --git a/3.insertionSort.md b/3.insertionSort.md index 11ed672..71beec9 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -65,3 +65,37 @@ func insertionSort(arr []int) []int { return arr } ``` + +## 6. Java 代码实现 + +```java +public class InsertSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的 + for (int i = 1; i < arr.length; i++) { + + // 记录要插入的数据 + int tmp = arr[i]; + + // 从已经排序的序列最右边的开始比较,找到比其小的数 + int j = i; + while (j > 0 && tmp < arr[j - 1]) { + arr[j] = arr[j - 1]; + j--; + } + + // 存在比其小的数,插入 + if (j != i) { + arr[j] = tmp; + } + + } + return arr; + } +} +``` diff --git a/4.shellSort.md b/4.shellSort.md index 0406030..c96d8b7 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -87,3 +87,36 @@ func shellSort(arr []int) []int { return arr } ``` + +## 5. Java 代码实现 + +```java +public class ShellSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int gap = 1; + while (gap < arr.length) { + gap = gap * 3 + 1; + } + + while (gap > 0) { + for (int i = gap; i < arr.length; i++) { + int tmp = arr[i]; + int j = i - gap; + while (j >= 0 && arr[j] > tmp) { + arr[j + gap] = arr[j]; + j -= gap; + } + arr[j + gap] = tmp; + } + gap = (int) Math.floor(gap / 3); + } + + return arr; + } +} +``` diff --git a/5.mergeSort.md b/5.mergeSort.md index e1e1479..8394ab5 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -136,3 +136,53 @@ func merge(left []int, right []int) []int { return result } ``` + +## 7. Java 代码实现 + +```java +public class MergeSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + if (arr.length < 2) { + return arr; + } + int middle = (int) Math.floor(arr.length / 2); + + int[] left = Arrays.copyOfRange(arr, 0, middle); + int[] right = Arrays.copyOfRange(arr, middle, arr.length); + + return merge(sort(left), sort(right)); + } + + protected int[] merge(int[] left, int[] right) { + int[] result = new int[left.length + right.length]; + int i = 0; + while (left.length > 0 && right.length > 0) { + if (left[0] <= right[0]) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } else { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + } + + while (left.length > 0) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } + + while (right.length > 0) { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + + return result; + } + +} +``` diff --git a/6.quickSort.md b/6.quickSort.md index d08b28f..497f973 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -177,9 +177,54 @@ func swap(arr []int, i, j int) { void QuickSort(int A[], int low, int high) //快排母函数 { if (low < high) { - int pivot = Paritition1(A, low, high); + int pivot = Paritition1(A, low, high); QuickSort(A, low, pivot - 1); QuickSort(A, pivot + 1, high); } } ``` + +## 7. Java 代码实现 + +```java +public class QuickSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return quickSort(arr, 0, arr.length - 1); + } + + private int[] quickSort(int[] arr, int left, int right) { + if (left < right) { + int partitionIndex = partition(arr, left, right); + quickSort(arr, left, partitionIndex - 1); + quickSort(arr, partitionIndex + 1, right); + } + return arr; + } + + private int partition(int[] arr, int left, int right) { + // 设定基准值(pivot) + int pivot = left; + int index = pivot + 1; + for (int i = index; i <= right; i++) { + if (arr[i] < arr[pivot]) { + swap(arr, i, index); + index++; + } + } + swap(arr, pivot, index - 1); + return index - 1; + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} +``` diff --git a/7.heapSort.md b/7.heapSort.md index d4bfa49..43d522c 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -147,3 +147,59 @@ func swap(arr []int, i, j int) { arr[i], arr[j] = arr[j], arr[i] } ``` + +## 6. Java 代码实现 + +```java +public class HeapSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int len = arr.length; + + buildMaxHeap(arr, len); + + for (int i = len - 1; i > 0; i--) { + swap(arr, 0, i); + len--; + heapify(arr, 0, len); + } + return arr; + } + + private void buildMaxHeap(int[] arr, int len) { + for (int i = (int) Math.floor(len / 2); i >= 0; i--) { + heapify(arr, i, len); + } + } + + private void heapify(int[] arr, int i, int len) { + int left = 2 * i + 1; + int right = 2 * i + 2; + int largest = i; + + if (left < len && arr[left] > arr[largest]) { + largest = left; + } + + if (right < len && arr[right] > arr[largest]) { + largest = right; + } + + if (largest != i) { + swap(arr, i, largest); + heapify(arr, largest, len); + } + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} +``` diff --git a/8.countingSort.md b/8.countingSort.md index 164d3ac..b0f17e5 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -80,3 +80,49 @@ func countingSort(arr []int, maxValue int) []int { return arr } ``` + +## 5. Java 代码实现 + +```java +public class CountingSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int maxValue = getMaxValue(arr); + + return countingSort(arr, maxValue); + } + + private int[] countingSort(int[] arr, int maxValue) { + int bucketLen = maxValue + 1; + int[] bucket = new int[bucketLen]; + + for (int value : arr) { + bucket[value]++; + } + + int sortedIndex = 0; + for (int j = 0; j < bucketLen; j++) { + while (bucket[j] > 0) { + arr[sortedIndex++] = j; + bucket[j]--; + } + } + return arr; + } + + private int getMaxValue(int[] arr) { + int maxValue = arr[0]; + for (int value : arr) { + if (maxValue < value) { + maxValue = value; + } + } + return maxValue; + } + +} +``` diff --git a/9.bucketSort.md b/9.bucketSort.md index 30966f4..e2e4aa6 100644 --- a/9.bucketSort.md +++ b/9.bucketSort.md @@ -61,4 +61,73 @@ function bucketSort(arr, bucketSize) { return arr; } -``` \ No newline at end of file +``` + +## 4. Java 代码实现 + +```java +public class BucketSort implements IArraySort { + + private static final InsertSort insertSort = new InsertSort(); + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return bucketSort(arr, 5); + } + + private int[] bucketSort(int[] arr, int bucketSize) throws Exception { + if (arr.length == 0) { + return arr; + } + + int minValue = arr[0]; + int maxValue = arr[0]; + for (int value : arr) { + if (value < minValue) { + minValue = value; + } else if (value > maxValue) { + maxValue = value; + } + } + + int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1; + int[][] buckets = new int[bucketCount][0]; + + // 利用映射函数将数据分配到各个桶中 + for (int i = 0; i < arr.length; i++) { + int index = (int) Math.floor((arr[i] - minValue) / bucketSize); + buckets[index] = arrAppend(buckets[index], arr[i]); + } + + int arrIndex = 0; + for (int[] bucket : buckets) { + if (bucket.length <= 0) { + continue; + } + // 对每个桶进行排序,这里使用了插入排序 + bucket = insertSort.sort(bucket); + for (int value : bucket) { + arr[arrIndex++] = value; + } + } + + return arr; + } + + /** + * 自动扩容,并保存数据 + * + * @param arr + * @param value + */ + private int[] arrAppend(int[] arr, int value) { + arr = Arrays.copyOf(arr, arr.length + 1); + arr[arr.length - 1] = value; + return arr; + } + +} +``` diff --git a/src/java/main/BubbleSort.java b/src/java/main/BubbleSort.java new file mode 100644 index 0000000..3c8cebc --- /dev/null +++ b/src/java/main/BubbleSort.java @@ -0,0 +1,33 @@ +import java.util.Arrays; + +/** + * 冒泡排序 + */ +public class BubbleSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + for (int i = 1; i < arr.length; i++) { + // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。 + boolean flag = true; + + for (int j = 0; j < arr.length - i; j++) { + if (arr[j] > arr[j + 1]) { + int tmp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = tmp; + + flag = false; + } + } + + if (flag) { + break; + } + } + return arr; + } +} diff --git a/src/java/main/BucketSort.java b/src/java/main/BucketSort.java new file mode 100644 index 0000000..c0b5183 --- /dev/null +++ b/src/java/main/BucketSort.java @@ -0,0 +1,69 @@ +import java.util.Arrays; + +/** + * 桶排序 + */ +public class BucketSort implements IArraySort { + + private static final InsertSort insertSort = new InsertSort(); + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return bucketSort(arr, 5); + } + + private int[] bucketSort(int[] arr, int bucketSize) throws Exception { + if (arr.length == 0) { + return arr; + } + + int minValue = arr[0]; + int maxValue = arr[0]; + for (int value : arr) { + if (value < minValue) { + minValue = value; + } else if (value > maxValue) { + maxValue = value; + } + } + + int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1; + int[][] buckets = new int[bucketCount][0]; + + // 利用映射函数将数据分配到各个桶中 + for (int i = 0; i < arr.length; i++) { + int index = (int) Math.floor((arr[i] - minValue) / bucketSize); + buckets[index] = arrAppend(buckets[index], arr[i]); + } + + int arrIndex = 0; + for (int[] bucket : buckets) { + if (bucket.length <= 0) { + continue; + } + // 对每个桶进行排序,这里使用了插入排序 + bucket = insertSort.sort(bucket); + for (int value : bucket) { + arr[arrIndex++] = value; + } + } + + return arr; + } + + /** + * 自动扩容,并保存数据 + * + * @param arr + * @param value + */ + private int[] arrAppend(int[] arr, int value) { + arr = Arrays.copyOf(arr, arr.length + 1); + arr[arr.length - 1] = value; + return arr; + } + +} diff --git a/src/java/main/CountingSort.java b/src/java/main/CountingSort.java new file mode 100644 index 0000000..74fcd2a --- /dev/null +++ b/src/java/main/CountingSort.java @@ -0,0 +1,46 @@ +import java.util.Arrays; + +/** + * 计数排序 + */ +public class CountingSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int maxValue = getMaxValue(arr); + + return countingSort(arr, maxValue); + } + + private int[] countingSort(int[] arr, int maxValue) { + int bucketLen = maxValue + 1; + int[] bucket = new int[bucketLen]; + + for (int value : arr) { + bucket[value]++; + } + + int sortedIndex = 0; + for (int j = 0; j < bucketLen; j++) { + while (bucket[j] > 0) { + arr[sortedIndex++] = j; + bucket[j]--; + } + } + return arr; + } + + private int getMaxValue(int[] arr) { + int maxValue = arr[0]; + for (int value : arr) { + if (maxValue < value) { + maxValue = value; + } + } + return maxValue; + } + +} diff --git a/src/java/main/HeapSort.java b/src/java/main/HeapSort.java new file mode 100644 index 0000000..6e9dcfe --- /dev/null +++ b/src/java/main/HeapSort.java @@ -0,0 +1,56 @@ +import java.util.Arrays; + +/** + * 堆排序 + */ +public class HeapSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int len = arr.length; + + buildMaxHeap(arr, len); + + for (int i = len - 1; i > 0; i--) { + swap(arr, 0, i); + len--; + heapify(arr, 0, len); + } + return arr; + } + + private void buildMaxHeap(int[] arr, int len) { + for (int i = (int) Math.floor(len / 2); i >= 0; i--) { + heapify(arr, i, len); + } + } + + private void heapify(int[] arr, int i, int len) { + int left = 2 * i + 1; + int right = 2 * i + 2; + int largest = i; + + if (left < len && arr[left] > arr[largest]) { + largest = left; + } + + if (right < len && arr[right] > arr[largest]) { + largest = right; + } + + if (largest != i) { + swap(arr, i, largest); + heapify(arr, largest, len); + } + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} diff --git a/src/java/main/IArraySort.java b/src/java/main/IArraySort.java new file mode 100644 index 0000000..7d607e5 --- /dev/null +++ b/src/java/main/IArraySort.java @@ -0,0 +1,14 @@ +/** + * Created by corning on 2017/12/19. + */ +public interface IArraySort { + /** + * 对数组进行排序,并返回排序后的数组 + * + * @param sourceArray + * @return + * @throws Exception + */ + int[] sort(int[] sourceArray) throws Exception; + +} diff --git a/src/java/main/InsertSort.java b/src/java/main/InsertSort.java new file mode 100644 index 0000000..1321972 --- /dev/null +++ b/src/java/main/InsertSort.java @@ -0,0 +1,34 @@ +import java.util.Arrays; + +/** + * 插入排序 + */ +public class InsertSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的 + for (int i = 1; i < arr.length; i++) { + + // 记录要插入的数据 + int tmp = arr[i]; + + // 从已经排序的序列最右边的开始比较,找到比其小的数 + int j = i; + while (j > 0 && tmp < arr[j - 1]) { + arr[j] = arr[j - 1]; + j--; + } + + // 存在比其小的数,插入 + if (j != i) { + arr[j] = tmp; + } + + } + return arr; + } +} diff --git a/src/java/main/MergeSort.java b/src/java/main/MergeSort.java new file mode 100644 index 0000000..7fec2b8 --- /dev/null +++ b/src/java/main/MergeSort.java @@ -0,0 +1,50 @@ +import java.util.Arrays; + +/** + * 归并排序 + */ +public class MergeSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + if (arr.length < 2) { + return arr; + } + int middle = (int) Math.floor(arr.length / 2); + + int[] left = Arrays.copyOfRange(arr, 0, middle); + int[] right = Arrays.copyOfRange(arr, middle, arr.length); + + return merge(sort(left), sort(right)); + } + + protected int[] merge(int[] left, int[] right) { + int[] result = new int[left.length + right.length]; + int i = 0; + while (left.length > 0 && right.length > 0) { + if (left[0] <= right[0]) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } else { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + } + + while (left.length > 0) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } + + while (right.length > 0) { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + + return result; + } + +} diff --git a/src/java/main/QuickSort.java b/src/java/main/QuickSort.java new file mode 100644 index 0000000..1c598ed --- /dev/null +++ b/src/java/main/QuickSort.java @@ -0,0 +1,45 @@ +import java.util.Arrays; + +/** + * 快速排序 + */ +public class QuickSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return quickSort(arr, 0, arr.length - 1); + } + + private int[] quickSort(int[] arr, int left, int right) { + if (left < right) { + int partitionIndex = partition(arr, left, right); + quickSort(arr, left, partitionIndex - 1); + quickSort(arr, partitionIndex + 1, right); + } + return arr; + } + + private int partition(int[] arr, int left, int right) { + // 设定基准值(pivot) + int pivot = left; + int index = pivot + 1; + for (int i = index; i <= right; i++) { + if (arr[i] < arr[pivot]) { + swap(arr, i, index); + index++; + } + } + swap(arr, pivot, index - 1); + return index - 1; + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} diff --git a/src/java/main/RadixSort.java b/src/java/main/RadixSort.java new file mode 100644 index 0000000..9052e76 --- /dev/null +++ b/src/java/main/RadixSort.java @@ -0,0 +1,83 @@ +import java.util.Arrays; + +/** + * 基数排序 + *

+ * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN/q/e98fa9 + */ +public class RadixSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int maxDigit = getMaxDigit(arr); + return radixSort(arr, maxDigit); + } + + /** + * 获取最高位数 + */ + private int getMaxDigit(int[] arr) { + int maxValue = getMaxValue(arr); + return getNumLenght(maxValue); + } + + private int getMaxValue(int[] arr) { + int maxValue = arr[0]; + for (int value : arr) { + if (maxValue < value) { + maxValue = value; + } + } + return maxValue; + } + + protected int getNumLenght(long num) { + if (num == 0) { + return 1; + } + int lenght = 0; + for (long temp = num; temp != 0; temp /= 10) { + lenght++; + } + return lenght; + } + + private int[] radixSort(int[] arr, int maxDigit) { + int mod = 10; + int dev = 1; + + for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { + // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10) + int[][] counter = new int[mod * 2][0]; + + for (int j = 0; j < arr.length; j++) { + int bucket = ((arr[j] % mod) / dev) + mod; + counter[bucket] = arrayAppend(counter[bucket], arr[j]); + } + + int pos = 0; + for (int[] bucket : counter) { + for (int value : bucket) { + arr[pos++] = value; + } + } + } + + return arr; + } + + /** + * 自动扩容,并保存数据 + * + * @param arr + * @param value + */ + private int[] arrayAppend(int[] arr, int value) { + arr = Arrays.copyOf(arr, arr.length + 1); + arr[arr.length - 1] = value; + return arr; + } +} diff --git a/src/java/main/SelectionSort.java b/src/java/main/SelectionSort.java new file mode 100644 index 0000000..0cee685 --- /dev/null +++ b/src/java/main/SelectionSort.java @@ -0,0 +1,34 @@ +import java.util.Arrays; + +/** + * 选择排序 + */ +public class SelectionSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + // 总共要经过 N-1 轮比较 + for (int i = 0; i < arr.length - 1; i++) { + int min = i; + + // 每轮需要比较的次数 N-i + for (int j = i + 1; j < arr.length; j++) { + if (arr[j] < arr[min]) { + // 记录目前能找到的最小值元素的下标 + min = j; + } + } + + // 将找到的最小值和i位置所在的值进行交换 + if (i != min) { + int tmp = arr[i]; + arr[i] = arr[min]; + arr[min] = tmp; + } + + } + return arr; + } +} diff --git a/src/java/main/ShellSort.java b/src/java/main/ShellSort.java new file mode 100644 index 0000000..6c0fbb1 --- /dev/null +++ b/src/java/main/ShellSort.java @@ -0,0 +1,33 @@ +import java.util.Arrays; + +/** + * 希尔排序 + */ +public class ShellSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int gap = 1; + while (gap < arr.length) { + gap = gap * 3 + 1; + } + + while (gap > 0) { + for (int i = gap; i < arr.length; i++) { + int tmp = arr[i]; + int j = i - gap; + while (j >= 0 && arr[j] > tmp) { + arr[j + gap] = arr[j]; + j -= gap; + } + arr[j + gap] = tmp; + } + gap = (int) Math.floor(gap / 3); + } + + return arr; + } +} diff --git a/src/java/pom.xml b/src/java/pom.xml new file mode 100644 index 0000000..60b4858 --- /dev/null +++ b/src/java/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.corning + sort + 1.0-SNAPSHOT + + + + + CorningSun + corningsun@163.com + http://www.corningsun.com + + + + + + UTF-8 + LATEST + + + + + junit + junit + ${dependency.version} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20.1 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/java/target/maven-archiver/pom.properties b/src/java/target/maven-archiver/pom.properties new file mode 100644 index 0000000..5239a24 --- /dev/null +++ b/src/java/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Fri Jan 05 09:51:14 CST 2018 +version=1.0-SNAPSHOT +groupId=com.corning +artifactId=sort diff --git a/src/java/target/sort-1.0-SNAPSHOT.jar b/src/java/target/sort-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..14116be182c4c2420e6bb6f38aabdf9be82da556 GIT binary patch literal 1873 zcmWIWW@h1H0D%lYRUa?|N^k;cU)K;vT~9wZ{Q#&k4u*7~vRmhm+|L6_w*avSvNB&s zKTkK;;1E4ux6i(3PWyQ4>RsgZ*3~+9=KSU$gDb`lo)+nNojal9t?R_W{$xqm6fx}s zDiu5Dco`RamCV&zD>CVG_a~#zmnwJ8=?)V14hlZd)W_O+QgS8NzRuK@m0ZWFj#W() z(AC@(r+HH$TIUPTBVFFgofSJ7VD7{820ya`>gtX?fco^&CYq5^QxpC(_GEPsT|JRdo>G`uirk_@KNl}tve0V9b8j2BVYQr>y)#eJY+SO z?}g6GhNE6fx!&imxgOefVJoNTrKNJ`+POFBe0gd0Ic8<*Ih}mpq>|Qrhv?4@Rr<=Y zXE{5W_iw#fkYK$!CBiQ6af2(D>r6%Gf{x5NyA<87_b#aNkzLWKKbyNVi4NChP?xu<&YXWOKkO#DegKO8p9 zsIJhR>A1xGLSwLHWxkS6t?7Z?3SWzAw{8r}=eg1&t7`Rmk=IcZ*M)~gl--tY-!B}j z%r9z129b5U(}`Db(CBf48B zDYx=Ov2dHMaP=-fr;{)#y~%j-yBU8&l*J}86yIj?FI)ZKhR_b98@G*RFS+zzRLeXX zQ}21~eDCC{Jy-Hp9rT`eUd?Oz_6;USo>cBpniCYndtWl`pL)CNnZn5hHuDd6Cv0R| z^*`$)>+Nm7?(h3jZ~uC)#hbUbwm)~>x3}7oQ*Cr#kl*u4z+>GBPYlDtC-3Dy^lWAE zpT~z^{#IXZfB##5+}U+Awapg?z5f~a{^|3_@7dMa*Z<%1JELpvzMmz3vg@lPo%Skx z+xRj?j9XXd0P9_g8-=&mF$dRV8Q8@0-kICHbm|qud|`fm7S*atmp?Ddcwn&W;igLC z11qDR-`Oo9`0~5qPqAs6{>yz4hvi;K=`!i&shAvKj>raLJtA{PK~a7|YEemMYH@Ix z|5@jQ!Rt)0fkCLjhAl>>TZ~Ks3;6f~4U7!7JkWv` zP^MRmFYtaV=HdAEf&ZbG{waOk4?Y`x&z-;OeNO+>=`-HXy>zrr`gr^3F>;AN7oS?d z2rP9NnM9az7oR}K1Azd;TSpL$RG7lFVJ}WWia}sWBTB)5RJh`^7*yavfB?h)|Hpw$ zxW%yI4`w~~0uZ733#Mk&;t;n%3J_C(B*+!Ij2Ny!HV9fg!c4_z&nLTUHPc0Pnkf^#A|> literal 0 HcmV?d00001 diff --git a/src/java/test/ArraySortTest.java b/src/java/test/ArraySortTest.java new file mode 100644 index 0000000..580701f --- /dev/null +++ b/src/java/test/ArraySortTest.java @@ -0,0 +1,142 @@ +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Random; + +import static org.junit.Assert.*; + +/** + * Created by corning on 2017/12/19. + */ +public class ArraySortTest { + + private int[] array; + private int[] sortedArray; + + // 计数排序等不支持负数排序 + private int[] positiveArray; + private int[] positiveArraySorted; + + @Before + public void setUp() throws Exception { + // 生成随机数组 + array = randomArray(-1000, 1000, 100); + // 使用 Arrays.sort() 排序作为对比 + sortedArray = Arrays.copyOf(array, array.length); + Arrays.sort(sortedArray); + + positiveArray = randomArray(0, 1000, 100); + positiveArraySorted = Arrays.copyOf(positiveArray, positiveArray.length); + Arrays.sort(positiveArraySorted); + } + + /** + * 随机指定范围内N个不重复的数 + * 在初始化的无重复待选数组中随机产生一个数放入结果中, + * 将待选数组被随机到的数,用待选数组(len-1)下标对应的数替换 + * 然后从len-2里随机产生下一个随机数,如此类推 + * + * @param max 指定范围最大值 + * @param min 指定范围最小值 + * @param n 随机数个数 + * @return int[] 随机数结果集 + */ + public int[] randomArray(int min, int max, int n) { + int len = max - min + 1; + + if (max < min || n > len) { + return null; + } + + //初始化给定范围的待选数组 + int[] source = new int[len]; + for (int i = min; i < min + len; i++) { + source[i - min] = i; + } + + int[] result = new int[n]; + Random rd = new Random(); + int index = 0; + for (int i = 0; i < result.length; i++) { + //待选数组0到(len-2)随机一个下标 + index = Math.abs(rd.nextInt() % len--); + //将随机到的数放入结果集 + result[i] = source[index]; + //将待选数组中被随机到的数,用待选数组(len-1)下标对应的数替换 + source[index] = source[len]; + } + return result; + } + + @After + public void tearDown() throws Exception { + array = null; + sortedArray = null; + } + + @Test + public void bubbleSort() throws Exception { + assertArrayEquals(sortedArray, new BubbleSort().sort(array)); + } + + @Test + public void choiceSort() throws Exception { + assertArrayEquals(sortedArray, new SelectionSort().sort(array)); + } + + @Test + public void insertSort() throws Exception { + assertArrayEquals(sortedArray, new InsertSort().sort(array)); + } + + @Test + public void shellSort() throws Exception { + assertArrayEquals(sortedArray, new ShellSort().sort(array)); + } + + @Test + public void mergeSort() throws Exception { + assertArrayEquals(sortedArray, new MergeSort().sort(array)); + } + + @Test + public void mergeSort_merge() throws Exception { + assertArrayEquals(new int[]{1, 2}, new MergeSort().merge(new int[]{1, 2}, new int[]{})); + assertArrayEquals(new int[]{1, 2}, new MergeSort().merge(new int[]{1}, new int[]{2})); + assertArrayEquals(new int[]{1, 2, 3}, new MergeSort().merge(new int[]{1, 3}, new int[]{2})); + } + + @Test + public void quickSort() throws Exception { + assertArrayEquals(sortedArray, new QuickSort().sort(array)); + } + + @Test + public void heapSort() throws Exception { + assertArrayEquals(sortedArray, new HeapSort().sort(array)); + } + + @Test + public void countingSort() throws Exception { + assertArrayEquals(positiveArraySorted, new CountingSort().sort(positiveArray)); + } + + @Test + public void bucketSort() throws Exception { + assertArrayEquals(sortedArray, new BucketSort().sort(array)); + } + + @Test + public void radixSort() throws Exception { + assertArrayEquals(sortedArray, new RadixSort().sort(array)); + } + + @Test + public void radixSort_getNumLenght() throws Exception { + assertEquals(3, new RadixSort().getNumLenght(-100)); + assertEquals(1, new RadixSort().getNumLenght(1)); + } + +} \ No newline at end of file From 920ab6052d97d10e7b8215f49f49b45f237cab38 Mon Sep 17 00:00:00 2001 From: Weilong Wang Date: Mon, 16 Apr 2018 09:57:55 +0800 Subject: [PATCH 32/52] =?UTF-8?q?=E6=B7=BB=E5=8A=A0PHP=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8F=8A=E6=B5=8B=E8=AF=95=E6=96=87=E4=BB=B6?= =?UTF-8?q?=20(#18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.bubbleSort.md | 19 +++ 10.radixSort.md | 37 ++++++ 2.selectionSort.md | 21 +++ 3.insertionSort.md | 19 +++ 4.shellSort.md | 24 ++++ 5.mergeSort.md | 37 ++++++ 6.quickSort.md | 25 ++++ 7.heapSort.md | 52 ++++++++ 8.countingSort.md | 29 +++++ 9.bucketSort.md | 42 ++++++ src/phpSortTest.php | 304 ++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 609 insertions(+) create mode 100644 src/phpSortTest.php diff --git a/1.bubbleSort.md b/1.bubbleSort.md index 621314f..78c3b83 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -110,3 +110,22 @@ public class BubbleSort implements IArraySort { } } ``` + +## 9. PHP 代码实现 + +```php +function bubbleSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len - 1; $i++) { + for ($j = 0; $j < $len - 1 - $i; $j++) { + if ($arr[$j] > $arr[$j+1]) { + $tmp = $arr[$j]; + $arr[$j] = $arr[$j+1]; + $arr[$j+1] = $tmp; + } + } + } + return $arr; +} +``` diff --git a/10.radixSort.md b/10.radixSort.md index 39b0a64..0bcd341 100644 --- a/10.radixSort.md +++ b/10.radixSort.md @@ -133,3 +133,40 @@ public class RadixSort implements IArraySort { } } ``` + +## 5. PHP 代码实现 + +```php +function radixSort($arr, $maxDigit = null) +{ + if ($maxDigit === null) { + $maxDigit = max($arr); + } + $counter = []; + for ($i = 0; $i < $maxDigit; $i++) { + for ($j = 0; $j < count($arr); $j++) { + preg_match_all('/\d/', (string) $arr[$j], $matches); + $numArr = $matches[0]; + $lenTmp = count($numArr); + $bucket = array_key_exists($lenTmp - $i - 1, $numArr) + ? intval($numArr[$lenTmp - $i - 1]) + : 0; + if (!array_key_exists($bucket, $counter)) { + $counter[$bucket] = []; + } + $counter[$bucket][] = $arr[$j]; + } + $pos = 0; + for ($j = 0; $j < count($counter); $j++) { + $value = null; + if ($counter[$j] !== null) { + while (($value = array_shift($counter[$j])) !== null) { + $arr[$pos++] = $value; + } + } + } + } + + return $arr; +} +``` \ No newline at end of file diff --git a/2.selectionSort.md b/2.selectionSort.md index ae7350f..103830e 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -105,3 +105,24 @@ public class SelectionSort implements IArraySort { } } ``` + +## 7. PHP 代码实现 + +```php +function selectionSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len - 1; $i++) { + $minIndex = $i; + for ($j = $i + 1; $j < $len; $j++) { + if ($arr[$j] < $arr[$minIndex]) { + $minIndex = $j; + } + } + $temp = $arr[$i]; + $arr[$i] = $arr[$minIndex]; + $arr[$minIndex] = $temp; + } + return $arr; +} +``` diff --git a/3.insertionSort.md b/3.insertionSort.md index 71beec9..c828cb3 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -99,3 +99,22 @@ public class InsertSort implements IArraySort { } } ``` + +## 7. PHP 代码实现 + +```php +function insertionSort($arr) +{ + $len = count($arr); + for ($i = 1; $i < $len; $i++) { + $preIndex = $i - 1; + $current = $arr[$i]; + while($preIndex >= 0 && $arr[$preIndex] > $current) { + $arr[$preIndex+1] = $arr[$preIndex]; + $preIndex--; + } + $arr[$preIndex+1] = $current; + } + return $arr; +} +``` diff --git a/4.shellSort.md b/4.shellSort.md index c96d8b7..187ac0e 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -120,3 +120,27 @@ public class ShellSort implements IArraySort { } } ``` + +## 6. PHP 代码实现 + +```php +function shellSort($arr) +{ + $len = count($arr); + $temp = 0; + $gap = 1; + while($gap < $len / 3) { + $gap = $gap * 3 + 1; + } + for ($gap; $gap > 0; $gap = floor($gap / 3)) { + for ($i = $gap; $i < $len; $i++) { + $temp = $arr[$i]; + for ($j = $i - $gap; $j >= 0 && $arr[$j] > $temp; $j -= $gap) { + $arr[$j+$gap] = $arr[$j]; + } + $arr[$j+$gap] = $temp; + } + } + return $arr; +} +``` diff --git a/5.mergeSort.md b/5.mergeSort.md index 8394ab5..bf0de32 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -186,3 +186,40 @@ public class MergeSort implements IArraySort { } ``` + +## 8. PHP 代码实现 + +```php +function mergeSort($arr) +{ + $len = count($arr); + if ($len < 2) { + return $arr; + } + $middle = floor($len / 2); + $left = array_slice($arr, 0, $middle); + $right = array_slice($arr, $middle); + return merge(mergeSort($left), mergeSort($right)); +} + +function merge($left, $right) +{ + $result = []; + + while (count($left) > 0 && count($right) > 0) { + if ($left[0] <= $right[0]) { + $result[] = array_shift($left); + } else { + $result[] = array_shift($right); + } + } + + while (count($left)) + $result[] = array_shift($left); + + while (count($right)) + $result[] = array_shift($right); + + return $result; +} +``` \ No newline at end of file diff --git a/6.quickSort.md b/6.quickSort.md index 497f973..28ad477 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -228,3 +228,28 @@ public class QuickSort implements IArraySort { } ``` + +## 8. PHP 代码实现 + +```php +function quickSort($arr) +{ + if (count($arr) <= 1) + return $arr; + $middle = $arr[0]; + $leftArray = array(); + $rightArray = array(); + + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] > $middle) + $rightArray[] = $arr[$i]; + else + $leftArray[] = $arr[$i]; + } + $leftArray = quickSort($leftArray); + $leftArray[] = $middle; + + $rightArray = quickSort($rightArray); + return array_merge($leftArray, $rightArray); +} +``` diff --git a/7.heapSort.md b/7.heapSort.md index 43d522c..35b24ec 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -203,3 +203,55 @@ public class HeapSort implements IArraySort { } ``` + +## 7. PHP 代码实现 + +```php +function buildMaxHeap(&$arr) +{ + global $len; + for ($i = floor($len/2); $i >= 0; $i--) { + heapify($arr, $i); + } +} + +function heapify(&$arr, $i) +{ + global $len; + $left = 2 * $i + 1; + $right = 2 * $i + 2; + $largest = $i; + + if ($left < $len && $arr[$left] > $arr[$largest]) { + $largest = $left; + } + + if ($right < $len && $arr[$right] > $arr[$largest]) { + $largest = $right; + } + + if ($largest != $i) { + swap($arr, $i, $largest); + heapify($arr, $largest); + } +} + +function swap(&$arr, $i, $j) +{ + $temp = $arr[$i]; + $arr[$i] = $arr[$j]; + $arr[$j] = $temp; +} + +function heapSort($arr) { + global $len; + $len = count($arr); + buildMaxHeap($arr); + for ($i = count($arr) - 1; $i > 0; $i--) { + swap($arr, 0, $i); + $len--; + heapify($arr, 0); + } + return $arr; +} +``` \ No newline at end of file diff --git a/8.countingSort.md b/8.countingSort.md index b0f17e5..efabf9c 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -126,3 +126,32 @@ public class CountingSort implements IArraySort { } ``` + +## 6. PHP 代码实现 + +```php +function countingSort($arr, $maxValue = null) +{ + if ($maxValue === null) { + $maxValue = max($arr); + } + for ($m = 0; $m < $maxValue + 1; $m++) { + $bucket[] = null; + } + + $arrLen = count($arr); + for ($i = 0; $i < $arrLen; $i++) { + if (!array_key_exists($arr[$i], $bucket)) { + $bucket[$arr[$i]] = 0; + } + $bucket[$arr[$i]]++; + } + + $sortedIndex = 0; + foreach ($bucket as $key => $len) { + if ($len !== null) $arr[$sortedIndex++] = $key; + } + + return $arr; +} +``` \ No newline at end of file diff --git a/9.bucketSort.md b/9.bucketSort.md index e2e4aa6..bd76a63 100644 --- a/9.bucketSort.md +++ b/9.bucketSort.md @@ -131,3 +131,45 @@ public class BucketSort implements IArraySort { } ``` + +## 5. PHP 代码实现 + +```php +function bucketSort($arr, $bucketSize = 5) +{ + if (count($arr) === 0) { + return $arr; + } + + $minValue = $arr[0]; + $maxValue = $arr[0]; + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] < $minValue) { + $minValue = $arr[$i]; + } else if ($arr[$i] > $maxValue) { + $maxValue = $arr[$i]; + } + } + + $bucketCount = floor(($maxValue - $minValue) / $bucketSize) + 1; + $buckets = array(); + for ($i = 0; $i < count($buckets); $i++) { + $buckets[$i] = []; + } + + for ($i = 0; $i < count($arr); $i++) { + $buckets[floor(($arr[$i] - $minValue) / $bucketSize)][] = $arr[$i]; + } + + $arr = array(); + for ($i = 0; $i < count($buckets); $i++) { + $bucketTmp = $buckets[$i]; + sort($bucketTmp); + for ($j = 0; $j < count($bucketTmp); $j++) { + $arr[] = $bucketTmp[$j]; + } + } + + return $arr; +} +``` \ No newline at end of file diff --git a/src/phpSortTest.php b/src/phpSortTest.php new file mode 100644 index 0000000..4fc59d5 --- /dev/null +++ b/src/phpSortTest.php @@ -0,0 +1,304 @@ + + * + * 主要参考了 JS 的写法及网上的一些写法。 + * + * Require: php -v >= 5.4 + * Test: php phpSortTest.php + */ + +function sortTest($func, $total = 5000) +{ + global $arr; + if (empty($arr)) { + $arr = range(1, $total); + echo "Verify sort md5: ", substr(md5(json_encode($arr)), 0, 8), "\r\n"; + shuffle($arr); + } + list($m1, $n1) = explode(' ', microtime()); + $res = $func($arr); + list($m2, $n2) = explode(' ', microtime()); + $time = round(($m2 - $m1) + ($n2 - $n1), 6); + echo " $func {$time}s " . substr(md5(json_encode($res)), 0, 8) . "\r\n"; +} + +function bubbleSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len; $i++) { + for ($j = 0; $j < $len - 1 - $i; $j++) { + if ($arr[$j] > $arr[$j+1]) { + $tmp = $arr[$j]; + $arr[$j] = $arr[$j+1]; + $arr[$j+1] = $tmp; + } + } + } + return $arr; +} + +function selectionSort($arr) +{ + $len = count($arr); + for ($i = 0; $i < $len - 1; $i++) { + $minIndex = $i; + for ($j = $i + 1; $j < $len; $j++) { + if ($arr[$j] < $arr[$minIndex]) { + $minIndex = $j; + } + } + $temp = $arr[$i]; + $arr[$i] = $arr[$minIndex]; + $arr[$minIndex] = $temp; + } + return $arr; +} + +function insertionSort($arr) +{ + $len = count($arr); + for ($i = 1; $i < $len; $i++) { + $preIndex = $i - 1; + $current = $arr[$i]; + while($preIndex >= 0 && $arr[$preIndex] > $current) { + $arr[$preIndex+1] = $arr[$preIndex]; + $preIndex--; + } + $arr[$preIndex+1] = $current; + } + return $arr; +} + +function shellSort($arr) +{ + $len = count($arr); + $temp = 0; + $gap = 1; + while($gap < $len / 3) { + $gap = $gap * 3 + 1; + } + for ($gap; $gap > 0; $gap = floor($gap / 3)) { + for ($i = $gap; $i < $len; $i++) { + $temp = $arr[$i]; + for ($j = $i - $gap; $j >= 0 && $arr[$j] > $temp; $j -= $gap) { + $arr[$j+$gap] = $arr[$j]; + } + $arr[$j+$gap] = $temp; + } + } + return $arr; +} + +function mergeSort($arr) +{ + $len = count($arr); + if ($len < 2) { + return $arr; + } + $middle = floor($len / 2); + $left = array_slice($arr, 0, $middle); + $right = array_slice($arr, $middle); + return merge(mergeSort($left), mergeSort($right)); +} + +function merge($left, $right) +{ + $result = []; + + while (count($left) > 0 && count($right) > 0) { + if ($left[0] <= $right[0]) { + $result[] = array_shift($left); + } else { + $result[] = array_shift($right); + } + } + + while (count($left)) + $result[] = array_shift($left); + + while (count($right)) + $result[] = array_shift($right); + + return $result; +} + +function quickSort($arr) +{ + if (count($arr) <= 1) + return $arr; + $middle = $arr[0]; + $leftArray = array(); + $rightArray = array(); + + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] > $middle) + $rightArray[] = $arr[$i]; + else + $leftArray[] = $arr[$i]; + } + $leftArray = quickSort($leftArray); + $leftArray[] = $middle; + + $rightArray = quickSort($rightArray); + return array_merge($leftArray, $rightArray); +} + + +function buildMaxHeap(&$arr) +{ + global $len; + for ($i = floor($len/2); $i >= 0; $i--) { + heapify($arr, $i); + } +} + +function heapify(&$arr, $i) +{ + global $len; + $left = 2 * $i + 1; + $right = 2 * $i + 2; + $largest = $i; + + if ($left < $len && $arr[$left] > $arr[$largest]) { + $largest = $left; + } + + if ($right < $len && $arr[$right] > $arr[$largest]) { + $largest = $right; + } + + if ($largest != $i) { + swap($arr, $i, $largest); + heapify($arr, $largest); + } +} + +function swap(&$arr, $i, $j) +{ + $temp = $arr[$i]; + $arr[$i] = $arr[$j]; + $arr[$j] = $temp; +} + +function heapSort($arr) { + global $len; + $len = count($arr); + buildMaxHeap($arr); + for ($i = count($arr) - 1; $i > 0; $i--) { + swap($arr, 0, $i); + $len--; + heapify($arr, 0); + } + return $arr; +} + +function countingSort($arr, $maxValue = null) +{ + if ($maxValue === null) { + $maxValue = max($arr); + } + for ($m = 0; $m < $maxValue + 1; $m++) { + $bucket[] = null; + } + + $arrLen = count($arr); + for ($i = 0; $i < $arrLen; $i++) { + if (!array_key_exists($arr[$i], $bucket)) { + $bucket[$arr[$i]] = 0; + } + $bucket[$arr[$i]]++; + } + + $sortedIndex = 0; + foreach ($bucket as $key => $len) { + if ($len !== null) $arr[$sortedIndex++] = $key; + } + + return $arr; +} + +function bucketSort($arr, $bucketSize = 5) +{ + if (count($arr) === 0) { + return $arr; + } + + $minValue = $arr[0]; + $maxValue = $arr[0]; + for ($i = 1; $i < count($arr); $i++) { + if ($arr[$i] < $minValue) { + $minValue = $arr[$i]; + } else if ($arr[$i] > $maxValue) { + $maxValue = $arr[$i]; + } + } + + $bucketCount = floor(($maxValue - $minValue) / $bucketSize) + 1; + $buckets = array(); + for ($i = 0; $i < count($buckets); $i++) { + $buckets[$i] = []; + } + + for ($i = 0; $i < count($arr); $i++) { + $buckets[floor(($arr[$i] - $minValue) / $bucketSize)][] = $arr[$i]; + } + + $arr = array(); + for ($i = 0; $i < count($buckets); $i++) { + $bucketTmp = $buckets[$i]; + sort($bucketTmp); + for ($j = 0; $j < count($bucketTmp); $j++) { + $arr[] = $bucketTmp[$j]; + } + } + + return $arr; +} + +function radixSort($arr, $maxDigit = null) +{ + if ($maxDigit === null) { + $maxDigit = max($arr); + } + $counter = []; + for ($i = 0; $i < $maxDigit; $i++) { + for ($j = 0; $j < count($arr); $j++) { + preg_match_all('/\d/', (string) $arr[$j], $matches); + $numArr = $matches[0]; + $lenTmp = count($numArr); + $bucket = array_key_exists($lenTmp - $i - 1, $numArr) + ? intval($numArr[$lenTmp - $i - 1]) + : 0; + if (!array_key_exists($bucket, $counter)) { + $counter[$bucket] = []; + } + $counter[$bucket][] = $arr[$j]; + } + $pos = 0; + for ($j = 0; $j < count($counter); $j++) { + $value = null; + if ($counter[$j] !== null) { + while (($value = array_shift($counter[$j])) !== null) { + $arr[$pos++] = $value; + } + } + } + } + + return $arr; +} + +$total = 2000; + +sortTest('bubbleSort', $total); +sortTest('selectionSort', $total); +sortTest('insertionSort', $total); +sortTest('shellSort', $total); +sortTest('mergeSort', $total); +sortTest('quickSort', $total); +sortTest('heapSort', $total); +sortTest('countingSort', $total); +sortTest('bucketSort', $total); +sortTest('radixSort', $total); From e100b91ddb51f7e4ce5e787e7800f5f1ac067f10 Mon Sep 17 00:00:00 2001 From: hustcc Date: Tue, 13 Nov 2018 21:03:15 +0800 Subject: [PATCH 33/52] change to lint-md --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index b2b108c..eefc643 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ -sudo: required -language: python -python: - - "2.7" +language: node_js +node_js: + - "10" before_install: - - pip install hint -script: - - hint . \ No newline at end of file + - npm i lint-md +script: npx lint-md ./ From fef886aebc3a01eeb70c706cb04704abc4c21315 Mon Sep 17 00:00:00 2001 From: hustcc Date: Tue, 13 Nov 2018 21:05:27 +0800 Subject: [PATCH 34/52] -g --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eefc643..8df8b91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,5 +2,5 @@ language: node_js node_js: - "10" before_install: - - npm i lint-md + - npm i -g lint-md script: npx lint-md ./ From 6c42a4931b95bf369d19612445d89f61faf2589e Mon Sep 17 00:00:00 2001 From: hustcc Date: Wed, 14 Nov 2018 09:45:06 +0800 Subject: [PATCH 35/52] hint -> lint-md --- .travis.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8df8b91..117276a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,4 @@ node_js: - "10" before_install: - npm i -g lint-md -script: npx lint-md ./ +script: lint-md ./ diff --git a/README.md b/README.md index a14f9c1..4c36daa 100644 --- a/README.md +++ b/README.md @@ -64,4 +64,4 @@ GitBook 在线阅读地址:[https://sort.hust.cc/](https://sort.hust.cc/)。 -本项目使用 [hint](https://github.com/hustcc/hint) 进行中文 Markdown 文件的格式检查,务必在提交 Pr 之前,保证 Markdown 格式正确。 +本项目使用 [lint-md](https://github.com/hustcc/lint-md) 进行中文 Markdown 文件的格式检查,务必在提交 Pr 之前,保证 Markdown 格式正确。 From fd6155a8606330fce301a4bcfdd8f3717136ad91 Mon Sep 17 00:00:00 2001 From: gallonyin Date: Thu, 15 Nov 2018 12:35:46 +0800 Subject: [PATCH 36/52] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BD=92=E5=B9=B6?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E7=A9=BA=E9=97=B4=E4=BD=BF=E7=94=A8(?= =?UTF-8?q?=E5=87=8F=E5=B0=91=E4=B8=8D=E5=BF=85=E8=A6=81copy)=20(#22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/java/main/MergeSort.java | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/java/main/MergeSort.java b/src/java/main/MergeSort.java index 7fec2b8..6457036 100644 --- a/src/java/main/MergeSort.java +++ b/src/java/main/MergeSort.java @@ -23,25 +23,25 @@ public int[] sort(int[] sourceArray) throws Exception { protected int[] merge(int[] left, int[] right) { int[] result = new int[left.length + right.length]; - int i = 0; - while (left.length > 0 && right.length > 0) { - if (left[0] <= right[0]) { - result[i++] = left[0]; - left = Arrays.copyOfRange(left, 1, left.length); + int l = 0, r = 0, len = 0; + while (len < left.length + right.length) { + if (left[l] <= right[r]) { + result[len++] = left[l++]; + + if (l == left.length) { + for (int i = r; i < right.length; i++) { + result[len++] = right[r++]; + } + } } else { - result[i++] = right[0]; - right = Arrays.copyOfRange(right, 1, right.length); - } - } + result[len++] = right[r++]; - while (left.length > 0) { - result[i++] = left[0]; - left = Arrays.copyOfRange(left, 1, left.length); - } - - while (right.length > 0) { - result[i++] = right[0]; - right = Arrays.copyOfRange(right, 1, right.length); + if (r == right.length) { + for (int i = l; i < left.length; i++) { + result[len++] = left[l++]; + } + } + } } return result; From a33fef7acbfa09fc5eaa332bb36966e9c89b7d15 Mon Sep 17 00:00:00 2001 From: hustcc Date: Tue, 13 Aug 2019 17:47:40 +0800 Subject: [PATCH 37/52] fix(*): update lint-md-cli lint-md -> lint-md-cli --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 117276a..2b6c65f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,5 +2,5 @@ language: node_js node_js: - "10" before_install: - - npm i -g lint-md + - npm i -g lint-md-cli script: lint-md ./ From 6cd1226d51169a68f9382a7460fa6db988741c47 Mon Sep 17 00:00:00 2001 From: kkxiaojun <985531883@qq.com> Date: Tue, 13 Aug 2019 17:51:12 +0800 Subject: [PATCH 38/52] Update 7.heapSort.md (#24) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update 7.heapSort.md 建议修改下第一步的说明 * Update 7.heapSort.md --- 7.heapSort.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/7.heapSort.md b/7.heapSort.md index 35b24ec..394d929 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -10,7 +10,7 @@ ## 1. 算法步骤 -1. 创建一个堆 H[0……n-1]; +1. 将待排序序列构建成一个堆 H[0……n-1],根据(升序降序需求)选择大顶堆或小顶堆; 2. 把堆首(最大值)和堆尾互换; @@ -254,4 +254,4 @@ function heapSort($arr) { } return $arr; } -``` \ No newline at end of file +``` From a2443c89e45aa25d31d77f6a46dc1d4a3f352570 Mon Sep 17 00:00:00 2001 From: TonyHe Date: Tue, 13 Aug 2019 19:24:17 +0800 Subject: [PATCH 39/52] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20PHP=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=83=A8=E5=88=86=E9=94=99=E8=AF=AF=20(#35)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 8.countingSort.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/8.countingSort.md b/8.countingSort.md index efabf9c..d0930cf 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -149,7 +149,11 @@ function countingSort($arr, $maxValue = null) $sortedIndex = 0; foreach ($bucket as $key => $len) { - if ($len !== null) $arr[$sortedIndex++] = $key; + if($len !== null){ + for($j = 0; $j < $len; $j++){ + $arr[$sortedIndex++] = $key; + } + } } return $arr; From 545fa6de16e7bf84aa697cc3df5d6b6364bfb936 Mon Sep 17 00:00:00 2001 From: hoop208 <137478244@qq.com> Date: Tue, 13 Aug 2019 19:30:44 +0800 Subject: [PATCH 40/52] Update 4.shellSort.md (#36) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正希尔排序java实现的gap计算 --- 4.shellSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4.shellSort.md b/4.shellSort.md index 187ac0e..cfa59f5 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -99,7 +99,7 @@ public class ShellSort implements IArraySort { int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); int gap = 1; - while (gap < arr.length) { + while (gap < arr.length/3) { gap = gap * 3 + 1; } From bee257b71af4b1766ca795f4437ada21270786e7 Mon Sep 17 00:00:00 2001 From: hustcc Date: Thu, 22 Aug 2019 19:05:24 +0800 Subject: [PATCH 41/52] Create FUNDING.yml --- .github/FUNDING.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..6e86d35 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: ['https://paypal.me/hustcc', 'https://atool.vip'] From 00f39c74fa039f9faa1727e570a807f9d84003f4 Mon Sep 17 00:00:00 2001 From: goldSunshine <892697603@qq.com> Date: Tue, 3 Sep 2019 13:53:03 +0800 Subject: [PATCH 42/52] =?UTF-8?q?=E5=9F=BA=E6=95=B0=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0python=E5=AE=9E=E7=8E=B0=20(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 增加python实现 * 基数排序格式调整 --- 10.radixSort.md | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/10.radixSort.md b/10.radixSort.md index 0bcd341..2da94b8 100644 --- a/10.radixSort.md +++ b/10.radixSort.md @@ -7,7 +7,7 @@ 基数排序有两种方法: -这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异: +这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异案例看大家发的: - 基数排序:根据键值的每位数字来分配桶; - 计数排序:每个桶只存储单一键值; @@ -49,7 +49,39 @@ function radixSort(arr, maxDigit) { } ``` -## 4. Java 代码实现 + +## 4. python 代码实现 + +```python +def radix(arr): + + digit = 0 + max_digit = 1 + max_value = max(arr) + #找出列表中最大的位数 + while 10**max_digit < max_value: + max_digit = max_digit + 1 + + while digit < max_digit: + temp = [[] for i in range(10)] + for i in arr: + #求出每一个元素的个、十、百位的值 + t = int((i/10**digit)%10) + temp[t].append(i) + + coll = [] + for bucket in temp: + for i in bucket: + coll.append(i) + + arr = coll + digit = digit + 1 + + return arr +``` + + +## 5. Java 代码实现 ```java /** @@ -134,7 +166,7 @@ public class RadixSort implements IArraySort { } ``` -## 5. PHP 代码实现 +## 6. PHP 代码实现 ```php function radixSort($arr, $maxDigit = null) @@ -169,4 +201,4 @@ function radixSort($arr, $maxDigit = null) return $arr; } -``` \ No newline at end of file +``` From 75a861bfd0f26c639a182fef2b5bdc4a5e4a90da Mon Sep 17 00:00:00 2001 From: nchhabra1311 Date: Wed, 9 Oct 2019 06:53:44 +0530 Subject: [PATCH 43/52] Added radix sort in pythonSortTest.py (#37) * Added radix sort in pythonSortTest.py * Improved code readability as suggested --- src/pythonSortTest.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/pythonSortTest.py b/src/pythonSortTest.py index ea765d2..bf092db 100644 --- a/src/pythonSortTest.py +++ b/src/pythonSortTest.py @@ -1,4 +1,4 @@ -''' +''' # Create by LokiSharp(loki.sharp#gmail) at 2017-1-22 ''' @@ -176,6 +176,34 @@ def countingSort(arr, maxValue=None): bucket[j] -= 1 return arr +def radix_count(exp1): + global list + n = len(list) + output = [0] * (n) + count = [0] * (10) + for i in range(0, n): + index = (list[i] / exp1) + count[(index) % 10] += 1 + for i in range(1,10): + count[i] += count[i - 1] + i = n - 1 + while i >= 0: + index = (list[i]/exp1) + output[count[(index) % 10] - 1] = list[i] + count[(index) % 10] -= 1 + i -= 1 + i = 0 + for i in range(0,len(list)): + list[i] = output[i] + +def radixSort(): + global list + max1 = max(list) + exp = 1 + while max1 / exp > 0: + radix_count(exp) + exp *= 10 + if __name__ == '__main__': sortTest(bubbleSort, TOTAL) @@ -185,3 +213,4 @@ def countingSort(arr, maxValue=None): sortTest(mergeSort, TOTAL) sortTest(quickSort, TOTAL) sortTest(heapSort, TOTAL) + sortTest(radixSort, TOTAL) From f89b90800f985d002a7f972088e95e254bdf3219 Mon Sep 17 00:00:00 2001 From: JulioFeng Date: Tue, 13 Apr 2021 16:20:52 +0800 Subject: [PATCH 44/52] Update 4.shellSort.md --- 4.shellSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4.shellSort.md b/4.shellSort.md index cfa59f5..e1e99a3 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -69,7 +69,7 @@ def shellSort(arr): func shellSort(arr []int) []int { length := len(arr) gap := 1 - for gap < gap/3 { + for gap < length/3 { gap = gap*3 + 1 } for gap > 0 { From e1b1c66c569c4b9b5db7531b209382acad4922df Mon Sep 17 00:00:00 2001 From: shouao <792417939@qq.com> Date: Sat, 1 Jan 2022 06:34:55 +0800 Subject: [PATCH 45/52] add cplusplus version in shell-sort and merg-sort --- 4.shellSort.md | 20 ++++++++++++++++ 5.mergeSort.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/4.shellSort.md b/4.shellSort.md index cfa59f5..6f0bc7f 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -144,3 +144,23 @@ function shellSort($arr) return $arr; } ``` + +## 7. C++ 代码实现 + +```cpp +void shellSort(vector& nums) { + int gap = 1; + while (gap < (int)nums.size() / 3) { + gap = gap * 3 + 1; + } + for (; gap >= 1; gap /= 3) { + for (int i = 0; i < gap; ++i) { + for (int j = i + gap; j < nums.size(); j += gap) { + for (int k = j; k - gap >= 0 && nums[k] < nums[k - gap]; k -= gap) { + swap(nums[k], nums[k - gap]); + } + } + } + } +} +``` \ No newline at end of file diff --git a/5.mergeSort.md b/5.mergeSort.md index bf0de32..f49f547 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -222,4 +222,69 @@ function merge($left, $right) return $result; } +``` + +## 9. C++ 代码实现 + +### 9.1 递归版 + +```cpp +void mergeSort(vector& nums, int l, int r) { + if (r - l <= 1) { + return; + } + int mid = (l + r) / 2; + mergeSort(nums, l, mid); + mergeSort(nums, mid, r); + int index = 0; + int ptrL = l; + int ptrR = mid; + static vectortempary(50000); + while (ptrL != mid && ptrR != r) { + if (nums[ptrL] < nums[ptrR]) { + tempary[index++] = nums[ptrL++]; + } else { + tempary[index++] = nums[ptrR++]; + } + } + while (ptrL != mid) { + tempary[index++] = nums[ptrL++]; + } + while (ptrR != r) { + tempary[index++] = nums[ptrR++]; + } + copy(tempary.begin(), tempary.begin() + index, nums.begin() + l); +} +``` + +### 9.2 迭代版 + +```cpp +void mergeSort(vector& nums) { + for (int step = 1; step <= nums.size(); step *= 2) { + for (int i = 0; i + step < nums.size(); i += 2 * step) { + int l = i; + int r = min((int)nums.size(), i + step * 2); + int mid = i + step; + int index = 0; + int ptrL = l; + int ptrR = mid; + static vectortempary(50000); + while (ptrL != mid && ptrR != r) { + if (nums[ptrL] < nums[ptrR]) { + tempary[index++] = nums[ptrL++]; + } else { + tempary[index++] = nums[ptrR++]; + } + } + while (ptrL != mid) { + tempary[index++] = nums[ptrL++]; + } + while (ptrR != r) { + tempary[index++] = nums[ptrR++]; + } + copy(tempary.begin(), tempary.begin() + index, nums.begin() + l); + } + } +} ``` \ No newline at end of file From 3125abbfb3af6171f3746cd13422aebf139af7eb Mon Sep 17 00:00:00 2001 From: shouao <58040617+chenshouao@users.noreply.github.com> Date: Sat, 1 Jan 2022 06:42:15 +0800 Subject: [PATCH 46/52] Update 4.shellSort.md --- 4.shellSort.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/4.shellSort.md b/4.shellSort.md index 6f0bc7f..fca5e60 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -153,14 +153,15 @@ void shellSort(vector& nums) { while (gap < (int)nums.size() / 3) { gap = gap * 3 + 1; } - for (; gap >= 1; gap /= 3) { - for (int i = 0; i < gap; ++i) { - for (int j = i + gap; j < nums.size(); j += gap) { - for (int k = j; k - gap >= 0 && nums[k] < nums[k - gap]; k -= gap) { - swap(nums[k], nums[k - gap]); + for (; gap >= 1; gap /= 3) { + for (int i = 0; i < gap; ++i) { + for (int j = i + gap; j < nums.size(); j += gap) { + for (int k = j; k - gap >= 0 && nums[k] < nums[k - gap]; k -= gap) { + swap(nums[k], nums[k - gap]); } } } } } -``` \ No newline at end of file + +``` From 6773da4867c9c79fa3a108fca8bd511b6a342dfb Mon Sep 17 00:00:00 2001 From: shouao <58040617+chenshouao@users.noreply.github.com> Date: Sat, 1 Jan 2022 06:47:37 +0800 Subject: [PATCH 47/52] Update 5.mergeSort.md --- 5.mergeSort.md | 51 ++++++++++---------------------------------------- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/5.mergeSort.md b/5.mergeSort.md index f49f547..c7b2622 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -226,16 +226,8 @@ function merge($left, $right) ## 9. C++ 代码实现 -### 9.1 递归版 - ```cpp -void mergeSort(vector& nums, int l, int r) { - if (r - l <= 1) { - return; - } - int mid = (l + r) / 2; - mergeSort(nums, l, mid); - mergeSort(nums, mid, r); +void merge(vector& nums, int l, int mid, int r) { int index = 0; int ptrL = l; int ptrR = mid; @@ -251,40 +243,17 @@ void mergeSort(vector& nums, int l, int r) { tempary[index++] = nums[ptrL++]; } while (ptrR != r) { - tempary[index++] = nums[ptrR++]; + tempary[index++] = nums[ptrR++]; } copy(tempary.begin(), tempary.begin() + index, nums.begin() + l); } -``` - -### 9.2 迭代版 - -```cpp -void mergeSort(vector& nums) { - for (int step = 1; step <= nums.size(); step *= 2) { - for (int i = 0; i + step < nums.size(); i += 2 * step) { - int l = i; - int r = min((int)nums.size(), i + step * 2); - int mid = i + step; - int index = 0; - int ptrL = l; - int ptrR = mid; - static vectortempary(50000); - while (ptrL != mid && ptrR != r) { - if (nums[ptrL] < nums[ptrR]) { - tempary[index++] = nums[ptrL++]; - } else { - tempary[index++] = nums[ptrR++]; - } - } - while (ptrL != mid) { - tempary[index++] = nums[ptrL++]; - } - while (ptrR != r) { - tempary[index++] = nums[ptrR++]; - } - copy(tempary.begin(), tempary.begin() + index, nums.begin() + l); - } +void mergeSort(vector& nums, int l, int r) { + if (r - l <= 1) { + return; } + int mid = (l + r) / 2; + mergeSort(nums, l, mid); + mergeSort(nums, mid, r); + merge(nums, l, mid, r); } -``` \ No newline at end of file +``` From 0c614a86da0d9e98395091e9173bcadb9283ec2c Mon Sep 17 00:00:00 2001 From: shouao <58040617+chenshouao@users.noreply.github.com> Date: Sat, 1 Jan 2022 06:57:11 +0800 Subject: [PATCH 48/52] Update 5.mergeSort.md --- 5.mergeSort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5.mergeSort.md b/5.mergeSort.md index c7b2622..c98680b 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -247,7 +247,7 @@ void merge(vector& nums, int l, int mid, int r) { } copy(tempary.begin(), tempary.begin() + index, nums.begin() + l); } -void mergeSort(vector& nums, int l, int r) { +void mergeSort(vector& nums, int l, int r) {// range is [l, r), so if there is a 0-index array arr whose length is n, "mergeSort(arr, 0, n)" should be called if (r - l <= 1) { return; } From f62636bede725aa4068b5ba3928d8d65392ee0e8 Mon Sep 17 00:00:00 2001 From: shouao <58040617+chenshouao@users.noreply.github.com> Date: Sat, 1 Jan 2022 06:59:10 +0800 Subject: [PATCH 49/52] Update 5.mergeSort.md --- 5.mergeSort.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/5.mergeSort.md b/5.mergeSort.md index c98680b..d28fb29 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -247,8 +247,8 @@ void merge(vector& nums, int l, int mid, int r) { } copy(tempary.begin(), tempary.begin() + index, nums.begin() + l); } -void mergeSort(vector& nums, int l, int r) {// range is [l, r), so if there is a 0-index array arr whose length is n, "mergeSort(arr, 0, n)" should be called - if (r - l <= 1) { +void mergeSort(vector& nums, int l, int r) {// sort the range [l, r), so if there is a 0-index array arr whose length is n + if (r - l <= 1) { //and you want sort the whole array, "mergeSort(arr, 0, n)" should be called return; } int mid = (l + r) / 2; From 4534fa5eff5ec2a11937c42358c1537b36dd60ae Mon Sep 17 00:00:00 2001 From: shouao <58040617+chenshouao@users.noreply.github.com> Date: Sat, 1 Jan 2022 07:04:15 +0800 Subject: [PATCH 50/52] Update 5.mergeSort.md --- 5.mergeSort.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/5.mergeSort.md b/5.mergeSort.md index d28fb29..e55b90c 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -231,7 +231,8 @@ void merge(vector& nums, int l, int mid, int r) { int index = 0; int ptrL = l; int ptrR = mid; - static vectortempary(50000); + static vectortempary; + tempary.resize(nums.size()); while (ptrL != mid && ptrR != r) { if (nums[ptrL] < nums[ptrR]) { tempary[index++] = nums[ptrL++]; From 1f7b01b699f921b36e9d02900a7243de3a1e22d5 Mon Sep 17 00:00:00 2001 From: shouao <58040617+chenshouao@users.noreply.github.com> Date: Sat, 1 Jan 2022 07:18:06 +0800 Subject: [PATCH 51/52] Update 5.mergeSort.md --- 5.mergeSort.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/5.mergeSort.md b/5.mergeSort.md index e55b90c..c030d8f 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -227,34 +227,36 @@ function merge($left, $right) ## 9. C++ 代码实现 ```cpp -void merge(vector& nums, int l, int mid, int r) { +void merge(vector& arr, int l, int mid, int r) { int index = 0; int ptrL = l; int ptrR = mid; static vectortempary; - tempary.resize(nums.size()); + if (arr.size() > tempary.size()) { + tempary.resize(arr.size()); + } while (ptrL != mid && ptrR != r) { - if (nums[ptrL] < nums[ptrR]) { - tempary[index++] = nums[ptrL++]; + if (arr[ptrL] < arr[ptrR]) { + tempary[index++] = arr[ptrL++]; } else { - tempary[index++] = nums[ptrR++]; + tempary[index++] = arr[ptrR++]; } } while (ptrL != mid) { - tempary[index++] = nums[ptrL++]; + tempary[index++] = arr[ptrL++]; } while (ptrR != r) { - tempary[index++] = nums[ptrR++]; + tempary[index++] = arr[ptrR++]; } - copy(tempary.begin(), tempary.begin() + index, nums.begin() + l); + copy(tempary.begin(), tempary.begin() + index, arr.begin() + l); } -void mergeSort(vector& nums, int l, int r) {// sort the range [l, r), so if there is a 0-index array arr whose length is n - if (r - l <= 1) { //and you want sort the whole array, "mergeSort(arr, 0, n)" should be called +void mergeSort(vector& arr, int l, int r) { // sort the range [l, r) in arr + if (r - l <= 1) { return; } int mid = (l + r) / 2; - mergeSort(nums, l, mid); - mergeSort(nums, mid, r); - merge(nums, l, mid, r); + mergeSort(arr, l, mid); + mergeSort(arr, mid, r); + merge(arr, l, mid, r); } ``` From 75cb7d6954aead08bb90d934e46655a8307d1d13 Mon Sep 17 00:00:00 2001 From: shouao <58040617+chenshouao@users.noreply.github.com> Date: Sat, 1 Jan 2022 07:19:37 +0800 Subject: [PATCH 52/52] Update 4.shellSort.md --- 4.shellSort.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/4.shellSort.md b/4.shellSort.md index fca5e60..858a78f 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -148,20 +148,19 @@ function shellSort($arr) ## 7. C++ 代码实现 ```cpp -void shellSort(vector& nums) { +void shellSort(vector& arr) { int gap = 1; - while (gap < (int)nums.size() / 3) { + while (gap < (int)arr.size() / 3) { gap = gap * 3 + 1; } for (; gap >= 1; gap /= 3) { for (int i = 0; i < gap; ++i) { - for (int j = i + gap; j < nums.size(); j += gap) { - for (int k = j; k - gap >= 0 && nums[k] < nums[k - gap]; k -= gap) { - swap(nums[k], nums[k - gap]); + for (int j = i + gap; j < arr.size(); j += gap) { + for (int k = j; k - gap >= 0 && arr[k] < arr[k - gap]; k -= gap) { + swap(arr[k], arr[k - gap]); } } } } } - ```