快速排序算法在Java中的实现

快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。

一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。

接着分别比较左右两边的序列,重复上述的循环。

public class FastSort{
	public static void main(String []args){
		System.out.println("Hello World");
		int[] a = {12,20,5,16,15,1,30,45,23,9};
		int start = 0;
		int end = a.length-1;
		sort(a,start,end);
		for (int i = 0; i<a.length; i++){
			System.out.println(a[i]);
		}
	}
	public void sort(int[] a,int low,int high){
		int start = low;
		int end = high;
		int key = a[low];
		while(end>start){
			//从后往前比较
			while(end>start&&a[end]>=key) //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
			end--;
			if(a[end]<=key){
				int temp = a[end];
				a[end] = a[start];
				a[start] = temp;
			}
			//从前往后比较
			while(end>start&&a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
			start++;
			if(a[start]>=key){
				int temp = a[start];
				a[start] = a[end];
				a[end] = temp;
			}
			//此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
		}
		//递归
		if(start>low) sort(a,low,start-1);
		//左边序列。第一个索引位置到关键值索引-1
		if(end<high) sort(a,end+1,high);
		//右边序列。从关键值索引+1到最后一个
	}
}

上面最后一句不是基准值的意思是,不是直接用基准值交换,是用基准值所在的索引交换。

下面我们看看另一种实现方式。

一趟快速排序的过程如下

(1)先从序列中选取一个数作为基准数

(2)将比这个数大的数全部放到它的右边,把小于或者等于它的数全部放到它的左边

一趟快速排序也叫做Partion,即将序列划分为两部分,一部分比基准数小,另一部分比基准数大,然后

再进行分治过程,因为每一次Partion不一定都能保证划分得很均匀,所以最坏情况下的时间复杂度不能

保证总是为

对于Partion过程,通常有两种方法

(1)两个指针从首尾向中间扫描(双向扫描)

这种方法可以用挖坑填数来形容,比如

初始化:i=0;j=9;pivot=a[0];

现在a[0]保存到了变量pivot中了,相当于在数组a[0]处挖了个坑,那么可以将其它的数填到这里来。从j开始向前找一个小于或者等于pivot的数,即将a[8]填入a[0],但a[8]又形成了一个新坑,再从i开始向后找一个大于pivot的数,即a[3]填入a[8],那么a[3]又形成了一个新坑......

就这样,直到i==j才停止,最终得到结果如下

上述过程就是一趟快速排序。

/**
 * 功能描述: 快速排序,双向扫描
 *
 * @date 2017-09-12 10:17
 * @since V1.0.0
 */
public class QuickSort {
	public static void main(String[] args){
		Integer[] arr = {8, 2, 9, 1, 5, 10, 12, 3, 18, 6};
		System.out.println(Arrays.asList(arr));
		quickSort(arr, 0, arr.length - 1);
		System.out.println(Arrays.asList(arr));
	}
	public static void quickSort(Integer[] arr, int left, int right) {
		if(left < right) {
			int partition = partition(arr, left, right);
			quickSort(arr, left, partition - 1);
			quickSort(arr, partition + 1, right);
		}
	}
	public static int partition(Integer[] arr, int left, int right) {
		Integer pivot = arr[left];
		int i = left, j = right;
		while (i < j) {
			while (arr[j] >= pivot && i < j) {
				j--;
			}
			arr[i] = arr[j];
			while (arr[i] <= pivot && i < j) {
				i++;
			}
			arr[j] = arr[i];
		}
		arr[i] = pivot;
		return i;
	}
}

总结

以上就是本文关于快速排序算法在Java中的实现的全部内容,希望对大家有所帮助。如有不足之处,欢迎留言指出。

(0)

相关推荐

  • Java编程实现直接插入排序代码示例

    算法描述:对于给定的一个数组,初始时假设第一个记录自成一个有序序列,其余记录为无序序列.接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直至最后一个记录插入到有序序列中为止. 直接插入排序Java实现教程 示例1 public class Insert { public static void main(String[] args) { int a[] = {9,3,28,6,34,7,10,27,1,5,8}; show(a); for (int i=1;i

  • Java 堆排序实例(大顶堆、小顶堆)

    堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法.堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点. 堆排序的平均时间复杂度为Ο(nlogn) . 算法步骤: 1. 创建一个堆H[0..n-1] 2. 把堆首(最大值)和堆尾互换 3. 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置 4. 重复步骤2,直到堆的尺寸为1 堆: 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:

  • Java分治归并排序算法实例详解

    本文实例讲述了Java分治归并排序算法.分享给大家供大家参考,具体如下: 1.分治法 许多有用的算法在结构上是递归的:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关的若干子问题.这些算法典型地遵循分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 分治模式在每层递归时都有三个步骤: (1)分解原问题为若干子问题,这些子问题是原问题的规模较小的实例. (2)解决这些子问题,递归地求解各子问题.然而,

  • Java语言实现基数排序代码分享

    算法思想:依次按个位.十位...来排序,每一个pos都有分配过程和收集过程,array[i][0]记录第i行数据的个数. package sorting; /** * 基数排序 * 平均O(d(n+r)),最好O(d(n+r)),最坏O(d(n+r));空间复杂度O(n+r);稳定;较复杂 * d为位数,r为分配后链表的个数 * @author zeng * */ public class RadixSort { //pos=1表示个位,pos=2表示十位 public static int g

  • 基数排序简介及Java语言实现

    基本思想 基数排序(RadixSort)是在桶排序的基础上发展而来的,两种排序都是分配排序的高级实现.分配排序(DistributiveSort)的基本思想:排序过程无须比较关键字,而是通过"分配"和"收集"过程来实现排序.它们的时间复杂度可达到线性阶:O(n). 基数排序是一种稳定的排序算法,但有一定的局限性: 1.关键字可分解. 2.记录的关键字位数较少,如果密集更好 3.如果是数字时,最好是无符号的,否则将增加相应的映射复杂度,可先将其正负分开排序. 先来看一

  • Java实现按照大小写字母顺序排序的方法

    本文实例讲述了Java实现按照大小写字母顺序排序的方法.分享给大家供大家参考,具体如下: 这里排序需要得到的结果按字母顺序.如:a-----z... import java.util.*; /** * 大小写字母的排序 * @author Administrator * */ public class z { //上边是按大写在后的进行排序 static Map<Character,Float> map=new HashMap<Character,Float>();//hashMa

  • Java编程实现快速排序及优化代码详解

    普通快速排序 找一个基准值base,然后一趟排序后让base左边的数都小于base,base右边的数都大于等于base.再分为两个子数组的排序.如此递归下去. public class QuickSort { public static <T extends Comparable<? super T>> void sort(T[] arr) { sort(arr, 0, arr.length - 1); } public static <T extends Comparabl

  • 堆排序实例(Java数组实现)

    堆排序:利用大根堆 数组全部入堆,再出堆从后向前插入回数组中,数组就从小到大有序了. public class MaxHeap<T extends Comparable<? super T>> { private T[] data; private int size; private int capacity; public MaxHeap(int capacity) { this.data = (T[]) new Comparable[capacity + 1]; size =

  • 快速排序算法在Java中的实现

    快速排序的原理:选择一个关键值作为基准值.比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的).一般选择序列的第一个元素. 一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换.找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换.直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两

  • 详解Java中使用泛型实现快速排序算法的方法

    快速排序算法概念 快速排序一般基于递归实现.其思路是这样的: 1.选定一个合适的值(理想情况中值最好,但实现中一般使用数组第一个值),称为"枢轴"(pivot). 2.基于这个值,将数组分为两部分,较小的分在左边,较大的分在右边. 3.可以肯定,如此一轮下来,这个枢轴的位置一定在最终位置上. 4.对两个子数组分别重复上述过程,直到每个数组只有一个元素. 5.排序完成. 基本实现方式: public static void quickSort(int[] arr){ qsort(arr,

  • 浅析java快速排序算法

    快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置.递归快速排序,将其他n-1个元素也调整到排序后的正确位置.最后每个元素都是在排序后的正 确位置,排序完成.所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归. 一趟快速排序的算法是: 1)设置两个变量i.j,排序开始的时候:i=0,j=N-1: 2)

  • Java基于分治法实现的快速排序算法示例

    本文实例讲述了Java基于分治法实现的快速排序算法.分享给大家供大家参考,具体如下: package cn.nwsuaf.quick; /** * 随机产生20个数,并对其进行快速排序 * * @author 刘永浪 * */ public class Quick { /** * 交换函数,实现数组中两个数的交换操作 * * @param array * 待操作数组 * @param i * 交换数组的第一个下标 * @param j * 交换数组的第二个下标 */ public static

  • Java实现快速排序算法的完整示例

    首先,来看一下,快速排序的实现的动态图: 快速排序介绍: 快速排序,根据教科书说法来看,是冒泡排序的一种改进. 快速排序,由一个待排序的数组(array),以及找准三个变量: 中枢值(pivot) 左值(left) 右值(right) 根据中枢值(pivot)来做调整,将数组(array)分为三个部分: 第一部分:中枢值(pivot),单独数字构成,这个值在每次排序好的"最中间": 第二部分:左边数组(由array的一部分组成),这个数组在第一部分 中枢值(pivot) 的"

  • 详解Java双轴快速排序算法

    目录 一.前言 二.回顾单轴快排 三.双轴快排分析 3.1.总体情况分析 3.2.k交换过程 3.3.收尾工作 四.双轴快排代码 一.前言 首选,双轴快排也是一种快排的优化方案,在JDK的Arrays.sort()中被主要使用.所以,掌握快排已经不能够满足我们的需求,我们还要学会双轴快排的原理和实现才行. 二.回顾单轴快排 单轴快排也就是我们常说的普通快速排序,对于快速排序我想大家应该都很熟悉:基于递归和分治的,时间复杂度最坏而O(n2),最好和平均情况为O(nlogn). 而快排的具体思路也很

  • java中几种常见的排序算法总结

    目录 本节目标: [插入排序] [优化版] [希尔排序] [选择排序] [堆排序]  [冒泡排序] 介绍一个冒泡排序的优化方法:  [快速排序] [归并排序] [正文] [代码简介:]  [排序总结] 本节目标: :分析常见的比较排序算法基本原理及实现 :分析排序算法的性能分析 :分析Java中常用排序方法 1 排序 排序,就是使一串记录,按照其中某个或某些关键字的大小,递增或递减排列的操作. 平时的上下文中,提到排序 通常指排升序. 2 稳定性 两个相同的数据,如果经过排序后,排序算法能保证其

  • Java中七种排序算法总结分析

    目录 前言:对文章出现的一些名词进行解释 一.插入排序 1.基本思想 2.直接插入排序 3.希尔排序(缩小增量排序) 二.选择排序 1.基本思想 2.直接选择排序 3.堆排序 三.交换排序 1.基本思想 2.冒泡排序 3.快速排序(递归与非递归) 1.Hoare版 2.挖坑法 3.前后标记法(难理解) 4.快速排序优化 5.快速排序非递归 6.相关特性总结 四.归并排序(递归与非递归) 前言:对文章出现的一些名词进行解释 排序: 使一串记录,按照其中的某个或某些关键字的大小,递增或者递减排列起来

  • Java实现快速排序算法(Quicktsort)

    快速排序算法介绍快速排序和归并排序都使用分治法来设计算法,区别在于归并排序把数组分为两个基本等长的子数组,分别排好序之后还要进行归并(Merge)操作,而快速排序拆分子数组的时候显得更有艺术,取一个基准元素,拆分之后基准元素左边的元素都比基准元素小,右边的元素都不小于基准元素,这样只需要分别对两个子数组排序即可,不再像归并排序一样需要归并操作.基准元素的选取对算法的效率影响很大,最好的情况是两个子数组大小基本相当.为简单起见,我们选择最后一个元素,更高级的做法可以先找一个中位数并把中位数与最后一

  • java 中模式匹配算法-KMP算法实例详解

    java 中模式匹配算法-KMP算法实例详解 朴素模式匹配算法的最大问题就是太低效了.于是三位前辈发表了一种KMP算法,其中三个字母分别是这三个人名的首字母大写. 简单的说,KMP算法的对于主串的当前位置不回溯.也就是说,如果主串某次比较时,当前下标为i,i之前的字符和子串对应的字符匹配,那么不要再像朴素算法那样将主串的下标回溯,比如主串为"abcababcabcabcabcabc",子串为"abcabx".第一次匹配的时候,主串1,2,3,4,5字符都和子串相应的

随机推荐