博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
快排序和堆排序,最小堆、最大堆
阅读量:6231 次
发布时间:2019-06-21

本文共 2424 字,大约阅读时间需要 8 分钟。

hot3.png

1)分类:

1)插入排序(直接插入排序、希尔排序)  

2)交换排序(冒泡排序、快速排序)

3)选择排序(直接选择排序、堆排序)

4)归并排序

5)分配排序(箱排序、基数排序)

所需辅助空间最多:归并排序

所需辅助空间最少:堆排序

平均速度最快:快速排序

不稳定:快速排序,希尔排序,堆排序。

1)选择排序算法的时候

1.数据的规模 ;  2.数据的类型 ;  3.数据已有的顺序  

一般来说,当数据规模较小时,应选择直接插入排序或冒泡排序。任何排序算法在数据量小时基本体现不出来差距。考虑数据的类型,比如如果全部是正整数,那么考虑使用桶排序为最优。  考虑数据已有顺序,快排是一种不稳定的排序(当然可以改进),对于大部分排好的数据,快排会浪费大量不必要的步骤。数据量极小,而起已经基本排好序,冒泡是最佳选择。我们说快排好,是指大量随机数据下,快排效果最理想。而不是所有情况。

快速排序

快 速排序是对冒泡排序的一种改进。它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要 小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。最坏情况的时间复杂度为O(n2),最好 情况时间复杂度为O(nlog2n)。

   假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一趟快速排序的算法是:

1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;

2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];

3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;

4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;

5)、重复第3、4步,直到I=J;

例如:待排序的数组A的值分别是:(初始关键数据X:=49)

                  A[1]    A[2]    A[3]    A[4]    A[5]     A[6]    A[7]:

                    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,两者交换,此时J:=4 )

     此时再执行第三步的时候就发现I=J,从而结束一躺快速排序,那么经过一躺快速排序之后的结果是:27       38      13      49      76      97       65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。

     快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:

初始状态                       {49    38    65    97    76    13    27}   

进行一次快速排序之后划分为     {27    38    13}    49 {76    97    65}

分别对前后两部分进行快速排序   {13}   27   {38}

                               结束        结束   {49   65}   76   {97}

                                                   49 {65}        结束

                                                       结束

                         图6   快速排序全过程

/** * 快速排序实现算法 * @author Administrator */public class SortTest {		/**		 * @param args		 */		public static void main(String[] args) 		{			// TODO 自动生成方法存根			quicksort qs = new quicksort();			int data[] = {44,22,2,32,54,22,88,77,99,11};			qs.data = data;			qs.sort(0, qs.data.length-1);			qs.display();		}	}	class quicksort	{		public int data[];				/*分割、分开*/		private int partition(int sortArray[],int low,int hight)		{			int key = sortArray[low];			while(low
=key) hight--; sortArray[low] = sortArray[hight]; while(low

堆排序:首先,数组里面用层次遍历的顺序放一棵完全二叉树。从最后一个非终端结点往前面调整,直到到达根结点,这个时候除根节点以外的所有非终端节点都已经满足堆得条件了,于是需要调整根节点使得整个树满足堆得条件,于是从根节点开始,沿着它的儿子们往下面走(最大堆沿着最大的儿子走,最小堆沿着最小的儿子走)。主程序里面,首先从最后一个非终端节点开始调整到根也调整完,形成一个heap, 然后将heap的根放到后面去(即:每次的树大小会变化,但是 root都是在1的位置,以方便计算儿子们的index,所以如果需要升序排列,则要逐步大顶堆。因为根节点被一个个放在后面去了。降序排列则要建立小顶堆)

转载于:https://my.oschina.net/hanzhankang/blog/194104

你可能感兴趣的文章
mysql+heartbeat双主高可用
查看>>
输入框字数统计(通过键盘输入和拷贝粘贴皆可)
查看>>
Qt笔记(1)连接 SQL Server 数据库
查看>>
记一次使用官方zabbix官方模板监控redis自己犯的错
查看>>
ASP.NET CS文件中输出JavaScript脚本的3种方法以及区别
查看>>
mysql 分隔某个字段
查看>>
《从零开始学Swift》学习笔记(Day 17)——Swift中数组集合
查看>>
traceroute路由追踪
查看>>
Bacula笔记
查看>>
我的友情链接
查看>>
svn merge以及Unknown action received: skipped conflicted path冲突解决
查看>>
CSS: the different of using CSS between @import and link
查看>>
f2fs 系列之七:page cache相关操作和接口
查看>>
马士兵教学语录
查看>>
ubuntu server 13.10修改引导等待时间与配置更新源
查看>>
leetCode 121. Best Time to Buy and Sell Stock 数组
查看>>
Jquery学习笔记-过滤选择器
查看>>
Android 一个apk多个ICON执行入口
查看>>
我的友情链接
查看>>
nginx安装
查看>>