排序问题是各大IT公司必考的题目。
1.排序的对象--文件
被排序的对象--文件由一组记录组成。
记录则由若干个数据项(或域)组成。其中有一项可用来标识一个记录,称为关键字项。该数据项的值称为关键字
(Key)。
2.排序运算的依据--关键字
用来做排序运算依据的关键字,可以是数字类型,也可以是字符类型。
关键字的选取应依据问题的要求而定。
3.排序的稳定性
当待排序记录的关键字均不相同时,排序结果是唯一的,否则排序结果不唯一。
所谓稳定性是考量在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的
相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生变化,则称这种排序方法是
不稳定的。排序算法的稳定性是针对所有输入实例而言的。即在所有可能的输入实例中,只要有一个实例使得算法不
满足稳定性要求,则该排序算法就是不稳定的。(说得有点啰嗦)
4.排序的分类
a.按是否涉及数据的内、外存交换分
在排序过程中,若整个文件都是放在内存中处理,排序时不涉及数据内、外存交换,则称为内部排序(简称内排序
)。反之,为外部排序。
所以,内排序适用于记录个数不很多的小文件。外排序则适用于记录个数太多,不能一次将其全部记录放入内存
的大文件。
b.按是否为就地(原地)排序
如排序算法所需的辅助空间并不依赖于问题的规模n,即辅助空间时1,则称为就地排序(In-PlaceSort)
非就地排序一般要求的辅助空间为n。
5.排序算法的基本操作
大多数排序算法都有两个基本的操作:
比较两个关键字的大小;
改变指向记录的指针或移动记录本身
大多数排序算法的时间开销主要是关键字之间的比较和记录的移动。有的排序算法其执行时间不仅依赖于问题的规
模,还取决于输入实例中数据的状态(影响算法的时间复杂度)。
6.待排文件的常用存储方式
a.以顺序表(或直接用向量)作为存储结构
排序过程:对记录本身进行物理重拍,即通过关键字的比较判定,将记录移到合适的位置。
b.以链表作为存储结构
排序过程:无须移动记录,仅需修改指针。通常将这类排序称为链式排序
c.用顺序的方式存储排序的记录,但同时建立一个辅助表(如包括关键字和指向记录位置的指针组成的索引表)
排序过程:只需对辅助表目进行物理重排(即只移动辅助表的表目,而不移动记录本身)。适用于难于在链表上
实现,且仍需避免排序过程中移动记录的排序方法。
上面的介绍应该是比较容易理解的。其实,常见的面试题目一般都是对数组中的数字进行排序,对于处理海量数据,
常用堆排序、哈希表。
下面先从整体上总结一下各种排序的时间复杂度、空间复杂度以及稳定性。后面会提供各种常用排序算法思想的讲解
及Java实现的源代码。
稳定的排序 时间复杂度 空间复杂度
冒泡排序 最差、平均O(n2),最好n 1
鸡尾酒排序(双向的冒泡排序) 最差、平均O(n2),最好n 1
插入排序 最差、平均O(n2),最好n 1
归并排序 最差、平均、最好都是nlogn n
桶排序(不常用) n k
基数排序(Radix Sort,不常用) dn(d为常数) n
二叉树排序 nlogn n
图书馆排序 nlogn (1+k)n
不稳定的排序有
选择排序 最差、平均都是n2 1
希尔排序 nlogn 1
堆排序 最差、平均、最好都是nlogn 1
快速排序 平均nlogn,最坏n2 logn(递归产生的栈)