冒泡排序:
分解思想:
1.每次取到最大的数和第i位交换
//取数组最大的数 遍历一遍数组 找到最大的
func GetMax(arr[] int){
for j:=1;j<len(arr);j++{
//找到数组中最小的值 交换到数组的第一位
if arr[j-1] < arr[j]{
arr[j-1],arr[j] = arr[j],arr[j-1]
}
}
}
2.然后在 对i + 1位重复第一步 不停循环 直到数组尾部
func BubbleSort(arr[] int) []int{
for i:=0;i<len(arr);i++{
// 9 5 3 三个数
//第一次arr[0:] 取 // 9 5 3 调用GetMax()找到 9 那么第i就改为 9
//第二次取arr[1:] /5 3
//第三次arr[2:] /3 由于只有一位 不需要查找
maxnum := GetMax(arr[i:])
arr[i] = maxnum
fmt.Printf("\n第%d次排序, %v",i,arr)
}
return arr
}
//冒泡排序完整版
//适用场景: 对已经有序的数组进行插入 算法复杂度:On
//对于普通场景:On的复杂度
func BubbleSort(arr[] int) []int{
for i:=0;i<len(arr);i++{
for j:=i+1;j<len(arr);j++{
if arr[i] > arr[j]{
arr[i],arr[j] = arr[j],arr[i]
}
}
fmt.Printf("\n第%d次排序, %v",i,arr)
}
return arr
}
堆排序
堆排序 实际就是 一个满二叉树 遍历所有父节点,父节 如果子节点小于 父节点就执行替换。
一颗二叉树的深度为:n/2 -1
左节点的位置为:2n + 1
右节点的位置为:2n + 2
堆排序代码
func HeapSort(arr []int,topn int) []int{
length := len(arr)
for i:=1;i<=length;i++{
lastlen := length -i
HeapSortMax(arr,lastlen)
if i< length {
arr[0],arr[lastlen] = arr[lastlen],arr[0]
}
if topn - i ==0{
break
}
}
return arr[len(arr) - topn:]
}
//每次从堆中 取一个最大数 放到 i处
func HeapSortMax(arr[] int,length int) []int{
if length <= 1{
return arr
}else{
depth := length/2 -1
for i:=depth;i>=0;i--{
topmax := i //最大的在i位置
leftchild := 2 * i + 1
rightchild := 2 * i + 2
if leftchild <= length && arr[leftchild] > arr[topmax]{
topmax = leftchild
}
if rightchild <= length && arr[rightchild] >arr[topmax]{
topmax = rightchild
}
if topmax != i{
arr[i],arr[topmax] = arr[topmax],arr[i]
}
}
return arr
}
}
func main(){
arr := []int{1,34,54,12,32,12,65,23,67}
fmt.Println(HeapSortMax(arr,len(arr)))
}
希尔排序
func shellsort(arr []int) []int{
if len(arr) <= 1 {
return arr
}else{
gap := len(arr)/2
for gap > 0{
for i:=0;i<gap;i++{
ShellSortStep(arr,i,gap)
}
gap/=2
}
return arr
}
}
func ShellSortStep(arr[] int,start int,gap int){
length := len(arr)
for i:= start + gap;i<length;i+=gap{
j := i - gap
bak := arr[i]
for j >=0 && bak < arr[j] {
arr[j + gap] = arr[j]
j -= gap
}
arr[j + gap] =bak
}
}
希尔排序并发版
func gourtinesort(arr []int){
if len(arr) <2 || arr == nil{
return
}
cpunum := runtime.NumCPU()
wg := sync.WaitGroup{}
for gap := len(arr);gap >0;gap/=2{
wg.Add(cpunum)
ch := make(chan int,1000)
go func(){
for k:=0;k<gap;k++{
ch <- k
}
close(ch)
}()
for k:=0;k<cpunum;k++{
go func() {
for v:= range ch{
fmt.Println(v,"XXX")
ShellSortStep(arr,v,gap)
}
wg.Done()
}()
}
wg.Wait()
}
fmt.Println(arr)
}
插入排序
func insertsort(arr []int) []int{
if len(arr) <= 1{
return arr
}
for m :=i+1;m<len(arr);m++{
j := m -1
tmp :=arr[m]
for j >= 0 && tmp < arr[j]{
arr[j+1] = arr[j]
j --
}
arr[j+1] = tmp
}
return arr
}
插入排序 特别像 老师在帮我们排队时 找到一个人作为标准 然后高于 这个人的排在右边低于这个人的 排在左边 如果这么想 再细想的话 如果找一个最高 或者最低的人作为标准 去排的话 那么 所有其他人 都要调整位置 这样的话 就要交换N-1次。