快速排序

前言

     最近补了补数据结构和算法,想写几篇,一是为了总结,二是为了能和大家交流交流。毕竟算法是内功,不管是对于自我提升还是面试都是有帮助的。 同时也希望能起到抛砖引玉的作用,欢迎大佬们多多指教。-_-

    

☆☆☆ 算法目录导航页,包含基础算法、高级算法、机器学习算法等☆☆☆

    

1.快速排序

快速排序是一种基于交换的排序方式,整个排序过程围绕三点进行:
    1.两个指针left和right。分别指向数组第一个和最后一个数字。
    2.选中一个key作为参照。key值在【一次】排序过程中是【不变】的。
    3.比较交换。每一步都和key去比较。如果left指向的数字比key大,则交换left和right对应的数字。同理,right指向的数字比key小,则交换。否则,移动left和right向数组中间靠拢。

2.一次排序过程完整图解

    首先,选中key = 5,左指针left指向的数字先进行比较,right不变。若arr[left] < 5,left++;否则,交换左右指针对应的数字。交换完成后,则left指针不变,right指针开始移动。每次交换过后互换指针移动。
    上面写的如果看着晕,建议先看下图解,然后跑一跑代码。

在这里插入图片描述

3.代码示例Java版本

/**
 * 
 * @author wxq
 *
 */
public class SortMy {
	/**
	 * 测试
	 * @param args
	 */
	public static void main(String[] args) {
		int [] arr = new int [] {1,8,6,4,2,3,5};
		quickSort1(arr, 0, arr.length-1);
		System.out.println(Arrays.toString(arr));
	}

	/**
	 * 一次排序过程
	 * @param arr
	 * @param left
	 * @param right
	 * @return
	 */
	static int oneSort(int [] arr , int left ,int right ){
		//选择最后一个元素为key
		int key = arr[right];
//		System.out.println("key="+key);
		
		//开始排序
		while (left < right) {
			//从左往右开始比较,右指针不变
			while(left < right && arr[left] <= key){
				left++;
			}
			//左边数小于key,交换
			swap(arr,left,right);
			//从右往左开始比较,左指针不变
			while(left < right && arr[right] >= key){
				right--;
			}
			//右边数小于key,交换
			swap(arr,left,right);
		}
		
		//left 和 right相遇
		return left;
	}
	
	/**
	 * 递归实现
	 * @param arr
	 * @param left
	 * @param right
	 */
	static void quickSort1(int[] arr,int left ,int right){
		//参数校验
		if(arr.length < 1 || left < 0 || right < 0) return;
		
		if(left < right){
			int index = oneSort(arr, left, right);
			quickSort1(arr,left,index - 1); //左子序列 快速排序	
			quickSort1(arr,index + 1,right);//右子序列 快速排序
		}
	}
	
	/**
	 * 交换
	 * @param arr
	 * @param a
	 * @param b
	 */
	static void swap(int[] arr, int a, int b) {
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
}

4.非递归实现

     递归的本质是栈,所以我们用栈来实现快排。
/**
	 * 非递归实现
	 * @param arr
	 * @param left
	 * @param right
	 */
	static void quickSort2(int[] arr,int left ,int right){
		Stack<Integer> s = new Stack<>();
		s.push(left);
		s.push(right);
		
		//终止条件
		while(!s.empty()){
			right = s.pop();
			left = s.pop();
			
			//一次排序后左右指针相遇点
			int index = oneSort(arr, left, right);
			//左子序列 快速排序
			if(left < (index-1)){
				s.push(left);
				s.push(index-1);
			}
			//右子序列 快速排序
			if((index+1) < right){
				s.push(index+1);
				s.push(right);
			}
		}
	}

总结:

     本文讲了快速排序,以及递归和非递归实现。时间复杂度O(nlog2n),空间复杂度为O(nlog2n),不稳定,当数据为随机分布时平均效率为排序中最高。主要描述的是算法思想,需要注意的是3个关键点的理解和实际代码中方法的抽取。网上也有很多版本以及优化,有兴趣的可以自己搜一搜。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值