排序算法java快速排序_快速排序算法--Java实现
标签(空格分隔): 数据结构与算法
原理:
对于任意一个无序数组,我们随机的选一个元素作为基准元素(例如:数组中的最后一个或者第一个元素, 然后我们将数组中的剩余元素分别与基准元素进行比较,将小于或等于基准元素的数据放在基准元素的左边,将大于基准元素的数据放在基准元素的右边,当全部比较完成之后,基准元素在数组中的位置就确定了下来。然后,在分别对左边数组和右边的数组递归的进行上面的操作,直到每一个元素的位置都唯一确定下来。
例如:我们对下面的数组进行快速排序
[ 8 2 1 7 3 5 9 6 ]
算法步骤分析:
1.选取数组中的最后一个元素6最为基准元素
2.遍历剩下所有数据8 2 1 7 3 5 9
我们使用一个变量n,记录小于基准元素的个数,比较前,我们假设所有的元素都大于或等于基准元素,即所有元素都被认为是大于基准元素的. n = start =0------------ n=0;
过程分析
8 和 6比较,8大于基准元素,不做任何变化
8 2 1 7 3 5 9 ----------- n=0;
2和6比较,2比6小. 我们应该将这个元素放到基准元素的左边,怎么做呢,我们将这个元素和大于基准的第一个元素交换一下就行了,然后将n加1.
2 8 1 7 3 5 9 ------------ n=1;
1和6比较,1比6小 ,交换1和8的位置,n加1.
2 1 8 7 3 5 9 ------------- n=2;
7和6比较,7比6大,不做任何变化
2 1 8 7 3 5 9 ------------- n=2;
3和6比较,3比6小,交换8和3的位置,n加1
2 1 3 7 8 5 9-------------- n=3;
5和6比较,5比6小,交换5和7的位置,n加1.
2 1 3 5 8 7 9-------------- n=4;
9和6比较,9比6小,不做任何变化
2 1 3 5 8 7 9-------------- n=4;
最终结果:表明小于或等于6的元素共有4个
2 1 3 5 8 7 9 6 ----------- n=4;
也就是说,6这个基准元素应该放到原数组中下标索引为4的位置上(数组从0开始下表).
即它可能应该类似这样的存放:
[ 2 1 3 5 6 8 7 9 ]
但是如何实现这样的操作呢?
事实上只要将6这个元素与此时数组[ 2 1 3 5 8 7 9 6 ]中的第4个元素8的交换位置即可.
结果如下:
[ 2 1 3 5 ] 6 [ 7 9 8 ]
这样我们就区分出了两个数组,比 6 小的[ 2 1 3 5 ]和不小于6的[ 7 9 8 ],当然这个两个数组的顺序不一定是正确的,但是基准元素所在的位置一定是正确的,然后我们在分别对左右两数组做同样的操作,依次类推下去,最后确定每一个元素所在的位置,这样整个数组就完成了排序。
/**
* 拆分数组
* @param arr 要拆分的数组
* @param start 数组拆分的起始索引 (从0开始)
* @param end 数组拆分的结束索引
*/
public static int partArr(int[] arr, int start, int end) {
//选取基准元素,这里我们以最后一个位置,作为基准
int base = arr[end];
//记录,比基准元素小的变量,这里我们假设要比较的元素都不小于基准元素,这样通过比较
//就把小于基准元素的数据全部找到,n=start表示的就是默认没有小于基准元素。
int n = start;
//基准元素不参与遍历比较
for (int i = start; i < end; i++) {
if (arr[i] < base) {
//将小于基准元素的放到基准的左边
if (i != n)
exchangeE(arr, i, n);
n++;
}
}
//遍历完成之后,将基准元素放到应该的位置上
exchangeE(arr, n, end);
return n;
}
/**
* 交换数组中指定位置的两个元素
*
* @param array
* @param index1
* @param index2
*/
public static void exchangeE(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
根据拆分的结果,进行在拆分,由于原理一样,因此我们使用递归调用的思想
public static void recurPartiton(int[] arr,int start,int end){
//递归调用的结束条件,开始要拆分的数组就剩下一个元素的时候
if(end-start<1)
return;
int part = partArr(arr, start, end);
//三种情况下的继续拆分
if(part==start)
recurPartiton(arr,part+1,end);
else if(part ==end)
recurPartiton(arr,start,end-1);
else{
recurPartiton(arr,start,part-1);
recurPartiton(arr,part+1,end);
}
}
最后封装测试:
public static void main(String[] args) {
int[] arr = {8, 2, 1, 4,6,7, 3, 5, 9, 6,11,19,13,55,67,32,22};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr){
recurPartiton(arr,0,arr.length-1);
}
完整代码测试案例
package com.sivin.test;
import java.util.Arrays;
public class main {
/**
* 拆分数组
* @param arr 要拆分的数组
* @param start 数组拆分的起始索引 (从0开始)
* @param end 数组拆分的结束索引
*/
public static int partArr(int[] arr, int start, int end) {
//选取基准元素,这里我们以最后一个位置,作为基准
int base = arr[end];
//记录,比基准元素小的变量,这里我们假设要比较的元素都不小于基准元素,这样通过比较
//就把小于基准元素的数据全部找到,n=start表示的就是默认没有小于基准元素。
int n = start;
//基准元素不参与遍历比较
for (int i = start; i < end; i++) {
if (arr[i] < base) {
//将小于基准元素的放到基准的左边
if (i != n)
exchangeE(arr, i, n);
n++;
}
}
//遍历完成之后,将基准元素放到应该的位置上
exchangeE(arr, n, end);
return n;
}
/**
* 交换数组中指定位置的两个元素
*
* @param array
* @param index1
* @param index2
*/
public static void exchangeE(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
public static void recurPartiton(int[] arr,int start,int end){
//递归调用的结束条件,开始要拆分的数组就剩下一个元素的时候
if(end-start<1)
return;
int part = partArr(arr, start, end);
//三种情况下的继续拆分
if(part==start)
recurPartiton(arr,part+1,end);
else if(part ==end)
recurPartiton(arr,start,end-1);
else{
recurPartiton(arr,start,part-1);
recurPartiton(arr,part+1,end);
}
}
public static void main(String[] args) {
int[] arr = {9,8,7,3,4,1,2,3};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr){
recurPartiton(arr,0,arr.length-1);
}
}
测试结果如下:
测试结果1.png
测试结果2.png
排序算法java快速排序_快速排序算法--Java实现相关推荐
- java贪心算法 区间调度_贪心算法-区间调度问题解之证明(示例代码)
一.贪心算法 定义:一个算法是贪心算法,如果它是通过一些小的步骤来一个求解,并且在每一步根据局部情况选择一个决定,使得某些主要的指标得到优化. 二.区间调度问题 1. 问题:我们有一组需求{1,2,3 ...
- 匈牙利算法java实现_匈牙利算法(Hungarian Algorithm)
匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法.换句话说就是,在可以接受的时间内去做匹配. 1. 描述问题 给定2个集合A和B,然后将AB中的元素完成一个连线.(这不就是小时候的连线题么 ...
- l bfgs算法java代码_优化算法——拟牛顿法之L-BFGS算法
一.BFGS算法 BFGS算法的校正公式: 利用Sherman-Morrison公式可对上式进行变换,得到 令 ,则得到: 二.BGFS算法存在的问题 在BFGS算法中.每次都要存储近似Hesse矩阵 ...
- java 排序算法面试题_面试题: java中常见的排序算法的实现及比较
1.冒泡排序 1.1 冒泡排序普通版 每次冒泡过程都是从数列的第一个元素开始,然后依次和剩余的元素进行比较,若小于相邻元素,则交换两者位置,同时将较大元素作为下一个比较的基准元素,继续将该元素与其相邻 ...
- java学习_都说Java难学,不知道具体的学习内容?全套Java学习路线送上
首先,我个人比较推崇的学习方法是:先学java前段,也就是HTML,css,js,因为学习java以后肯定是往java ee方向发展的,学习完前端,在学习后端很多东西比计较容易理解! 其中J2SE是关 ...
- groovy 使用java类_深入学习java中的Groovy 和 Scala 类
前言 Java 传承的是平台,而不是语言.有超过 200 种语言可以在 JVM 上运行,它们之中不可避免地会有一种语言最终将取代 Java 语言,成为编写 JVM 程序的最佳方式.本系列将探讨三种下一 ...
- 简单java程序_简单的Java程序
简单java程序 Simple java programs are good for assessing the coding skills of a programmer. You will fin ...
- java安装_在线学习Java编程的最佳方法
java安装 1.简介 Java是使用最广泛的编程语言之一. 根据Github的最新报告,Java被列为仅次于JavaScript的第二大最常用的编程语言. 掌握Java的人有很多话题. 好消息是,您 ...
- 安卓 java内存碎片_理解Android Java垃圾回收机制
Jvm(Java虚拟机)内存模型 从Jvm内存模型中入手对于理解GC会有很大的帮助,不过这里只需要了解一个大概,说多了反而混淆视线. Jvm(Java虚拟机)主要管理两种类型内存:堆和非堆. 堆是运行 ...
- java拆解_深入拆解Java虚拟机视频教程
目录: 第1节说在前面的话 00:05:07分钟 | 第3节环境搭建以及jdk,jre,jvm的关系 00:20:48分钟 | 第5节jvm再体验-jvm可视化监控工具 00:21 ...
最新文章
- 步步为营 .NET 设计模式学习笔记 六、Adapter(适配器模式)
- java三大集合_java中三大集合框架
- 数据结构与算法基础-试题
- python运行一个项目_Django 项目创建到启动(最全最详细的第一个项目)
- linux系列之:告诉他,他根本不懂kill
- 数学狂想曲(十)——复变函数, 平稳离散时间随机过程, 功率谱
- python多因子量化选股模型_量化新兵第十步:多因子选股模型
- vue国际化高逼格多语言
- matlab物探版,s4m matlab中画地震图件的子程序源代码,对物探人员很有用。 238万源代码下载- www.pudn.com...
- 【python学习】如何批量从文件夹中根据文件后缀名提取文件,并存储到新的文件夹
- STM32 CAN通讯过滤器使用总结及代码分析
- 平果手机桌面计算机,苹果手机怎么做老系统文件夹-苹果手机桌面怎么建文件夹...
- 个推里群推php教程,GitHub - lyx2297999137/yii2-igetui: yii2个推
- 创蓝253短信平台代码实现
- 巫师编程语言“咒语” 设想
- 特征选择(模型输入参数的分析选择)方法汇总
- 大学计算机课程ppt,以计算思维为导向的大学计算机基础课
- CSDN如何快速提升等级
- Matlab axis函数
- 视觉导航定位系统工作原理及过程