算法特点:
1.分治法设计
2.节省内存
3.非常实用
算法过程:
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与key交换;
4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与key交换;
5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)
例如:待排序的数组A的值分别是:(初始关键数据:X=49) 注意关键X永远不变,永远是和X进行比较,无论在什么位子,最后的目的就是把X放在中间,小的放前面大的放后面。
A[0] A[1] A[2] A[3] A[4] A[5] A[6]:
49 38 65 97 76 13 27
进行第一次交换后:27 38 65 97 76 13 49
( 按照算法的第三步从后面开始找)
进行第二次交换后:27 38 49 97 76 13 65
( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时:I=3 )
进行第三次交换后:27 38 13 97 76 49 65
( 按照算法的第五步将又一次执行算法的第三步从后开始找
进行第四次交换后:27 38 13 49 76 97 65
( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时:I=4,J=6 )
此时再执行第三步的时候就发现I=J,从而结束一趟快速排序,那么经过一趟快速排序之后的结果是:27 38 13 49 76 97 65,即所有大于49的数全部在49的后面,所有小于49的数全部在49的前面。
变种算法
快速排序(Quicksort)有几个值得一提的变种算法,这里进行一些简要介绍:
随机化快排:快速排序的最坏情况基于每次划分对主元的选择。基本的快速排序选取第一个元素作为主元。这样在数组已经有序的情况下,每次划分将得到最坏的结果。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为主元。这种情况下虽然最坏情况仍然是O(n^2),但最坏情况不再依赖于输入数据,而是由于随机函数取值不佳。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2^n)。所以随机化快速排序可以对于绝大多数输入数据达到O(nlogn)的期望时间复杂度。一位前辈做出了一个精辟的总结:“随机化快速排序可以满足一个人一辈子的人品需求。”
随机化快速排序的唯一缺点在于,一旦输入数据中有很多的相同数据,随机化的效果将直接减弱。对于极限情况,即对于n个相同的数排序,随机化快速排序的时间复杂度将毫无疑问的降低到O(n^2)。解决方法是用一种方法进行扫描,使没有交换的情况下主元保留在原位置。
平衡快排(Balanced Quicksort):每次尽可能地选择一个能够代表中值的元素作为关键数据,然后遵循普通快排的原则进行比较、替换和递归。通常来说,选择这个数据的方法是取开头、结尾、中间3个数据,通过比较选出其中的中值。取这3个值的好处是在实际问题(例如信息学竞赛……)中,出现近似顺序数据或逆序数据的概率较大,此时中间数据必然成为中值,而也是事实上的近似中值。万一遇到正好中间大两边小(或反之)的数据,取的值都接近最值,那么由于至少能将两部分分开,实际效率也会有2倍左右的增加,而且利于将数据略微打乱,破坏退化的结构。
外部快排(External Quicksort):与普通快排不同的是,关键数据是一段buffer,首先将之前和之后的M/2个元素读入buffer并对该buffer中的这些元素进行排序,然后从被排序数组的开头(或者结尾)读入下一个元素,假如这个元素小于buffer中最小的元素,把它写到最开头的空位上;假如这个元素大于buffer中最大的元素,则写到最后的空位上;否则把buffer中最大或者最小的元素写入数组,并把这个元素放在buffer里。保持最大值低于这些关键数据,最小值高于这些关键数据,从而避免对已经有序的中间的数据进行重排。完成后,数组的中间空位必然空出,把这个buffer写入数组中间空位。然后递归地对外部更小的部分,循环地对其他部分进行排序。
三路基数快排(Three-way Radix Quicksort,也称作Multikey Quicksort、Multi-key Quicksort):结合了基数排序(radix sort,如一般的字符串比较排序就是基数排序)和快排的特点,是字符串排序中比较高效的算法。该算法被排序数组的元素具有一个特点,即multikey,如一个字符串,每个字母可以看作是一个key。算法每次在被排序数组中任意选择一个元素作为关键数据,首先仅考虑这个元素的第一个key(字母),然后把其他元素通过key的比较分成小于、等于、大于关键数据的三个部分。然后递归地基于这一个key位置对“小于”和“大于”部分进行排序,基于下一个key对“等于”部分进行排序。
public class QuickSort {
public static void sort(Comparable[] data, int low, int high) {
// 枢纽元,一般以第一个元素为基准进行划分
int i = low;
int j = high;
if (low < high) {
// 从数组两端交替地向中间扫描
Comparable pivotKey = data[low];
// 进行扫描的指针i,j;i从左边开始,j从右边开始
while (i < j) {
while (i < j && data[j].compareTo(pivotKey) > 0) {
j--;
}// end while
if (i < j) {
// 比枢纽元素小的移动到左边
data[i] = data[j];
i++;
}// end if
while (i < j && data[i].compareTo(pivotKey) < 0) {
i++;
}// end while
if (i < j) {
// 比枢纽元素大的移动到右边
data[j] = data[i];
j--;
}// end if
}// end while
// 枢纽元素移动到正确位置
data[i] = pivotKey;
// 前半个子表递归排序
sort(data, low, i - 1);
// 后半个子表递归排序
sort(data, i + 1, high);
}// end if
}// end sort
public static void main(String[] args) {
// 在JDK1.5版本以上,基本数据类型可以自动装箱
// int,double等基本类型的包装类已实现了Comparable接口
Comparable[] c = { 4, 9, 23, 1, 45, 27, 5, 2 };
sort(c, 0, c.length - 1);
for (Comparable data : c) {
System.out.println(data);
}
}
}
分享到:
相关推荐
10. **概率与随机化算法**:介绍随机化算法在解决计算问题中的应用,如鸽巢原理、随机化快速排序等。 11. **计算复杂性理论**:探讨P类、NP类问题,以及NP完全问题的性质。 12. **近似算法**:对于NP难问题,讲解...
此外,书中还包括概率算法和随机化技术,例如鸽巢原理、大数定律以及Monte Carlo和Las Vegas算法。 麻省理工学院的课堂讲义通常会提供额外的实例和解释,帮助学生更好地消化理论知识。练习题则可以检验理解和应用...
快排及随机化算法》是关于计算机科学中两个重要概念的深入探讨,主要围绕快速排序(Quick Sort)和随机化算法这两个主题展开。快速排序是一种高效的排序算法,而随机化算法则在处理大规模数据时展现出其独特优势。在...
概率分析和随机化算法是现代算法设计中的一个重要分支,《算法导论》通过这一章节向读者展示了如何将概率理论应用于算法设计中,以及如何评估随机化算法的性能。 #### 动态规划与贪心算法 动态规划是一种解决具有...
这份资料包含了书中多个章节的教学笔记和练习题解答,覆盖了算法的基础概念、复杂度分析、排序算法、概率分析、随机化算法、数据结构等内容。 #### 重要知识点详述: ##### 第2章:开始学习 - **知识点**: - ...
10. **概率与随机化算法**:书中介绍了概率论基础,并探讨了如Monte Carlo方法和Las Vegas算法等随机化技术,它们在解决某些NP难问题时展现出优势。 这些知识点构成了《算法导论》的主要内容,它们不仅是理论知识,...
通过深入学习这本《MIT算法导论》的课堂笔记,你可以系统地掌握算法的精髓,提高解决问题的能力,为未来的编程生涯打下坚实的基础。同时,Word文档的格式使得笔记易于阅读和整理,方便你在学习过程中随时查阅和复习...
- **讲座笔记**:讨论了概率在算法分析中的作用,以及如何设计和分析随机化算法。 - **解决方案**:解释了如何评估随机化算法的性能,并给出了实例。 #### 5. 第6章至第14章:排序与数据结构 - **讲座笔记**:分别...
《算法导论--教师手册》是一本为教育者设计的辅助教材,旨在配合《算法导论》第二版的深入学习。此手册由Thomas H. Cormen、Clara Lee和Erica Lin共同编著,作为对Thomas H. Cormen、Charles E. Leiserson、Ronald L...
- **讲座笔记**:讲解了如何利用概率分析来评估算法的行为,并介绍了一类特殊的算法——随机化算法。 - **解决方案**:提供了概率分析方法的应用实例,以及如何评估随机化算法的性能。 ##### 2.5 第六章:堆排序 - ...
- **主题**:探讨概率在算法分析中的作用,以及随机化算法的设计。 - **核心知识点**:期望值、概率分布、概率分析技巧。 - **第6章:堆排序** - **主题**:详细讲解堆排序算法的工作原理。 - **核心知识点**:...
《麻省理工算法导论读书笔记》是一份深入学习算法理论和实践的宝贵资源,源自世界顶级学府麻省理工学院的教学资料。这份笔记涵盖了算法分析、设计策略、数据结构等多个核心主题,对于想要深入了解算法的朋友们极具...
在概率分析和随机算法一章中,文档探讨了算法分析的概率方法,包括期望、方差等概念,并介绍了随机化算法的原理。这对于理解随机选择和概率方法在算法设计中的应用至关重要。 随后的章节“增长的函数”涉及到算法...
- **概率分析**:了解如何运用概率论工具进行算法设计,尤其是随机化算法的设计与分析。 这些知识点构成了算法设计与分析领域的核心内容,对于理解和应用计算机科学中的各种算法至关重要。通过深入学习这些知识点,...
- **主题讲解**:从堆排序到快速排序,再到线性时间排序和中位数及顺序统计量,这一系列章节的讲座笔记全面覆盖了各种排序算法的原理和应用场景。 - **解决方案**:课后解答不仅提供了排序算法的实现细节,还深入...
《算法导论》系列读书笔记之五主要涵盖了指示器随机变量、概率分析以及它们在算法设计与分析中的应用,特别是雇用问题的解决方案。在这个章节中,我们将深入探讨这些概念,以便更好地理解和运用它们。 首先,我们要...
8. **概率算法与随机化算法**:如蒙特卡洛算法和拉斯维加斯算法,用于处理大规模数据或近似计算。 9. **字符串匹配**:KMP算法、Boyer-Moore算法、Rabin-Karp算法等。 10. **计算几何**:点、线段、多边形的碰撞...
- **讲座笔记**:介绍概率分析的基本原理及如何设计和分析随机化算法。 - **习题解答**:给出概率分析和随机化算法相关的经典问题解答。 ##### 5. 第6章:堆排序 - **讲座笔记**:阐述堆排序算法的实现细节及其时间...
在《算法导论》第七章中,读者将深入理解快速排序的工作原理,学习如何实现这个算法,并了解如何通过分析证明其时间复杂度。此外,书中还可能讨论其他排序算法,如归并排序、堆排序等,以及它们与快速排序的对比和...
10. **随机化算法**:如鸽巢原理、随机化求解线性方程组、蒙特卡洛方法等,它们在某些情况下可以提供接近最优或概率最优的解。 通过阅读《麻省理工学院-算法导论》的Lecture Notes,学生不仅能深入了解各种算法的...