分而治之(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))
	}
}


















