快速排序----以第一个元素作为基准值

快速排序的算法思想在大二学习数据结构的时候就有了解,只是一直都不能做到熟练地代码实现,最近一段时间在看基础的排序、查找算法,下面进行总结:

代码思想

1、基本思想是:通过一趟排序将待排元素(一般选择数组存放)分隔成独立的三部分:“中间值”、小于“中间值”的部分、大于“中间值”的部分。之后,分别对小于“中间值”的部分、大于“中间值”的部分,进行相同的排序,直至最终所有的待排序元素都变得有序为止。
2、用到的算法思想:递归
3、实现原理:(大致思路,具体实现时可能略有差异)
[1]循环体内的部分(排序时进行的操作):
(1)在每一次排序时,选择“一个‘中间值’(base),两个指针”:每次进行排序的时候,选择一个数作为排序的参照值base(通常选择目前待排序列的第一个元素);确定两个指针------一个指针 low (指向待排序列的第一个元素),一个指针 high (指向待排序列的最后一个元素)。
(2)让 low 指针在待排序列中从前往后遍历,直至遍历到第一个比 base 值大的元素为止;让 high 指针指向待排序列的最后一个元素,让 high 指针从后向前遍历,直至遍历到第一个比 base 小的元素为止。
(3)如果此时满足: high > low,则交换 high 与 low 位置上对应的元素,直至出现 high < low,结束此次的循环。
[2]循环体外:
(4)结束循环之后,将此时的 base 与 high 交换对应位置上的元素,并将它定为 middle 。
(因为循环结束的时候,实际上也是找到了:low比 base 值大,high比 base 小,所以此时将 base 与 high 指向的元素互换,才可以保证:middle 左侧的元素都小于等于 middle,middle右侧的元素都大于等于 base )。
(5)之后,调用该函数本身,对middle左侧、右侧的元素序列进行排序(就是递归的过程)。
注意的是:此时middle的位置已经确定了,不需要再挪动,所以不需要再参与排序。

代码实现
import java.util.Arrays;

public class QuickSort {

	/*
	 * 交换数组元素值的方法
	 */
	private static void swap(int[] data,int i,int j) {
		int temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}
	
	/*
	 * 快排的核心方法------递归的部分
	 */
	private static void subSort(int[] data,int start,int end) {
		/*
		 * 这里的条件是递归的 终止条件
		 */
		if(start < end ) {
			/*
			 * 这里以序列的 第一个元素作为每次排序的基准
			 */
			int base = data[start];
			/*
			 * 让low指针指向当前序列的第一个元素
			 * high指针指向当前序列的最后一个元素+1(最后一个元素后边的位置)
			 * ------
			 * 其实,high应该指向当前序列的最后一个元素,
			 * 但是因为考虑到下边的while循环中,每次从后往前遍历的时候,都是先将high指针自减1,然后才进行判断,
			 * 所以应该在每次 刚进循环的时候将high的值置为:序列的最后一个元素后边的位置
			 * 
			 */
			int low = start;
			int high = end+1;
			
			/*
			 * 应该注意的是:在每次查找符合要求的下标值low、high的过程中
			 * 除了应该保证,low对应的值 > base,high对应的值 < base之外,
			 * 还应该保证  索引下标“不越界”
			 * ------“不越界”指的是不越 当前正在进行排序的 序列的下标 对应的范围
			 */
			while(true) {
				/*
				 * 每次查找的时候,
				 * 让 low 指针在待排序列中从当前low 指针对应的索引值开始,从前往后遍历,
				 * 在这个过程中需要保证 下标不越界--------low < end,
				 * ----即,low指针对应的索引值,最大 也应该小于当前排序序列的最后一个元素对应的索引值,
				 * --这是因为,即使:序列中的最后一个元素的值 大于当前的base值(所选取的基准元素),也不用进行swap()操作
				 * 直至遍历到第一个比 base 值大的元素为止
				 */
				while(low < end && data[++low] - base <= 0);
				/*
				 * 每次查找的时候,
				 * 让 high 指针在待排序列中从当前high 指针对应的索引值开始,从后往前遍历,
				 * 在这个过程中需要保证 下标不越界----------high > start,
				 * ----即,high 指针对应的索引值,最小 也应该大于当前排序序列的最前边一个元素对应的索引值,
				 * --这是因为,所选取的base值(所选取的基准元素),即为当前序列
				 * 直至遍历到第一个比 base 值大的元素为止
				 */
				while(high > start && data[--high] - base >= 0);
				
				if(low < high) {
					/*
					 * 当找出来的符合要求的元素 对应的索引值
					 * 满足:没有出现交叉重叠
					 * 交换low、high 上对应的元素 
					 */
					swap (data,low,high);
				}else {
					/*
					 * 进行到当前这一步的时候,有一个前提就是:
					 * 此时 找出来的符合要求的元素 对应的下标值,已经出现了交叉重叠
					 * 所以------表明当前序列的排序已经进行完毕
					 * ----------->跳出外层的while循环
					 */
					break;
				}
			}
			/*
			 * 交换当前的基准元素(base) 与 退出外层while循环时,
			 * high指针 对应的元素(middle)
			 * -------
			 * 实现“中值归位”
			 * -------
			 * 为进一步的递归序列的划分提供依据
			 */
			swap(data,start,high);
			/*
			 * 对于middle(刚刚确定了 最终位置的“中值”)左边的序列进行递归排序
			 */
			subSort(data,start,high-1);
			/*
			 * 对于middle(刚刚确定了 最终位置的“中值”)右边的序列进行递归排序
			 */
			subSort(data,high+1,end);
		}
	}
	
	public static void quickSort(int[] data) {
		/*
		 * 第一次调用排序
		 * (快速排序算法的启动)
		 */
		subSort(data,0,data.length-1);
	}
	
	public static void main(String[] args) {
		
		int[] data = new int[]{9,-36,30,23,-30,-49,25,21,30};
		System.out.println("输出排序之前的数组:\n" + Arrays.toString(data));
		quickSort(data);
		System.out.println("排序之后的数组:\n"+Arrays.toString(data));	
	}
}




代码总结

快速排序的
平均时间复杂度为:O(nlogn)
最坏时间复杂度:O(n^2)

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值