From 1c2d0cd647986c70d677e80aab35240885351ac2 Mon Sep 17 00:00:00 2001 From: bonfy Date: Thu, 26 Jan 2017 20:22:17 +0800 Subject: [PATCH 1/2] Add go code 1-6 --- 1.bubbleSort.md | 16 ++++ 2.selectionSort.md | 18 ++++ 3.insertionSort.md | 17 ++++ 4.shellSort.md | 25 ++++++ 5.mergeSort.md | 42 +++++++++- 6.quickSort.md | 35 ++++++++ goSortTest.go | 203 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 355 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..f4dfcd5 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -49,3 +49,20 @@ def insertionSort(arr): arr[preIndex+1] = current    return arr ``` + +## 5. Go 代码实现 +```go +func insertionSort(arr []int) []int { + // length := len(arr) + 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/goSortTest.go b/goSortTest.go new file mode 100755 index 0000000..757f014 --- /dev/null +++ b/goSortTest.go @@ -0,0 +1,203 @@ +package main + +import ( + "fmt" + "math/rand" + "time" +) + +// 初始化 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 { + // length := len(arr) + 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 +} + +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) +} From e8f7b86cc1c18b573eb52dd30cd80e072a3559a4 Mon Sep 17 00:00:00 2001 From: bonfy Date: Mon, 6 Feb 2017 18:07:40 +0800 Subject: [PATCH 2/2] add 7&8 --- 3.insertionSort.md | 1 - 7.heapSort.md | 41 +++++++++++++++++++++++++++++++++++++++++ 8.countingSort.md | 26 ++++++++++++++++++++++++++ goSortTest.go | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/3.insertionSort.md b/3.insertionSort.md index f4dfcd5..11ed672 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -53,7 +53,6 @@ def insertionSort(arr): ## 5. Go 代码实现 ```go func insertionSort(arr []int) []int { - // length := len(arr) for i := range arr { preIndex := i - 1 current := 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 index 757f014..3738cf0 100755 --- a/goSortTest.go +++ b/goSortTest.go @@ -6,6 +6,9 @@ import ( "time" ) +/* global varialbe for heapsort*/ +var arrLen int + // 初始化 array with num func initArray(num int) []int { if num < 1 { @@ -88,7 +91,6 @@ func selectionSort(arr []int) []int { // insertion sort func insertionSort(arr []int) []int { - // length := len(arr) for i := range arr { preIndex := i - 1 current := arr[i] @@ -188,6 +190,40 @@ func partition(arr []int, left, right int) int { 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] } @@ -200,4 +236,5 @@ func main() { test_func(num, shellSort) test_func(num, mergeSort) test_func(num, quickSort) + test_func(num, heapSort) }