排序之选择排序、堆排序、归并排序、高速排序

本学习笔记内容部分来自网易云课堂浙江大学数据结构视频,及海子的博客:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html以及~大器晚成~的博客http://www.cnblogs.com/luchen927/archive/2012/02/29/2368070.html

1、选择排序

基本思想:在一个长度为N的无序数组中。在第一趟遍历N个数据,找出当中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出当中最小的数值与第二个元素交换......第N-1趟遍历剩下的2个数据,找出当中最小的数值与第N-1个元素交换。至此选择排序完毕。

举例:选择排序:56 12 80 91 20

第一次:遍历这5个数。找到最小值12。位置在2,交换1和2位置的数字,12 56 80 91 20

第二次:遍历剩下的4个数。找到最小值20。位置在5,交换2和5位置的数字,12
20 80 91 56

依次类推

2、堆排序

是对选择排序的改进

基本思想:

1、将初始待排序keyword序列(R1,R2....Rn)构建成最大堆。此堆为初始的无序区;

2、将堆顶元素R[1]与最后一个元素R[n]交换。此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];

3、因为交换后新的堆顶R[1]可能违反堆的性质,因此须要对当前无序区(R1,R2,......Rn-1)调整为新最大堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。

不断反复此过程直到有序区的元素个数为n-1。则整个排序过程完毕。

举例:堆排序:16,7,3,20,17,8

第一次:构建初始最大堆:

,此时交换最大值20和堆最后一个位置元素得到

第二次:除20外剩下的元素继续调整为最大堆,之后再交换顶点最大值和倒数第二个位置的元素。得到:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

依次类推

对N个元素进行堆排序,最坏情况下时间复杂度为O(NlogN)

3、归并排序

核心:有序子列的归并

两个有序子列归并算法例如以下:



watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

归并算法基本思想:将待排序文件看成为n个长度为1的有序子文件,把这些子文件两两归并,得到「n/2」个长度为2的有序子文件;然后再把这「n/2」个有序文件的子文件两两归并。如此重复,直到最后得到一个长度为n的有序文件为止。这样的排序方法成为二路归并排序。

举例:归并排序:72 18 53 36 48 31 36

第一趟:18 72|36 53|31 48|36

第二趟:18 36 53 72|31 36 48

第三趟:18 31 36 36 48 53 72

算法:分而治之:

归并排序非递归的算法须要额外的空间O(N)

4、高速排序

基本思想:高速排序是找出一个元素(理论上能够随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归高速排序。将其它n-1个元素也调整到排序后的正确位置。最后每一个元素都是在排序后的正
确位置。排序完毕。

怎样选基准??算法Median3    想法是把左、中、右三个位置最小的元素放到最左边,然后返回中间位置那个数做为基准

选定基准后,怎样划分子集呢?左右各一个指针,分别往中间走,当左右指针各不正确时(左边大于基准、右边小于基准为不正确的情况)。左右指针指的数字交换。



watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

举例:

2 2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比較2和5,5比2大,j左移

2 2 4 9 3 6 7 1 5 比較2和1。1小于2,所以把1放在2的位置

2 1 4 9 3 6 7 1 5 比較2和4,4大于2,因此将4移动到后面(原来1的位置)

2 1 4 9 3 6 7 4 5 比較2和7,2和6,2和3。2和9,所有大于2。满足条件,因此不变

经过第一轮的高速排序,元素变为以下的样子

[1] 2 [4 9 3 6 7 5]

之后,在把2左边的元素进行快排。因为仅仅有一个元素,因此快排结束。右边进行快排。递归进行,终于生成最后的结果。

注:当递归的数据规模充分小时。则停止递归,直接调用简单排序就可以了。

时间: 2024-08-26 06:53:01

排序之选择排序、堆排序、归并排序、高速排序的相关文章

算法 排序NB二人组 堆排序 归并排序

参考博客:基于python的七种经典排序算法     常用排序算法总结(一) 序前传 - 树与二叉树 树是一种很常见的非线性的数据结构,称为树形结构,简称树.所谓数据结构就是一组数据的集合连同它们的储存关系和对它们的操作方法.树形结构就像自然界的一颗树的构造一样,有一个根和若干个树枝和树叶.根或主干是第一层的,从主干长出的分枝是第二层的,一层一层直到最后,末端的没有分支的结点叫做叶子,所以树形结构是一个层次结构.在<数据结构>中,则用人类的血统关系来命名,一个结点的分枝叫做该结点的"

常见的排序算法(四)( 归并排序,计数排序 , 基数排序)

 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. (如果读者不太了解什么叫分治法,可以去看看<算法导论>第一二章.) 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1:否则将第

算法学习之排序算法(五)(高速排序)

1.算法思想 设要排序的数组是A[0]--A[N-1],首先随意选取一个数据(通常选用数组的第一个数)作为重要数据,然后将全部比它小的数都放到它前面.全部比它大的数都放到它后面.这个过程称为一趟高速排序.值得注意的是,高速排序不是一种稳定的排序算法.也就是说,多个同样的值的相对位置或许会在算法结束时产生变动. 一趟高速排序的算法是: 1)设置两个变量i.j.排序開始的时候:i=0.j=N-1. 2)以第一个数组元素作为重要数据,赋值给key.即key=A[0]. 3)从j開始向前搜索,即由后開始

高速排序算法

高速排序算法 作者 July  二零一一年一月四日------------------------------------------ 写之前,先说点题外话.每写一篇文章,我都会遵循下面几点原则:一.保持版面的尽量清晰,力保排版良好.二.力争所写的东西,清晰易懂,图文并茂三.尽最大可能确保所写的东西精准,有实用价值. 由于,我认为,你既然要把你的文章,发布出来,那么你就一定要为你的读者负责.不然,就不要发表出来.一切,为读者服务. ok,闲不多说.接下来,咱们立马进入本文章的主题,排序算法.众所

C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序

以下列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序,然后是測试的样例.代码位置:http://download.csdn.net/detail/luozuolincool/8040027 排序类: public class Sortings { //插入排序 public void insertSort(int[] array) { int temp = 0; int index = 0; for (int i = 0; i <

C# 插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序

下面列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序,然后是测试的例子.代码位置:http://download.csdn.net/detail/luozuolincool/8040027 排序类: public class Sortings { //插入排序 public void insertSort(int[] array) { int temp = 0; int index = 0; for (int i = 0; i <

七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)

 写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列.因此排序掌握各种排序算法非常重要.对下面介绍的各个排序,我们假定所有排序的关键字都是整数.对传入函数的参数默认是已经检查好了的.只是简单的描述各个算法并给出了具体实现代码,并未做其他深究探讨. 基础知识: 由于待排序的记录数量不同,使得排序过程中设计的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在计算机随机存储器中进行的排序过程.另一类是外部排序,

九种经典排序算法详解(冒泡排序,插入排序,选择排序,快速排序,归并排序,堆排序,计数排序,桶排序,基数排序)

综述 最近复习了各种排序算法,记录了一下学习总结和心得,希望对大家能有所帮助.本文介绍了冒泡排序.插入排序.选择排序.快速排序.归并排序.堆排序.计数排序.桶排序.基数排序9种经典的排序算法.针对每种排序算法分析了算法的主要思路,每个算法都附上了伪代码和C++实现. 算法分类 原地排序(in-place):没有使用辅助数据结构来存储中间结果的排序**算法. 非原地排序(not-in-place / out-of-place):使用了辅助数据结构来存储中间结果的排序算法 稳定排序:数列值(key)

排序 之 堆排序 归并排序

堆的概念 堆是具有下列性质的完全二叉树:每个节点的值都大于或等于其左右孩子结点的值,称为大顶堆:或着每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆. 堆排序 堆排序(Heap Sort)就是利用堆(假设利用大顶堆)进行排序的方法.它的基本思想是,将待排序的序列构造成一个大顶堆.此时,整个序列的最大值就是对顶的根结点.将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次大值.如此反复执行,就可以得到一个