-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic_sort.go
More file actions
204 lines (172 loc) · 4.32 KB
/
basic_sort.go
File metadata and controls
204 lines (172 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package basic_algorithms
import "fmt"
// 1) 冒泡,持续比较相邻元素,大的挪到后面 O(n^2)
func BubbleSort(array []int) []int {
n:=len(array)
for i:=0;i<n;i++{
for j:=1;j<n-i;j++{
if array[j-1]>array[j]{
array[j-1],array[j]=array[j],array[j-1]
}
}
}
return array
}
// 2) 选择,不断地选择剩余元素中的最小者(找到最小的元素,和第一个元素交换;从剩下的元素找到最小的元素,和第二个元素交换,以此类推) O(n^2)
func SelectSort(array []int)[]int {
n:=len(array)
for i:=0;i<n;i++{
min:=i //min存放最小值的元素下标
for j:=i+1;j<n;j++{
if array[j]<array[min]{
min=j
}
}
array[i],array[min]=array[min],array[i]
}
return array
}
// 3) 插入,对于未排序数据,在已排序数据中,从后往前扫描,插入 1,3,5,6,8 7(8后移一位,插到8的前面)
func InsertSort(array []int)[]int {
n:=len(array)
for i:=1;i<n;i++{
for j:=i-1;j>=0&&array[j]>array[j+1];j--{
array[j], array[j+1] = array[j+1],array[j]
}
}
return array
}
// 4)快速排序:找基准值(一般是取第一个或最后一个称为基准);划分区(所有比基准小的元素置于基准左侧,比基准大的元素置于右侧;左右两个指针;左比基准值大,右比基准值小,交换;相遇停止交换);递归调用
func Partition(arr []int, low, high int) int {
baseNum := arr[low] //最左边元素作为基准值,指针从右边开始移动
for low < high {
for arr[high] >= baseNum && high > low {
high--
}
arr[low] = arr[high]
for arr[low] <= baseNum && high > low {
low++
}
arr[high] = arr[low]
}
arr[high] = baseNum //第一轮low和high相等时均为5,此时交换停止 [5 1 2 4 3 6 9 7 10 8]
return high
}
func QuickSort(arr []int, low, high int) []int {
if low >= high {
return arr
}
mid := Partition(arr, low, high)
QuickSort(arr, low, mid-1)
QuickSort(arr, mid+1, high)
return arr
}
// 5)堆排序 堆排序在 top K 问题中使用比较频繁;父节点的键值总大于等于任何一子节点的键值;每个节点的左右子树都是一个二叉堆(最大堆或最小堆)
// 参考链接:http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/
//最大堆调整:将堆的末端子节点作调整,使得子节点永远小于父节点
func heapify(array []int, i, arrLen int) {
left := 2*i + 1
right := 2*i + 2
largest := i
if left < arrLen && array[left] > array[largest] {
largest = left
}
if right < arrLen && array[right] > array[largest] {
largest = right
}
if largest != i {
array[i],array[largest]=array[largest],array[i]
heapify(array, largest, arrLen)
}
}
func buildMaxHeap(array []int, arrLen int) {
for i := arrLen / 2; i >= 0; i-- {
heapify(array, i, arrLen)
}
fmt.Println(array)
}
func HeapSort(arr []int) []int {
arrLen := len(arr)
buildMaxHeap(arr, arrLen)
for i := arrLen - 1; i >= 0; i-- {
arr[0],arr[i]=arr[i],arr[0]
arrLen -= 1
heapify(arr, 0, arrLen)
}
return arr
}
// 6)归并,两个有序数组归并成更大的有序数据 ???
//迭代法实现
func MergeSort(array []int) []int{
n := len(array)
if n < 2 {
return array
}
key := n / 2
left := MergeSort(array[0:key])
right := MergeSort(array[key:])
return merge(left, right)
}
func merge(left []int, right []int) []int{
newArr := make([]int, len(left)+len(right))
i, j, index :=0,0,0
for {
if left[i] > right[j] {
newArr[index] = right[j]
index++
j++
if j == len(right) {
copy(newArr[index:], left[i:])
break
}
}else{
newArr[index] = left[i]
index++
i++
if i == len(left) {
copy(newArr[index:], right[j:])
break
}
}
}
return newArr
}
//递归法实现
func MergeRecursive(data []int) []int {
sum := len(data)
if sum <= 1 {
return data
}
left := data[0 : sum/2]
lSize := len(left)
if lSize >= 2 {
left = MergeRecursive(left)
}
right := data[sum/2:]
rSize := len(right)
if rSize >= 2 {
right = MergeRecursive(right)
}
j := 0
t := 0
arr := make([]int, sum)
//fmt.Println(left, right, data)
for i := 0; i < sum; i++ {
if j < lSize && t < rSize {
if left[j] <= right[t] {
arr[i] = left[j]
j++
} else {
arr[i] = right[t]
t++
}
} else if j >= lSize{
arr[i] = right[t]
t++
} else if t >= rSize{
arr[i] = left[j]
j++
}
}
return arr
}