快排

快排 java实现

喜你入骨 提交于 2020-03-01 04:31:42
快排 java实现 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。 快排的核心思想是:将要排序的序列(假设下标是从start到end)中选任意一个数据作为pivot(分区点,也叫基准点),然后遍历数据,将小于pivot 的数据放在pivot的前面,大于等于 pivot 的数据放在pivot的后面。之后递归的将两个子序列排序。 过程如下。 这里我们给出的是原地排序的实现,也就是算法的执行过程中不需要额外的空间。 public class Quick { // 快速排序,a是数组,n表示数组的大小 public static void quickSort(int[] a, int n) { quickSortInternally(a, 0, n - 1); } // 快速排序递归函数 private static void quickSortInternally(int[] a, int start, int end) { if (start >= end) { return; } int q = partition(a, start, end); // 获取分区点 quickSortInternally(a, start, q - 1); quickSortInternally(a, q +

快速排序---quick sort

删除回忆录丶 提交于 2020-03-01 02:34:56
快排应该是平时使用的最多的一种排序了,这里实现的快排是一种未经改良的简单快排。 快排的思想是,使用二分法找到一个中间基准值,然后将序列分成小于和大于两部分,对这两部分再分别进行快排。 public class QuickSort { int[] queue = new int[]{5,3,15,0,1,29,14,4,3,2,0}; public void quickSortTest(){ print(); quickSort(0,queue.length-1); print(); } public void print(){ int length = queue.length; int index; for(index=0;index<length;index++){ System.out.print(queue[index]+" "); } System.out.println(); } public void quickSort(int left,int right){ if(left<right){ int pivotpos = Partition(left,right); quickSort(left,pivotpos-1); quickSort(pivotpos+1,right); } } public int Partition(int low,int high){

使用Java泛型实现快速排序(快排,Quicksort)算法

巧了我就是萌 提交于 2020-02-28 21:54:53
快排算法的特点 实用性强。 很多实际的项目中使用了快排算法。但通常对算法都进行了调整(tuning),比如Java.util.Arrays类中的sort函数就使用了快排算法,但使用了双参考值( Dual-Pivot Quicksort )等一些改进措施。由于快排算法为递归算法,可以用循环代替递归函数调用,改进性能。 不需要额外的空间。 可以将数组中的数据直接交换位置实现排序,所以理论上不需要额外的空间。 时间复杂度 平均情况:O(nlgn) 最坏情况: O(n*n),发生在当数据已经是排序状态时 快排算法的基本原理 1、从数据中选取一个值a[i]作为参考 2、以a[i] 为参考,将数据分成2部分:P1、P2,P1中的数据全部≤a[i],P2中的数据全部>a[i],数据变为{{P1}{a[i]}{P2}} 3、将P1、P2重复上述步骤,直到各部分中只剩1个数据 4、数据完成升序排列 示例: 原始数据: {3,9,8,5,2,1,6} 第1步:选取第1个数据:3 第2步:将数据分成2部分,左边≤3,右边大于>3: {2,1} {3} {9,8,5,6} 第3步:将各部分重复以上步骤,直到每部分只剩1个数据: {2,1} => {1} {2} {9,8,5,6} => {8,5,6} {9}=> {5,6} {8} {9}=> {5} {6} {8} {9} 第4步:数据完成升序排列:

分治思想:快速排序

心已入冬 提交于 2020-02-02 01:51:59
快速排序思想: 设k=a[0](取基准元素),将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k的右边,和k相等的,在k的左右均可。然后再把k的左边的元素和右边的元素按照同样的方式进行排序。 时间复杂度:n*logn 空间复杂度:1 和归并排序比较,快速排序比归并排序更加节省空间,但是快速排序的稳定性要比归并排序差。 这里快排的代码没有对基准元素进行优化,属于最原始的快排代码。在快排的单数组比较的代码中,给了2种对比的方式。 代码: #include <iostream> using namespace std; void QuickSort(int arr[], int left, int right);//快排1 void QuickSort2(int arr[], int left, int right);//快排2 void swap(int& a, int& b); int main() { int arr[] = { 15,6,11,7,5,99,22,3,2,67,45,12,23,1,43,55,0,8,17,58 };//初始待排序数组 int size = sizeof(arr) / sizeof(int); int left = 0, right = size - 1; QuickSort(arr, left, right); for (int

JS函数

佐手、 提交于 2020-02-01 00:49:23
快速排序 算法步骤: 在数列之中,选择一个元素作为”基准”(pivot),或者叫比较值。 数列中所有元素都和这个基准值进行比较,如果比基准值小就移到基准值的左边,如果比基准值大就移到基准值的右边 以基准值左右两边的子列作为新数列,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。 算法分析: 稳定性:快排是一种不稳定排序,比如基准值的前后都存在与基准值相同的元素,那么相同值就会被放在一边,这样就打乱了之前的相对顺序 比较性:因为排序时元素之间需要比较,所以是比较排序 时间复杂度:快排的时间复杂度为O(nlogn) 空间复杂度:排序时需要另外申请空间,并且随着数列规模增大而增大,其复杂度为:O(nlogn) 归并排序与快排 :归并排序与快排两种排序思想都是分而治之,但是它们分解和合并的策略不一样:归并是从中间直接将数列分成两个,而快排是比较后将小的放左边大的放右边,所以在合并的时候归并排序还是需要将两个数列重新再次排序,而快排则是直接合并不再需要排序,所以快排比归并排序更高效一些,可以从示意图中比较二者之间的区别。 快速排序有一个缺点就是对于小规模的数据集性能不是很好。 示例 假设用户输入了如下数组: 创建变量i=0(指向第一个数据), j=5(指向最后一个数据), k=6(赋值为第一个数据的值)。 我们要把所有比k小的数移动到k的左面,所以我们可以开始寻找比6小的数,从j开始

算法学习?挑战高薪的必经之路!让面试官满意的排序算法(图文解析)

我的梦境 提交于 2020-01-07 01:09:43
让面试官满意的排序算法(图文解析) 这种排序算法能够让面试官面露微笑 这种排序算法集各排序算法之大成 这种排序算法逻辑性十足 这种排序算法能够展示自己对Java底层的了解 这种排序算法出自Vladimir Yaroslavskiy、Jon Bentley和Josh Bloch三位大牛之手,它就是JDK的排序算法——java.util.DualPivotQuicksort(双支点快排) 想看以往学习内容的朋友 可以看我的GitHub: https://github.com/Meng997998/AndroidJX 觉得文章枯燥的朋友,可以看视频学习 DualPivotQuicksort 先看一副逻辑图(如有错误请大牛在评论区指正) 插排指的是改进版插排—— 哨兵插排 快排指的是改进版快排—— 双支点快排 DualPivotQuickSort没有Object数组排序的逻辑,此逻辑在Arrays中,好像是归并+Tim排序 图像应该很清楚:对于不同的数据类型,Java有不同的排序策略: byte、short、char 他们的取值范围有限,使用计数排序占用的空间也不过256/65536个单位,只要排序的数量不是特别少(有一个计数排序阈值,低于这个阈值的话就没有不要用空间换时间了),都应使用计数排序 int、long、float、double 他们的取值范围非常的大,不适合使用计数排序

算法 - 排序算法的稳定性

蹲街弑〆低调 提交于 2019-12-05 02:03:46
排序算法的稳定性 排序的稳定性,指原有数据相同值的原始次序不变。 可以: 冒泡排序遇到相等的数不交换即可做到稳定。 插入排序,遇到相等的数即停止比较,插入数组。 归并排序 merge 过程中,遇到相等的值先填入左区域的值就可以做到稳定。 不可以: 选择排序不能做到稳定性,选择数值的时候交换数字是会打乱原始的次序。 随机快排不具有稳定性,因此荷兰国旗问题也是不能做到稳定性的。 堆排序。 稳定性的意义: 现实工程中需要 保持上一次排序时遗留的信息 ,比如学校的成绩排序,第一次查询以成绩高低排序,第二次查询以班级排序,如果排序算法具有稳定性,就可以保留上一次查询的信息,那么第二次查询得到的结果就是以班级和成绩高低两项指标排序的成绩。 排序总结 工程上的排序算法是综合排序:先调用快排或归并排序,再调用插入排序。 在样本量小于 60 的时候使用插入排序,对比冒泡排序和选择排序,插入排序的时间复杂度是受数据状况影响的,范围是 [O(n), O(n^2)] , 而且其代码简洁,常数项低; 样本量大于 60 的时候,在能使用快排的场景下,如不用区分数据的差异,不追求稳定性,这时选用快排,因为其非常简洁,操作少,常数项低;需要区分数据的差异,要求算法具有稳定性的时候使用归并排序。 工程中需要将快排和归并排序的递归调用部分改写成非递归的调用。 归并排序空间复杂度是 O(N),可以变成 O(1)

快速排序思想及实现

让人想犯罪 __ 提交于 2019-12-04 15:39:01
1、快速排序思想:快速排序主要利用分治和递归的思想,例如,将一个数组{2,5,10,1,0,7}排序。首先选取其第一个元素2作为基准,将<2的元素移动到其左边,将>=2的元素移动到其右边(其中等于2放左放右都可以),此过程称为一次分区,可以得到{0,1,2,10,5,7}。经过一次分区后,数组就分成了两个部分,左边小于2,右边大于等于2。因此可以继续分别对其左右分区{0,1,2}和{10,5,7}再分别进行快排,不断的迭代,直至完全有序。 过程解析图 2、代码实现 import java.util.Arrays; public class TestQuickSort { private static int partition(int[] arr, int low, int high) { //指定左指针i和右指针j int i = low; int j= high; //将第一个数作为基准值。挖坑 int x = arr[low]; //使用循环实现分区操作 while(i<j){//5 8 //1.从右向左移动j,找到第一个小于基准值的值 arr[j] while(arr[j]>=x && i<j){ j--; } //2.将右侧找到小于基准数的值加入到左边的(坑)位置, 左指针想中间移动一个位置i++ if(i<j){ arr[i] = arr[j]; i++; } //3

QuickSort快排算法

此生再无相见时 提交于 2019-11-29 06:31:12
QuickSort快排算法: 如 6 1 2 7 9 3 4 5 10 8 基准数:最左的数:6 规则:最左的哨兵i, 最右的哨兵j; 先从最右往左 找一个小于基准的数,再从左往右找一个大于基准的数, 交换[i] 和 [j] ; 当i==j 时, 交换基准数和[i] , 则基准数归位(找到自己正确的位置)。 本质:每一轮会使一个基准数归位。 开始: 6 1 2 7 9 3 4 5 10 8 第一轮: 6 1 2 7 9 3 4 5 10 8 6 1 2 5 9 3 4 7 10 8 第二轮: 6 1 2 5 9 3 4 7 10 8 6 1 2 5 4 3 9 7 10 8 第三轮: 3 1 2 5 4 6 9 7 10 8 【6】归位! 左: 3 1 2 5 4 右:9 7 10 8 同理! 代码如下: package com.suixingpay.testpro; /** * @program: test-pro * @description: 快排算法 * @author: jiabao.yan * @create: 2019-09-03 18:48 **/ public class QuickSortTest { public static void main(String[] args) { int[] arr = { 49, 38, 65, 97, 23, 22, 76

快排

空扰寡人 提交于 2019-11-28 23:39:21
先讲经典快排。 数组最后一个值是 X (划分值) 争取<= X 的值放在左边,>= X 的放在右边。 开始一个数组,最后一个值作为划分值。 然后整个数组分为两个部分,<=X 的在左边,>=X 的在右边。 然后<=X 的当做一个全新的数组,再次把最后一个值当做划分值。两个部分拆分下去,让整个部分都有序。以上是经典快排。 改进: =x 的部分不动,小于X 的区域和大于 X 的区域继续这样的过程——递归。 package suanfa; public class quickSort { public static void quicksort(int[] arr) { //重载 if (arr == null || arr.length < 2) { return; } quicksort(arr, 0, arr.length - 1); } public static void quicksort(int[] arr, int L, int R) { if (L < R) { // 临界条件 //swap(arr,L+(int)(Math.random()*(R-L+1)),R); 这时一个随机快排 int[] p = partition(arr, L, R); //经过一个p过程,返回一个数组,是等于区域的左右两个边界 quicksort(arr, L, p[0] - 1); //