快速排序


基本思想

快排是对冒泡排序的一种改进,是C.R.A.Hoare于1962年提出的一种划分交换排序,采用了分治的策略,通常称为分治法
基本思想:
1、选取一个值为基准值point
2、将小于或等于point的值放于左边
3、将大于point的值放于右边
4、分别对左右子序列重复前三个步骤,直到各子序列只有一个数

在这里插入图片描述
上述图实例为快速的第一轮过程,显然是挖坑填数+分治法来实现整个快速排序过程,以序列为一数组,以i=0指向数组第一个数字,以j=5来指向数组最后一个数字,进行快排。
第一次取下标为0的数作为基准值:18

012345
1898101627

开始时,i=0,j=5,temp=num[i]=18
此时已经将num[0]的值保存到temp中,可理解为将num[0]这里挖坑,可以将其他数据填充到这里。从j=5开始向前寻找小于或等于temp的数字,j=5时,7<18,符合条件,将num[5]的值挖出填入坑num[0]中,即num[0]=num[5];i++;填完坑之后,又出现了新坑num[5],则需要再一次找数字来填这个坑,这次从i开始向后找大于temp的数字,当i=1时,即num[1]=98大于temp,符合条件,挖出num[1]的值填入坑num[5]中,即num[5]=num[1];j++;这样又出现了新坑num[1]…以此类推,当j等于i时,将基准值赋给num[i],分别对num[i]左右子序列递归调用快排方法,递归的结束条件为各子序列只有一个数字


代码实现

1、以上思想中挖坑填数+分治法结合,Java实现如下

public void quick_sort(int num[], int l, int r)
{
    if (l < r)
    {
        int i = l, j = r, temp = num[l];
        while (i < j)
        {
            // 从右向左找第一个小于或等于x的数来填坑num[i]
            while(i < j && num[j] > temp) 
                j--;  
            if(i < j) 
                num[i++] = num[j];  //将num[j]填到num[i]中,num[j]形成新坑
                
            // 从左向后找第一个大于x的数
            while(i < j && num[i] <= temp) 
                i++;  
            if(i < j) 
                num[j--] = num[i]; //将num[i]填到num[j]中,num[i]形成新坑
        }
        num[i] = temp;
        quick_sort(s, l, i - 1); // 左边子序列递归调用 
        quick_sort(s, i + 1, r); //右边子序列递归调用
    }
}

2、Golang的快排结合切片实现(用填坑法+分治Go重写1的Java代码超出时间限制)
注:continue语句执行是跳过本次循环(不管后面未执行的语句)继续下一次循环

func quick_sort(nums []int){
    i , j := 0 , len(nums) - 1
    for i < j {
        if nums[j] > nums[0] {
            j--
            continue
        }
        if nums[i] <= nums[0] {
            i++
            continue
        }
        nums[i],nums[j] = nums[j] ,nums[i]
    }
    nums[0],nums[i] = nums[i],nums[0]
    if len(nums[:j]) > 1 {
        sortArray(nums[:j]) //左边子序列递归调用
    }
    if len(nums[j+1:]) >1 {
        sortArray(nums[j+1:]) //右边子序列递归调用
    }
}

3、Golang slice方法,很好体现出分治思想

func sortArray(nums []int) []int {
    if len(nums) <= 1 {
		return  nums
	}
    //nums[0]作为基准值
	key := nums[0]
	var left, right []int
	for _, e := range nums[1:] {
		if e <= key {
			left = append(left, e)
		} else {
			right = append(right, e)
		}
	}
	return  append(append(sortArray(left), key), sortArray(right)...)
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值