排序
排序是计算机程序设计的重要操作,掌握排序,可以提高查找效率。
使序列按照一个关键字有序序列,这样的操作称之为排序。
优点:
如果数据能够按照某种规则排序,就能大大提高算法效率,通常在处理数据之前
需要先对其进行排序。
排序特性:
唯一性
稳定性
排序的分类:
内部排序
外部排序(涉及内、外存交换)
注意:内部排序适宜在纪录个数不多的小文件情况下使用
外部排序适用于纪录个数太多,不能一次将其全部纪录放入内存的大文件
注意:排序的关键字必须相同,不然排序的结果是不唯一的。
排序算法分析:
1、考虑比较的次数
2、数据移动的次数
注意:但是两者很难达到最高效,可根据实际情况选择哪一种算法
插入排序
就是将每一个待排序的纪录按照其关键字大小插入到前面已经排序好的子文件的适当位置,直到全部插入完成为止。
直接插入排序
注意:直接插入排序是稳定的排序方法
折半插入排序
问题:为什么内层的循环while(low<=high){...}结束之后以low作为a[i]应该放置的位置?
来自 <详解折半插入排序算法 - tensory - 博客园>
希尔排序
希尔排序又称缩小增量排序,其本质还是插入排序,只不过是将待排序列按某种规则分成几个子序列,然后如同前面的插入排序一般对这些子序列进行排序。因此当增量为 1 时,希尔排序就是插入排序,所以希尔排序最重要的就是增量的选取。
主要步骤:
图解:
代码实现:
注意:最后一个增量必须是1,希尔排序比直接插入排序更好,但是是不稳定的排序方法
交换排序
交换,指比较两个元素关键字的大小,来交换两个元素在序列中的位置,从而达到序列有序的状态。主要分类有冒泡排序和快速排序。
冒泡排序
比较相邻的两个元素,数值大的放在右边,
注意:第四趟就把顺序排出来了,那么还需要进行比较吗?
要的,因为暂时我们的计算机还没有人工智能,自我辨别的能力。
代码实现:
1、有一个数组进行存储数列,
2、通过双层for循环进行比较
3、外层控制轮数,(arr.length)、内层(arr.length-1-i)
注意:冒泡排序是就地排序,它是稳定的。
快速排序
实际也是属于交换类排序,对冒泡排序进行了改进,只是他通过多次划分操作实现排序,分治思想。
分治法:将原问题分解成若干个规模更小但结构于原问题相似的子问题,递归的解决这些子问题,然后将这些子问题的解组合为原问题的解。
步骤:
过程图解:
代码实现:
注意:
快速排序是非稳定的。
选择排序
就是每一次从代派序列中选择出关键字最小的元素,直到待排序列选择完毕后结束。
主要分类:直接选择排序和堆排序
直接选择排序
第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,与R[1]交换,....,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列。
代码实现:
堆排序
堆是一种数据结构,可以把堆看成一颗完全二叉树,
过程:堆排序就是把堆排序的序列构造成一个堆,将堆中最大的取走,再将剩余的元素调整成堆,然后再将最大的元素取出。这样重复直至取出的序列有序。
排序主要步骤可以分为(以大顶堆为例):
一般升序采用大顶堆,降序采用小顶堆
过程图解:
代码实现:
注意:堆排序也是一种不稳定的排序方法
归并排序
也是建立在分治法。也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。
若将两个有序表合并成一个有序表,称为二路归并。
要解决归并问题,首先需要解决两两归并问题。
实例说明:
代码实现:
注意:归并排序是一种稳定的排序。
基数排序
过程:第一步先按个位进行 分配,放入带有编号的桶中,第二步按十位进行分配…..直至最高位。
代码实现: