快速排序法

快速排序法,一听名字就觉得这个排序方法效率很高。那么究竟什么是快速排序法呢?举个例子,现在有一个未排序的数组【5,12,3,1,7,8,4】,我们从中选择一个基准数,也可以理解为用来参照的数。
在这里插入图片描述

在这里我们可以将 i 和 j 想象为两个哨兵,确定了 i 和 j 的位置之后,

首先哨兵j往左边搜索,当它找到小于基准数的时候就停下来,

正好 j 所在的位置的数就比基准数 5 要小,那么 j 就不继续往左搜索了。

这个时候哨兵j就会告诉哨兵i:“嘿我找到了,该你了!”。

哨兵i听到后就开始行动,从左往右开始搜索,它的目标是寻找大于基准数的值。
在这里插入图片描述

然后i在索引为 2 的位置停了下来,这里的值是 12,

i 停下来后也告诉 j:“我也找到啦!”。

接下来哨兵 i 和哨兵 j 就会交换手中的目标,也就是12与4的位置进行交换。

完成交换后,哨兵 j 继续搜索它的目标,然后它找到了1。接下来轮到 i 开始搜索,可是 i 走着走着,就跟 j 碰在一起了。

这下可不好了,j在1那里停下来了,i也在1那里停下来了,他们互不相让,就快要打起来了。在经过一番谈论后,它们决定将责任推给1,j不要了,i也不要了,并且把象征着它们友谊的基准数5拿过来,和1交换。这样哨兵i和哨兵j就愉快的完成了这次搜索任务。
在这里插入图片描述

这个时候的数组为在这里插入图片描述,排序还没有完成,但是我们可以发现,在基准数5的左边,都是比它小的数,右边都是比他大的数。然后再分别对左右两边的数进行快速排序。

在这里插入图片描述

排序的最终结果就是这样了在这里插入图片描述

接下来要思考的就是,如何将快速排序用代码表示出来。先来看看我们需要的参数,首先是要进行排序操作的数组arr,然后就是基准数temp,最后还有两个哨兵 i 和 j。这里我以Java代码为例

public static void qsort(int arr[],int start,int end) {        
    int i = start; //声明i用来接收start的值       
    int j = end;   //声明j用来接收end的值
    int x,y;  //x和y用来存储arr[i]和arr[j]对应的值
    if(i>j){
    	//如果i>j了,说明哨兵i和哨兵j已经碰头,就跳出循环
    	//作为递归的结束条件
    	return;
    }
    // temp 用于存放基准数
    int temp = arr[start];  

在这里声明了哨兵 i 和哨兵 j ,他们的值就是数组的开始索引和结束索引。而后声明了 x 和 y,用来存放哨兵i和哨兵j搜索到的目标值。以 i > j 作为递归的结束条件。接下来就让两个哨兵开始搜索目标

	while(i<j){
    	//哨兵j的目标是大于基准数的值
    	//如果j所在位置的值小于基准数,则j--,继续往左搜索
    	while(temp<=arr[j]&&i<j){
    		j--;
    	}
    	
    	
    	//同理,哨兵i的目标是小于基准数的值
    	//如果j所在位置的值大于基准数,则i++,继续往右搜索
    	while(temp>=arr[i]&&i<j){
    		i++;
    	}
    	if(i<j){
    		//当i和j都找到目标时,进行交换
    		x=arr[i];
    		y=arr[j];
    		arr[i]=y;
    		arr[j]=x;
    	}
    }

这个时候循环结束,最后我们就需要将i和j共同占有的位置上的值与基准数进行交换

	    arr[start]=arr[i];
	    //或者是 arr[start]=arr[j];
	    arr[i]=temp;

我们得到了第一次排序的结果,接下来就是调用递归再次循环,但是传递的参数发生了改变
在这里插入图片描述

		//将基准数的左边进行快速排序
	    qsort(arr,start,j-1);
	    //将基准数的右边进行快速排序
	    qsort(arr, j+1, end);
	}    

在main方法中调用我们写好的方法,测试一下

public static void main(String[] args) {        
	int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
	qsort(arr, 0, arr.length-1);//调用递归
       for (int i = 0; i < arr.length; i++) {
       	//循环输出
           System.out.print(arr[i]+" ");
       }
}

输出结果为
在这里插入图片描述

快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准数,将小于基准数的放在左边,大于基准数的放在右边。这样每次循环就确定了一半的数,而不是像冒泡排序法那样只能在相邻的数之间两两相比。总的比较和交换次数就少了,速度自然就快了。

推荐参考 https://blog.csdn.net/u014241071/article/details/81565148
写的很好,图文并茂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值