排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。下面让我们一起来看快速排序。
AD:
快速排序(Quicksort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。快速排序不稳定,O(log(n))的额外空间,时间复杂度为O(nlog(n)),不是自适应的。
快速排序(Quicksort)有几个值得一提的变种算法,这里进行一些简要介绍:
随机化快排:快速排序的最坏情况基于每次划分对主元的选择。基本的快速排序选取第一个元素作为主元。这样在数组已经有序的情况下,每次划分将得到最坏的结果。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为主元。这种情况下虽然最坏情况仍然是O(n^2),但最坏情况不再依赖于输入数据,而是由于随机函数取值不佳。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2^n)。所以随机化快速排序可以对于绝大多数输入数据达到O(nlogn)的期望时间复杂度。一位前辈做出了一个精辟的总结:“随机化快速排序可以满足一个人一辈子的人品需求。”
随机化快速排序的唯一缺点在于,一旦输入数据中有很多的相同数据,随机化的效果将直接减弱。对于极限情况,即对于n个相同的数排序,随机化快速排序的时间复杂度将毫无疑问的降低到O(n^2)。解决方法是用一种方法进行扫描,使没有交换的情况下主元保留在原位置。
平衡快排(BalancedQuicksort):每次尽可能地选择一个能够代表中值的元素作为关键数据,然后遵循普通快排的原则进行比较、替换和递归。通常来说,选择这个数据的方法是取开头、结尾、中间3个数据,通过比较选出其中的中值。取这3个值的好处是在实际问题(例如信息学竞赛……)中,出现近似顺序数据或逆序数据的概率较大,此时中间数据必然成为中值,而也是事实上的近似中值。万一遇到正好中间大两边小(或反之)的数据,取的值都接近最值,那么由于至少能将两部分分开,实际效率也会有2倍左右的增加,而且利于将数据略微打乱,破坏退化的结构。
外部快排(ExternalQuicksort):与普通快排不同的是,关键数据是一段buffer,首先将之前和之后的M/2个元素读入buffer并对该buffer中的这些元素进行排序,然后从被排序数组的开头(或者结尾)读入下一个元素,假如这个元素小于buffer中最小的元素,把它写到最开头的空位上;假如这个元素大于buffer中最大的元素,则写到最后的空位上;否则把buffer中最大或者最小的元素写入数组,并把这个元素放在buffer里。保持最大值低于这些关键数据,最小值高于这些关键数据,从而避免对已经有序的中间的数据进行重排。完成后,数组的中间空位必然空出,把这个buffer写入数组中间空位。然后递归地对外部更小的部分,循环地对其他部分进行排序。
三路基数快排(Three-way Radix Quicksort,也称作MultikeyQuicksort、Multi-key Quicksort):结合了基数排序(radixsort,如一般的字符串比较排序就是基数排序)和快排的特点,是字符串排序中比较高效的算法。该算法被排序数组的元素具有一个特点,即multikey,如一个字符串,每个字母可以看作是一个key。算法每次在被排序数组中任意选择一个元素作为关键数据,首先仅考虑这个元素的第一个key(字母),然后把其他元素通过key的比较分成小于、等于、大于关键数据的三个部分。然后递归地基于这一个key位置对“小于”和“大于”部分进行排序,基于下一个key对“等于”部分进行排序。
快速排序是目前使用的最广泛的排序算法了,快速排序的核心在于分割算法,也可以说是最有技巧的部分。希望通过本文的介绍,能给你带来帮助。
代码一:
<wbr><pre name="code" class="java"> public static voidquickSort(int[] a, int low, int high) {
int n =a.length;
int i =low;
int j =high;
int temp= a[low];
while (i< j) {
//必须从右边开始扫描,否则从左边开始扫描遇到一个比它大的元素时(左边不是有一个空位吗?但是放到左边肯定是不合适)应该放到右边,放到哪里呢,放到任何地方都会覆盖掉一个数据 这样没有利用上这个缺口 严重错误
while(i < j && a[j]>= temp) {
j -- ;//放过
}
if(i<j) {
a[i] = a[j] ;
i ++ ; //放过,并开始左端循环
}
while(i< j && a[i]< temp) { //注意 :" < " 而不是<=这个细节说明即使和temp相等也要放到它的后面这样保证了-在数值相同时,保持原有顺序的原则!
i ++ ;
}
if(i< j) {
a[j] = a[i] ;
j -- ;
}
}
a[i] =temp ;
//有可能i=low 如 :a[low]是最小的,一开始循环就一直j-- 一直减到了i ==j然后赋值(即它本来就应该在第一位),也有可能a[low]是最大的,一直i++到high。如果是这样就不用对那个子区间排序了,所以下面用if语句
if(i> low) quickSort(a, low, i-1) ;
if(i< high) quickSort(a , i+1, high) ;
}
public static voidmain(String[] args) {
int [] a= {49,38,65,97,76,13,27};
quickSort(a, 0 , a.length-1) ;
print(a);
}
//为了打印数组的方便增加一个方法print()
public static voidprint(int [] a) {
int n =a.length ;
for(inti=0;i<n;i++) {
System.out.print(a[i] + " ") ;
if((i+1) % 5 == 0) {
System.out.println() ;
}
}
System.out.println( ) ;
}
}</pre>
<br><br></wbr>
代码二:
public class quickSort2 {
public static void main(String[] args){
//声明数组
int[] nums ={49,38,65,97,76,13,27,-77};
//应用快速排序方法
quickSort(nums, 0,nums.length-1);
//显示排序后的数组
for(int i = 0; i< nums.length; ++i) {
System.out.print(nums[i] +",");
}
System.out.println("");
}
public static void quickSort(int[] a, int M, int K){
int lo =M;
System.out.println("lo是从左到右,初始值为:"+lo);
int hi =K;
System.out.println("hi是从右到左,初始值为:"+hi);
if (lo >=hi) {
System.out.print("lo:"+lo+" hi:"+hi);
System.out.println(" 因为lo:"+lo+">=hi:"+hi+"被返回!!");
return;
}
//确定指针方向的逻辑变量
booleantransfer=true;
while (lo != hi){
System.out.println("lo的值是:"+lo);
System.out.println("hi的值是:"+hi);
if(a[lo] > a[hi]) {
//交换数字
int temp = a[lo];
a[lo] = a[hi];
a[hi] = temp;
System.out.println("交换数字了!"+a[lo]+"和"+a[hi]+"进行了交换,temp的值为:"+temp);
//显示每一次比较的数组数字的变化
System.out.print("现在数组的排列顺序为:");
for(int i = 0; i< a.length; ++i) {
System.out.print(a[i] +",");
}
System.out.println("特殊记号M:"+M);
//决定移动,還是不動,这个开关是个钟摆,轮流真假两种状态!触发条件是发生交换!
transfer = (transfer == true) ? false :true;
System.out.println("开关动了,指针要移动了!开关transfer的值为:"+transfer);
}
//将指针向前或者向后移动,默认情况下lo++,注意!有交换不一定会让transfer变为true!--,
if(transfer) {
hi--;
System.out.println("hi被减了1");
}
else{
lo++;
System.out.println("lo被加了1");
}
}
System.out.println("while循环退出,lo和hi相等:"+lo+"="+hi);
//将数组分开两半,确定每个数字的正确位置,return的时候会单独做这个操作
lo--;
hi++;
System.out.println("将数组分开两半,确定每个数字的正确位置,现在lo和hi的值为:"+lo+" "+hi);
System.out.println("M的值为:"+M);
//神奇的M,因为没有传任可值过去,所以M一直为最原先程序所传过来的“0”
System.out.println("quickSort(a, M, lo)");
System.out.println("调用程序之前 M:"+M+" K:"+K+" hi:"+hi+" lo:"+lo );
quickSort(a, M, lo);
System.out.println("调用程序之后 M:"+M+" K:"+K+" hi:"+hi+" lo:"+lo );
System.out.println("quickSort(a, hi, K);");
quickSort(a, hi,K);
System.out.println("调用程序之后 M:"+M+" K:"+K+" hi:"+hi+" lo:"+lo );
}
}
分享到:
相关推荐
在JAVA中,实现这两种排序算法可以使用面向对象的特性,创建一个类如`MaopaoKuaisu.java`,在这个类中定义两个方法,分别实现冒泡排序和快速排序。类的结构可能如下: ```java public class MaopaoKuaisu { public...
快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是分治法(Divide and Conquer),通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的...
在编程领域,排序算法是数据结构与算法学习中的重要组成部分,尤其在Java中,掌握各种排序算法对于优化程序性能至关重要。以下将详细讲解标题和描述中提到的五种排序算法:选择排序、插入排序、自顶向上合并排序、...
"快速排序算法java代码" ...*Scientific computing:快速排序算法可以用于科学计算中的排序操作。 快速排序算法是一种高效、稳定、广泛应用的排序算法,它有很多优点和缺点,但它仍然是目前最快的排序算法之一。
本文将深入探讨Java编程语言中实现的七种主要排序算法:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序以及归并排序。每种算法都有其独特性,适用于不同的场景和数据特性。 1. **直接插入排序**:...
本文将详细探讨标题所提及的几种排序算法:合并排序、插入排序、希尔排序、快速排序、冒泡排序以及桶排序,并结合Java语言的实现进行解析。 1. **合并排序(Merge Sort)**: 合并排序是一种基于分治策略的排序算法...
Java 快速排序,目前来说效率很高的一种排序算法,好理解。
Java实现快速排序算法+编程知识+技术开发; Java实现快速排序算法+编程知识+技术开发; Java实现快速排序算法+编程知识+技术开发; Java实现快速排序算法+编程知识+技术开发; Java实现快速排序算法+编程知识+技术...
Java排序算法大全是一份专为Java开发者准备的学习资源,涵盖了各种经典的排序算法,旨在帮助初学者和有经验的程序员深入理解排序的原理和实现。排序是计算机科学中的基础且重要的概念,它在数据处理、数据库操作、...
以上介绍了Java排序算法中常见的几种方法及其变体。每种算法都有其特点和适用场景,例如当数据量较小时可以选择直接插入排序或直接选择排序;当数据量较大时,归并排序和快速排序则更为合适。理解这些算法的工作原理...
快速排序:分别使用Java和Python实现快速排序算法.zip 快速排序:分别使用Java和Python实现快速排序算法.zip 快速排序:分别使用Java和Python实现快速排序算法.zip 快速排序:分别使用Java和Python实现快速排序算法....
在Java编程语言中,排序算法是数据结构与算法学习中的重要组成部分。本实验通过生成大量随机数并写入文件,然后使用四种不同的排序算法进行排序,以比较它们的效率。以下是对这四种排序算法的详细解释: 1. **冒泡...
在Java中,我们可以创建一个名为`Qsort`的类来实现快速排序。这个类包含两个主要方法:`sort`和`partition`。`sort`方法是快速排序的递归入口,`partition`方法则是快速排序的核心,它负责将数组分为两部分,并返回...
这个名为"Java各种排序算法代码.zip"的压缩包包含了一系列实现不同排序算法的Java源代码。排序算法是计算机科学中的基本概念,用于对一组数据进行排列。下面将详细讨论这些算法及其在Java中的实现。 1. 冒泡排序...
这里我们将深入探讨标题和描述中提到的六种排序算法:快速排序、归并排序、插入排序、冒泡排序、选择排序以及堆排序。 1. **快速排序**:由C.A.R. Hoare在1960年提出,是一种高效的分治算法。快速排序的基本思想是...
快速排序是一种高效的排序算法,由英国计算机科学家C.A.R....这个压缩包中的"java快速排序算法"可能包含了更多关于快速排序的示例代码、详细解析和实践练习,可以帮助初学者更好地理解和掌握这种高效的排序算法。
【Java排序算法详细整理】 在计算机科学中,排序算法是用于对一组数据进行排列的算法。在Java中,实现各种排序算法有助于理解数据结构和算法的原理,同时也能提高编程能力。以下是对Java中常见的几种排序算法的详细...
在编程领域,排序算法是计算机科学中的核心概念,特别是在Java这样的高级编程语言中。排序算法是用来组织和优化数据结构的关键工具,它可以帮助我们快速查找、分析和处理数据。本资源包含的是Java实现的各种常见排序...