10大排序算法对比
冒泡排序
算法描述
冒泡排序是一种交换排序,它的基本思想是:对待排序记录从后往前(逆序)进行多遍扫描,当发现相邻两条记录的次序与排序要求的规则不符时,就将这两个记录进行交换。这样,值较小的记录将逐渐从后面向前移动,就像气泡在水中向上浮一样。
实现步骤
假设需要排序的记录有n 个,其值保存在数组A 中,使用冒泡排序法,需对数组A进行n-1 次扫描,完成排序操作。具体过程如下:
1. 将A[n-1] 与A[n] 进行比较,若A[n] < A[n-1] ,则交换两元系的位置。
2. 修改数组下标,使需要比较的两个元素为A[n-1] 和A[n-2] ,重复步骤(1),对这两个元素进行比较。重复这个过程,直到对A[1] 和A[0] 进行比较完为止。完成第1 遍扫描。
3. 经过第1 遍扫描后,最小的元素已经像气泡一样“浮”到最上面,即位于元素A[0] 中了。接下来重复前面的步骤,进行第2 遍扫描,只是扫描结束位置到A[2] 与A[1] 进行比较完为止(因为A[0]中已经是最小的数据,不用再进行比较)。
4. 通过n-1 遍扫描,前n-1 个数都已经排序完成,最后一个元素A[n] 肯定就是最大的数了。至此,完成排序操作。
图片
代码实现
希尔排序
算法描述
希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序,如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动。
实现步骤
希尔排序的思想是采用插入排序的方法,先让数组中任意间隔为 h 的元素有序,刚开始 h 的大小可以是 h = n / 2,接着让 h = n / 4,让 h 一直缩小,当 h = 1 时,也就是此时数组中任意间隔为1的元素有序,此时的数组就是有序的了。
代码实现
选择排序
算法描述
选择排序是通过n-i 次关键字间的比较,从n-i+1 个记录中选出关键字最小的记录,并和第i ( 1 <= i <= n ) 个记录交换。
实现步骤
1. 维护数组中最小的前n 个元素的已排序序列。
2. 每次从剩余未排序的元素中选取最小的元素,将其放在已排序序列的后面,作为序列的第n+1 个记元素。
3. 以空序列作为排序工作的开始,直到未排序的序列里只剩一个元素时(它必然为最大),只需直接将其放在已排序的记录之后,整个排序就完成了。
图片
代码实现
插入排序
算法描述
插入排序是通过构建有序序列,从未排序数据中选择一个元素,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在从后向前扫描过程中,需要把已排序元素逐个向后移动,为最新元素提供插入空间。
实现步骤
1. 对于第1 个元素,因为没有比较,将其作为已经有序的序列。
2. 从数组中获取下一个元素,在已经排序的元素序列中从后向前扫描,并进行判断。
3. 若排序序列的元素大于新元素,则将该元素向后移动一位。
4. 重复步骤(3),直到在已排序的元素中找到小于或者等于新元素的元素,将新元素插入到该元素的后面。
5. 重复步骤(2) ~ (4),直到完成排序。
图片
代码实现
快速排序
算法描述
快速排序是通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
实现步骤
快速排序使用分治策略来把待排序数据序列分为两个子序列,具体步骤如下:
1. 从数列中挑出一个元素,以该元素为“基准”。
2. 扫描一遍数列,将所有比“基准”小的元素排在基准前面,所有比“基准”大的元素排在基准后面。
3. 通过递归,将各子序列划分为更小的序列,直到把小于基准值元素的子数列和大于基谁值元素的子数列排序。
图片
代码实现
堆排序
算法描述
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
实现步骤
1、将初始待排序关键字序列(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,则整个排序过程完成。
图片
代码实现
归并排序
算法描述
归并是一种典型的序列操作,其工作是把两个或更多有序序列合并为一个有序序列。基于归并的思想也可以实现排序,称为归并排序。
实现步骤
1. 初始时,把待排序序列中的n 个元素看成n 个有序子序列(因为只有1 个元素的序列总是排好序的),每个子序列的长度均为1。
2. 把序列组里的有序子序列两两归并,每完成一论归并,序列组里的序列个数减半,每个子序列的长度加倍。
3. 对加长的有序子序列重复上面的操作,最终得到一个长度为n 的有序序列。这种归并方法也称为简单的二路归并排序,其中每次操作都是把两个有序序列合并为一个有序序列。也可考虑三路归并或更多路的归并。
图片