分而治之(divide and conquer,D&C)
D&C算法是递归的,并且有2个步骤:
- 找出基线条件,并且条件尽可能简单
- 不断将问题分解,直到符合基线条件
给定一个数组,求和:
利用循环很容易,递归该如何做呢?
-
找基线条件:
-
缩小规模
func total(nums []int)int{
if len(nums)==0{
return 0
}else if len(nums)==1{
return nums[0]
}else{
return nums[0]+total(nums[1:])
}
}
快速排序
C语言标准库qsort中使用的就是快排,快排使用的就是D&C思想
- 数组为空或者只有一个元素时,根本不用排序,直接返回即可
- 选择一个基准值,以数组第一个元素为例,找出比基准值大和小的元素
- 对左右两边的子数组快速排序,然后合并就是排序好的数组
func GetNewArr(target int,nums []int,greater bool)[]int{
length:=len(nums)
result:=make([]int,0,length)
if greater{
// 大
for i:=0;i<length;i++{
if nums[i]>target{
result=append(result,nums[i])
}
}
}else{
// 小
for i:=0;i<length;i++{
if nums[i]<=target{
result = append(result,nums[i])
}
}
}
return result
}
func Join(args...[]int)[]int{
if len(args)==0{
return []int{}
}else{
result:=make([]int,0,len(args[0]))
for _,val:=range args{
result=append(result,val...)
}
return result
}
}
func quickSort(nums []int)[]int{
if len(nums)==0 || len(nums)==1{
return nums
}else{
target:=nums[0]
less:= GetNewArr(target,nums[1:],false)
greater:= GetNewArr(target,nums[1:],true)
return Join(quickSort(less),[]int{target},quickSort(greater))
}
}
平均情况和最糟情况
快排的性能高度依赖基准值,在最坏情况下快排的时间复杂度为O(n**2),而平均情况下快排的时间复杂度为O(n*logn)
- 最坏情况,栈长为n
2. 最佳情况,栈长为logn
不管哪种情况,调用栈每层都需要遍历每一个元素,从而找到大于基准值和小于基准值的数组,所以为O(n)
func GetNewArr(target int,nums []int,greater bool)[]int{
length:=len(nums)
result:=make([]int,0,length)
if greater{
// 大
for i:=0;i<length;i++{
if nums[i]>target{
result=append(result,nums[i])
}
}
}else{
// 小
for i:=0;i<length;i++{
if nums[i]<=target{
result = append(result,nums[i])
}
}
}
return result
}
func Join(args...[]int)[]int{
if len(args)==0{
return []int{}
}else{
result:=make([]int,0,len(args[0]))
for _,val:=range args{
result=append(result,val...)
}
return result
}
}
func quickSort(nums []int)[]int{
if len(nums)==0 || len(nums)==1{
return nums
}else{
index:=rand.Intn(len(nums))
target:=nums[index]
nums = append(nums[:index],nums[index+1:]...)
less:= GetNewArr(target,nums,false)
greater:= GetNewArr(target,nums,true)
return Join(quickSort(less),[]int{target},quickSort(greater))
}
}