快速排序是通用排序中(针对内存中)最为流行的算法,其时间效率为O(n * log n)。
其关键算法是基于划分的排序。
划分只将数组中任意一个元素作为枢纽值,经过交换,使得数组中排列成所有小于枢纽的数值都在枢纽左边,而所有大于枢纽的数值都在枢纽右侧,然后返回枢纽的位置。注意,枢纽的选择可以是任意的。
快排选择将给定数组范围的的第一个数字作为枢纽,然后将数组分为两部分,大于枢纽的,小于枢纽的。然后对这两部分递归调用快速排序。
快排在极端情况下可能出现效率底下问题,这与枢纽的选取的策略有关,加入数组完全逆序,则枢纽总会选取指定范围中最大的值,只是一次简单交换,没有将数组有效划分两个部分。因此可以调整枢纽选取策略来修正这个问题,比如在给定范围中前中后三个位置选取三个值,选择值为中间的位置作为枢纽,这样可以一定程度上避免极端问题。
其他速度较快的,且很少出现极端情况的排序方法见希尔排序
代码如下:
class Quick {
public static void main(String[] args) {
int[] a = {6,9,5,4,2,45,23,45,53,3,7};
int pos = getPartitionPos(a,0,a.length);
sort(a,0,a.length);
println(a);
}
public static void println(int[] a) {
for(int i: a) System.out.print(i + " ");
System.out.println();
}
public static void sort(int[] a,int begin, int end) {
if(begin >= end) return;
int pos = getPartitionPos(a,begin,end);
sort(a,begin,pos);
sort(a,pos + 1, end);
}
private static int getPartitionPos(int[] a, int begin, int end) {
int pos = begin;
int value = a[begin];
while(true) {
while(begin < end && a[--end] > value); //从结尾向左找到第一个比枢纽小的数值
while(begin < end && a[++begin] < value); //从结尾向右找到第一个比枢纽大的数值
if(begin < end) { //如果需交互
a[pos] = a[end]; //将比枢纽小的值放在空位
a[end] = a[begin]; //将比枢纽大的值放在原来从右向左第一个比枢纽小的值的位置上
pos = begin; //将从左向右第一个比枢纽大的值的位置标志为空位
} else break;
}
if(pos != begin) { //如果空位与结束位置不等
a[pos] = a[begin]; //将空位置为结束时位置的值
a[begin] = value; //将结束位置放置枢纽
} else a[pos] = value;
return begin;
}
}
同样代码还可以这样:
class Quick2 {
public static void main(String[] args) {
int[] a = {1501,545,414,78,3,18,611,578,114,125,94,67,157};
sort(a,0,a.length);
print(a);
}
public static void sort(int[] a,int p1,int p3) {
if((p3-p1) <= 1) return;
int p2 = get(a,p1,p3);
sort(a,p1,p2);
sort(a,p2+1,p3);
}
public static int get(int[] a,int b, int e) {
int pos=b, temp=a[b];
boolean dir = true;
while(b<e) {
if(dir) {
if(a[--e] <= temp) {
a[pos] = a[e];
pos = e;
dir = false;
}
} else {
if(a[++b] >= temp) {
a[pos] = a[b];
pos = b;
dir = true;
}
}
}
a[pos] = temp;
return pos;
}
private static void print(int[] a) {
for(int i: a) System.out.print(i + " ");
System.out.println();
}
}
分享到:
相关推荐
快速排序和堆排序是两种非常重要的内部排序算法,在计算机科学中有着广泛的应用。它们都是基于比较的排序方法,但各自有着独特的实现策略和性能特点。 快速排序由C.A.R. Hoare在1960年提出,其核心思想是分治法。...
本主题将详细探讨四种常见的排序算法:选择排序、插入排序、快速排序以及冒泡排序,它们都是用C语言实现的。以下是这些排序算法的详细解析: 1. **选择排序(Selection Sort)** - 选择排序是一种简单直观的排序...
快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是分治策略,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再...
本主题将深入探讨四种常见的排序算法:归并排序、快速排序以及与链表相关的排序方法。 首先,我们来讨论归并排序(Merge Sort)。这是一种基于分治策略的排序算法。归并排序将大问题分解为小问题,然后逐步合并这些...
快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是分治法,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按...
但是,快速排序的实际执行时间却比堆排序更快,这是因为快速排序的 cache freundliness 比堆排序更好。 快速排序、堆排序和归并排序都是 O(nlogn) 的时间复杂度,但是它们的稳定性、辅助空间和 cache freundliness ...
Java代码-排序-直接插入排序、希尔排序、直接选择排序、冒泡排序、堆排序、快速排序、归并排序中部分排序以及算法-贪心法,大家可以将源码下载下来进行学习,附带着注释和解释,有不理解的可以找博主一起探讨,共同...
本主题主要探讨了三种经典的排序算法——希尔排序、快速排序和堆排序,并在Java语言环境下通过多线程实现,以充分利用系统资源,提升排序性能。 希尔排序是一种基于插入排序的算法,由Donald Shell于1959年提出。它...
数据结构--快速排序C++源代码,自己编写调试,代码简单易懂,不长
本篇文章将详细讨论几种常见的排序算法:选择排序、冒泡排序、插入排序、合并排序以及快速排序,分析它们的算法原理、时间效率,并通过经验分析验证理论分析的准确性。 **1. 选择排序(Selection Sort)** 选择排序...
java代码-使用java解决java排序之-快速排序的问题的源代码 ——学习参考资料:仅用于个人学习使用!
本实验旨在通过对两种经典排序算法——快速排序和归并排序的研究与实现,深入理解它们的基本原理、时间复杂度,并通过编程实践比较这两种算法在不同数据规模下的性能表现。 #### 二、快速排序 **1. 基本思想** ...
快速排序是一种高效的排序算法,由C.A.R. Hoare在1960年提出,它采用了分治(Divide and Conquer)策略。快速排序的基本思想是通过一趟排序将待排序的数据分割成两部分,其中一部分的所有数据都比另一部分的所有数据...
5. 快速排序(Quick Sort):快速排序是一种分治策略的排序算法,通过选取一个“基准”元素,将数组分为两部分,一部分的所有元素都小于基准,另一部分的所有元素都大于基准,然后再对这两部分进行快速排序。...
通过阅读和实践这些代码,你可以深入理解排序算法的内部机制,为进一步学习更复杂的排序算法如快速排序、归并排序等奠定基础。同时,这些基础知识对于提升编程能力,优化数据处理效率,解决实际问题都有着重要作用。
### c语言 - 快速排序 #### 知识点概览 1. **递归算法的概念及应用** 2. **快速排序的基本原理** 3. **快速排序的实现步骤** 4. **快速排序的时间复杂度分析** 5. **快速排序的空间复杂度分析** 6. **快速排序与...
该算法的基本思想是:选择一个基准值,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归...
快速排序快速排序 快速排序 快速排序 快速排序 快速排序
本实验涉及了四种经典的内部排序算法:希尔排序、快速排序、堆排序和归并排序。 **希尔排序**(Shell Sort)是由希尔提出的,它是一种改进的插入排序。希尔排序的核心思想是将待排序的元素按照一定的间隔分组,对每...