快速排序

概念介绍

QuickSort快速和归并排序一样,是采用分治法解决问题的一个典型应用。它选择一个元素作为基准元素,并围绕选定的基准元素对给定数组进行分区。

quickSort有很多不同的版本,它们以不同的方式选择基准元素。

  • 选择第一个元素作为基准元素。
  • 选择最后一个元素作为基准元素
  • 选择一个随机元素作为基准元素
  • 选择中值作为基准元素

QuickSort中的关键进程是partition()。
目标分区:给定一个数组和数组的一个元素x作为基准元素,将x放在已排序数组中正确的位置,并将所有较小的元素(小于x的)放在x之前,将所有较大的元素(大于x的)放在x之后。所有这些都应该在线性时间内完成。

实现思路

/* low  --> Starting index,  high  --> Ending index */
quickSort(arr[], low, high)
{if (low < high){/* pi is partitioning index, arr[pi] is nowat right place */pi = partition(arr, low, high);quickSort(arr, low, pi - 1);  // Before piquickSort(arr, pi + 1, high); // After pi}
}

适用场景

适用于大数据的比较
比较的元素越多,快速排序比冒泡排序越快

代码示例

选取最后一个值作为基准元素

public class SortExample {// Driver codepublic static void main(String args[]) {int[] arr = { 1, 20, 6, 4, 5,2,3,1,8,2 };quickSort(arr,0,arr.length-1);printArray(arr);}static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}static int partition(int[] arr, int low, int high) {// pivotint pivot = arr[high];// Index of smaller element and indicates the right position of pivot found so farint i = (low - 1);for(int j = low; j <= high - 1; j++) {// 升序排列,如果修改为>,则是倒序if (arr[j] < pivot) {// Increment index of smaller elementi++;swap(arr, i, j);}}swap(arr, i + 1, high);return (i + 1);}/* The main function that implements QuickSortarr[] --> Array to be sorted,low --> Starting index,high --> Ending index*/static void quickSort(int[] arr, int low, int high) {if (low < high) {// pi is partitioning index, arr[p] is now at right placeint pi = partition(arr, low, high);// Separately sort elements before partition and after partitionquickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}}/* A utility function to print array of size n */private static void printArray(int arr[]) {int n = arr.length;for (int i = 0; i < n; ++i) {System.out.print(arr[i] + " ");}System.out.println();}
}

选取中间值作为基准元素

public class QuickSortExample {public static void main(String[] args) {int arr[] = {981,8, 3, 2, 7, 4, 6, 8,23,23,11,8,9,11,5,50,101};quickSort(arr,0,arr.length-1);print(arr);}public static void quickSort(int arr[], int low, int high) {if (low<high) {int pivot = partition(arr, low, high);     //算出枢轴值quickSort(arr, low, pivot - 1);       //对低子表递归排序quickSort(arr, pivot + 1, high);      //对高子表递归排序}}/*函数作用:取待排序序列中low、mid、high三个位置上数据,选取他们中间的那个数据作为枢轴*/public static int partition(int arr[],int low,int high) {int mid = low + ((high - low) >> 1);  //计算数组中间的元素的下标//使用三数取中法选择枢轴if (arr[mid] > arr[high]) {swap(arr,mid,high);}if (arr[low] > arr[high]) {swap(arr,low,high);}if (arr[mid] > arr[low]) {swap(arr,mid,low);}//此时,arr[mid] <= arr[low] <= arr[high]int pivotkey = arr[low];int i = low, j = high;//从表的两端交替向中间扫描,当没有相遇while(i<j) {while (arr[j] >= pivotkey && i<j){j--;}while (arr[i] <= pivotkey && i<j){i++;}if (i<j) {swap(arr, i, j);}}//最终将基准数归位swap(arr, low, i);//返回枢轴所在的位置return i;}static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}static void print(int arr[]) {int n = arr.length;for (int i = 0; i < n; i++) {System.out.print(arr[i] + " ");}System.out.println();}
}

3区快速排序

快速排序面对重复的元素时的处理方法是,把它放在了左部分数组或右部分数组,下次进行分区时,还需检测它。如果需要排序的数组含有大量重复元素,则这个问题会造成性能浪费。

解决方法:新增一个相同区域,并把重复元素放进去,下次进行分区时,不对相同区域进行分区。

这就是3区快速排序,3区如下:

  • a[l…i] contains all elements smaller than pivot
  • a[i+1…j-1] contains all occurrences of pivot
  • a[j…r] contains all elements greater than pivot */

代码示例

import org.apache.commons.lang3.tuple.Pair;public class SortExample{// Driver codepublic static void main(String args[]) {int[] arr = { 1, 20, 4,4,4,6, 4, 5,2,3,1,8,2 };quickSort(arr,0,arr.length-1);printArray(arr);}static void quickSort(int a[], int l, int r) {if (r <= l) {return;}//返回相同区域左,右的边界-1Pair<Integer, Integer> pair = partition(a, l, r);quickSort(a, l, pair.getLeft());quickSort(a, pair.getRight(), r);}/* This function partitions a[] in three partsa) a[l..i] contains all elements smaller than pivotb) a[i+1..j-1] contains all occurrences of pivotc) a[j..r] contains all elements greater than pivot */static Pair<Integer, Integer> partition(int[] a, int l, int r) {int i = l - 1,j = r;int p = l - 1, q = r;int v = a[r];while (true) {// From left, find the first element greater than or equal to v. This loop will definitely terminate as v is last elementwhile (a[++i] < v) {// do nothing}// From right, find the first element larger than or equal to vwhile (v < a[--j]) {if (j == l) {break;}}// If i and j cross, then we are doneif (i >= j) {break;}// Swap, so that smaller goes on left greater goes on rightint temp = a[i];a[i] = a[j];a[j] = temp;// Move all same left occurrence of pivot to beginning of array and keep count using pif (a[i] == v) {p++;temp = a[i];a[i] = a[p];a[p] = temp;}// Move all same right occurrence of pivot to end of array and keep count using qif (a[j] == v) {q--;temp = a[q];a[q] = a[j];a[j] = temp;}}// Move pivot element to its correct indexint temp = a[i];a[i] = a[r];a[r] = temp;// Move all left same occurrences from beginning to adjacent to arr[i]j = i - 1;for (int k = l; k < p; k++, j--) {temp = a[k];a[k] = a[j];a[j] = temp;}// Move all right same occurrences from end to adjacent to arr[i]i = i + 1;for (int k = r - 1; k > q; k--, i++) {temp = a[i];a[i] = a[k];a[k] = temp;}return Pair.of(j,i);}/* A utility function to print array of size n */private static void printArray(int arr[]) {int n = arr.length;for (int i = 0; i < n; ++i) {System.out.print(arr[i] + " ");}System.out.println();}
}

排序算法--快速排序(QuickSort)、 3区快速排序(3 Way QuickSort)原理、适用场景及代码示例相关推荐

  1. 排序算法之三路划分的快速排序

    当待排序元素序列中有大量的重复排序码时,简单的快速排序算法的效率将会降到非常之低.一种直接的想法就是将待排序列分成三个子序列:一部分是排序码比基准元素排序码小的:一部分是与基准元素排序码等值的:一部分 ...

  2. 排序算法(二):快速排序

    快速排序(Quicksort)是对冒泡排序的一种改进. 他的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分 ...

  3. 十大经典排序算法动画与解析,看我就够了!(配代码完全版)

    排序算法是<数据结构与算法>中最基本的算法之一. 排序算法可以分为内部排序和外部排序. 内部排序是数据记录在内存中进行排序. 而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排 ...

  4. 十大经典排序算法动画与解析,看我就够了!(附代码)

    作者 | 程序员小吴 来源 | 五分钟学算法(ID:CXYxiaowu) 排序算法是<数据结构与算法>中最基本的算法之一.排序算法可以分为内部排序和外部排序.内部排序是数据记录在内存中进行 ...

  5. 各个排序算法的时间复杂度、稳定性、快排的原理以及图解

    目录 一.数据结构的八大排序算法总结笔记: 1.常见的数据结构排序算法如下图所示: 2.常见数据结构排序算法的时间复杂度.空间复杂度.稳定性介绍如下图所示: 二.排序算法逐一介绍: 1.直接插入排序: ...

  6. 十大排序算法之(二)快速排序--JAVA+C++实现(简单易懂)

    文章目录 快速排序(Quicksort) 1.实现原理: 1.1.动图展示: 1.2.实现步骤: 2.时间复杂度 3.代码实现: 3.1.JAVA 实现 3.2.C++实现 3.3.C语言实现 3.4 ...

  7. 排序算法(五):快速排序

    快速排序:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分:其中一部分的所有数据都比另外一部分的所有数据都要小.然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以 ...

  8. 排序序列排序算法总结(二)——快速排序、归并排序

    最近研究排序序列,稍微总结一下,以后继续补充: 快速排序 排序想思:通过一趟排序将要排序的数据分割成独立的两分部,其中一分部的有所数据都比另外一分部的有所数据都要小,然后再按此法方对这两分部数据别分停 ...

  9. 排序算法总结(四)快速排序【QUICK SORT】

    感觉自己这几篇都是主要参考的Wikipedia上的,快排就更加是了....wiki上的快排挺清晰并且容易理解的,需要注意的地方我也添加上了注释,大家可以直接看代码.需要注意的是,wikipedia上快 ...

最新文章

  1. pythonis啥意思-isinstance在python中的意思是什么?
  2. 02-导航实例-storyboard实现
  3. 基于koa2开发的用户中心
  4. Apache Common常用jar包
  5. 并发场景下MySQL存在的问题及解决思路
  6. 本地方法(JNI)——访问域+字符串参数
  7. java可视化压缩_WEB可视化技术发展
  8. Redis操作命令(一)
  9. java图像的灰度值获取_java获取图像灰度
  10. linux 下的文件搜索、可执行文件搜索
  11. selenium+webdriver+java(基本小例子及初始化三种浏览器)---------------
  12. JDK = JRE + 编译器 + api + tools
  13. 第1章 Linux内核概述
  14. python pdf转word并保持原有的格式_将PDF转换为Word文档后,格式即可解决问题
  15. 如何在博途精智面板及WinCC RT ADV中创建面板
  16. TeX排版系统安装使用
  17. 基于樽海鞘群算法的WSN节点的部署优化
  18. ecshop 首页调用多个促销,显示到计时
  19. QCheckBox::toggled(bool)和QCheckBox::clicked(bool)的区别
  20. sumif单列求和_EXCEL条件求和函数SUMIF的几种常见用法

热门文章

  1. 20万+字,熬夜整理了一份程序员不可或缺的软技能高分原创电子书送给你
  2. 电商图片下载,下载阿里巴巴天猫淘宝图片,电商助手
  3. bzoj-4974 [Lydsy1708月赛]字符串大师
  4. Matlab项目实例-用电量
  5. 如何使用HTML插槽自动生成目录
  6. 【彩彩只能变身队】第四次会议
  7. 控制台五子棋java源代码_两套 五子棋小游戏源码(控制台+JavaSWing)
  8. java中new的含义如何理解?
  9. 【机器学习】之第十三章——半监督学习
  10. 声学多普勒流速剖面仪_ADCP-600声学多普勒流速剖面仪