【图解排序】快速排序(Java)

前言

唠叨一下:半夜实在睡不着,起床敲了一个 快速排序 的代码,讲真这是大学第一次亲手敲出这个代码,代码使用Java实现,但算法和数据结构一样,其本身和编程语言是没有关系的。

简单介绍

算法思想

基于分治的思想,是 冒泡排序 的改进型。

1.首先在数组中选择一个基准点
(该基准点的选取可能影响快速排序的效率,后面讲解选取的方法);

2.然后分别从数组的两端扫描数组,设两个指示标志
low 指向起始位置,high 指向末尾);

3.首先从后半部分开始,如果发现有元素比该基准点的值小,就交换lowhigh位置的值,然后从前半部分开始搜索,发现有元素大于基准点的值,就交换lowhigh位置的值,如此往复循环,直到 low>=high,然后把基准点的值放到high这个位置。

一次排序就完成了。

以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。


在这里插入图片描述

算法特点

快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较;

最坏情况
每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n2)

最好情况
每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlogn)
尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlogn)

源码

package nono.sort;

import java.util.Arrays;

/**
 * 快速排序
 * 
 * @author Nonoas
 */
public class QuikSorter {
	/**
	 * 快速排序
	 * 
	 * @param arry 进行排序的数组
	 * @param low  数组的起始下标
	 * @param high 数组的终止下标
	 */
	public static void quikSort(int[] arry, int low, int high) {
		if (low >= high)
			return; // 递归出口,当起始下标大于等于终止下标时,结束排序
		int temp = arry[low]; // 临时变量用于保存参考元素的值
		int left = low; // 左端指针
		int rigth = high; // 右端指针

		while (left < rigth) {// 当左标小于右标时执行循环
			while (left < rigth && arry[rigth] > temp)
				rigth--; // 从后往前搜索小于中间值的数
			if (left < rigth)
				arry[left++] = arry[rigth]; // 将小于中间值的数移到左边,这里不用交换值,直接覆盖即可
			while (left < rigth && arry[left] < temp)
				left++; // 从前往后搜索大于中间值的数
			if (left < rigth)
				arry[rigth--] = arry[left]; // 将大于中间值的数移到右边,这里不用交换值,直接覆盖即可
		}
		// 循环体结束,说明左标与右标相遇
		arry[left] = temp;// 将参考值赋给当前位置的数,此时左边的数都小于temp,右边的数都大于temp
		
		quikSort(arry, low, left - 1);// 递归排序左部
		quikSort(arry, rigth + 1, high);// 递归排序右部
	}

	public static void main(String[] args) {
		int[] a = { 8, 7, 6, 3, 5, 4 };
		System.out.println("排序前:" + Arrays.toString(a));
		QuikSorter.quikSort(a, 0, a.length - 1);
		System.out.println("排序后:" + Arrays.toString(a));
	}
}

运行结果

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章