内部排序
(排序期间元素存放在内存中的排序)
1. 插入排序
每次将一个待排序的记录插入前面已排好序的子序列。
- 直接插入排序:每次将后方未排序序列的第一个与已排序序列从后向前比较,插入对应位置。
- 折半插入排序:先折半查找待插入的位置,然后同上插入。
- 希尔排序:相隔增量d的元素组成一个子表,各子表内进行直接插入排序;缩小增量 d,重复以上步骤直至d=1全部有序。(不稳定)
2. 交换排序
- 冒泡排序:从后往前/从前往后两两比较,每趟冒泡通过一次次交换将最小元素放在最终位置
- *快速排序:基于分治法。取一个待排序元素作为基准,两端指针不断搜索交换小于和大于枢轴的元素,最终放入枢轴元素,确定一个最终位置,这一趟排序将待排序元素分为两部分。递归的对两个子表重复以上内容。(不稳定)(尽量选将数据中分的枢轴元素/随机取)
3. 选择排序
- 简单选择排序:每次在待排序元素中选取最小元素放入有序序列,第i趟即将最小元素与L(i)交换。(不稳定)
- *堆排序:n个元素构成初始堆完全二叉树,然后依次对⌊n/2⌋~1为根的子树进行筛选,直到根节点。其中比较次数最多等于树高-1(适合关键字较多的情况)
4. 归并排序
归并,即把两个及以上的有序表组合成一个新的有序表。
2路归并排序,即从长度为1的子表开始两两归并,通过从两个段各取一个记录依次比较得到有序段。递归的2路归并排序算法是基于分治的。
5. 基数排序
基于关键字各位的大小依次逐层划分进行排序。按关键字位权重递减即最高位优先法,递增即最低位优先法。
取r为基数,d为位数。使用r个队列做d次分配和收集得到有序序列。
内部排序算法的应用
n较小-->直接插入排序、简单选择排序
基本有序-->直接插入、冒泡
n较大-->快速排序、堆排序、归并排序(稳定)、基数排序(关键字位数少时)
注:记录本身信息量大用链表,减少移动耗费时间
外部排序
(排序期间元素会在内、外存间移动的排序)
归并排序法:根据内存缓冲区大小划分外存文件为多个长度l的子文件,读入内存进行内部排序,再写回外存。称这些有序子文件为归并串/顺串。
外部排序总时间=内部排序时间+外存读写时间+内部归并时间
- k路归并即k个输入缓冲区,可减少归并趟数,进而减少总的磁盘I/O次数。但内部归并时间随k增大而增大。
- 引入败者树进行归并:叶结点存放归并段,每次得到一个最小数即根节点。使得内部归并时间与k无关。
置换-选择排序生成初始归并段:内存工作区可容纳w个记录,每次选比上一个输出关键字大的最小关键字输出(利用败者树),当选不出时,此时的输出作为一个归并段。
最佳归并树:记录数少的先归并,可使得总的I/O次数最少。用虚段辅助构成k叉树的形式((n-1)%(k-1)=u不为0则加上k-u-1个虚段)。