1. 程式人生 > 其它 >go語言實現快速排序和堆排序

go語言實現快速排序和堆排序

package example

import (
    "fmt"
    "math/rand"
    "testing"

    "gopkg.in/go-playground/assert.v1"
)//Test_example 排序
func Test_example(t *testing.T) {
    t.Run("選擇排序",sort1) //每次比較未排序的數,從中選出最大的數方到前面
    t.Run("氣泡排序",sort2) //n個元素比較n-1躺,每趟比較n-i-1次
    t.Run("快速排序",sort3) //找基準元素,從基準右邊開始比較,小於基準的元素交換到左邊;然後比較基準左邊的元素,大於基準的元素交換到右邊
t.Run("堆排序",sort4) } func sort1(t *testing.T){ //nums:=make([]int,0,10) var nums = []int {9,8,3,4,5,2,5,3} for i:=0;i<len(nums)-1;i++{ for j:=i+1;j<len(nums);j++{ if nums[i]>=nums[j]{ tmp:=nums[i] nums[i]=nums[j] nums[j]
=tmp } } } assert.Equal(t,[]int{2,3,3,4,5,5,8,9},nums) } func sort2(t *testing.T){ //nums:=make([]int,0,10) var nums = []int {9,8,3,4,5,2,5,3} for i:=0;i<len(nums)-1;i++{ //n個元素進行n-1次排序 for j:=0;j<len(nums)-i-1;j++{ //每趟排序比較的次數 if nums[j]>=nums[j+1
]{ tmp:=nums[j] nums[j]=nums[j+1] nums[j+1]=tmp } } } assert.Equal(t,[]int{2,3,3,4,5,5,8,9},nums) } func sort3(t *testing.T){ var nums = []int {9,8,3,4,5,2,5,3} quickPow(0,len(nums)-1,nums) assert.Equal(t,[]int{2,3,3,4,5,5,8,9},nums) } func quickPow(le,ri int,nums []int){ if le>=ri { return } pos:=findBase(le,ri,nums) quickPow(le,pos-1,nums) quickPow(pos+1,ri,nums) } func findBase(le,ri int,nums []int) int{ base:=nums[le] for;le<ri;{ for;le<ri&&nums[ri]>=base;{ ri-- } nums[le]=nums[ri] for;le<ri&&nums[le]<=base;{ le++ } nums[ri]=nums[le] } nums[le]=base return le } var heap []int func sort4(t *testing.T){ var args = []int {9,8,3,4,5,2,5,3} for i:=range args{ insertHeap(args[i]) } fmt.Println(heap) fmt.Println("heap",len(heap)) for i:=0;i<len(args);i++{ fmt.Printf("%v ",heap[0]) deleteHeap() } assert.Equal(t,8,8) } //insertHeap 往堆中插入一個元素 func insertHeap(n int){ heap=append(heap,n) index:=len(heap)-1 for;index>0;{ root:=index/2 if heap[root]>heap[index]{ tmp:=heap[root] heap[root]=heap[index] heap[index]=tmp }else{ break } index=root } } //deleteHeap 刪除堆頂元素 func deleteHeap(){ index:=len(heap)-1 if index<0{ //堆為空 return } //交換堆頂和堆底元素 heap[0]=heap[index] root:=0 //從堆頂往下維護最小堆的性質,迴圈條件是一定要有左兒子 for;root*2+1<=len(heap)-1;{ le:=root*2+1 ri:=root*2+2 //結束條件1:右兒子不存在||左右兒子都存在的情況下左兒子更小 if ri>=len(heap)-1||heap[le]<=heap[ri]{ if heap[root]>heap[le]{ tmp:=heap[root] heap[root]=heap[le] heap[le]=tmp }else{ break } root=le }else{//結束條件2:左右兒子都存在的情況下右兒子更小,交換父節點和右兒子節點 if heap[root]>heap[ri]{ tmp:=heap[root] heap[root]=heap[ri] heap[ri]=tmp }else{ break } root=ri } } heap=heap[:len(heap)-1] return }