直接选择排序
大家都知道我们一般不会用直接选择排序,因为时间复杂度比较高,相信大家对直接插入排序都不陌生,就是每次确定一个当前的最小值或者最大值,我也在这个基础上进行了一点小改进,即每次都确定一个最大值和最小值
代码:
func SelectSort(nums []int,n int) []int{
first:=0
end:=n-1
for first<end{ //用两个位置标量来控制结束
min:=first
max:=end
for i:=first;i<=end;i++{
if nums[i]<nums[min]{
min=i
}
if nums[i]>nums[max]{
max=i
}
}
nums[min],nums[first]=swap(nums[min],nums[first])
if min!=end && max!=first{
nums[max],nums[end]=swap(nums[max],nums[end])
}
first++
end--
}
return nums
}
func swap(a,b int)(int ,int){
temp:=a
a=b
b=temp
return a,b
}
堆排序
以前我是非常拒绝堆排序的,不是因为他不好,是因为我总得他太复杂,不好理解,总是怕用的时候出错,事实也证明的确容易出错,主要是因为他不仅要排序,还有有一个函数不断进行调整,但是这几天好好看了之后,这个的确是一个非常好的排序算法,巧妙地利用二叉树的这种特性,大顶堆(小顶堆)即每个父节点都比孩子节点大,其实也是每次调整后确定一个最大值或最小值,但是他巧妙在,每次是拿出一个分支进行比较,当数据很大的时候,比较次数会明显减少,效率很高
代码:
func swap(a,b int)(int ,int){
temp:=a
a=b
b=temp
return a,b
}
func AdjustDown(nums []int,n int,root int){
parent:=root
child:=parent*2+1
for child<n{
if child+1<n && nums[child+1]>nums[child]{ //找出左右孩子节点中数值较大的节点
child++
}
if nums[child]>nums[parent]{
nums[child],nums[parent]=swap(nums[child],nums[parent])
parent=child
child=parent*2+1
}else{
break
}
}
}
func HeapSort(nums []int,n int) []int{
//调整堆
for i:=(n-2)/2;i>=0;i--{
AdjustDown(nums,n,i)
}
//排序
end:=n-1
for end>=0{
nums[0],nums[end]=swap(nums[0],nums[end])
AdjustDown(nums,end,0)
end--
}
return nums
}