排序分类
- 插入排序
- 直接插入排序
- 折半插入排序
- 表插入排序
- 希尔排序
- 交换排序
- 冒泡排序
- 快速排序
- 选择排序
- 简单选择排序
- 堆排序
- 归类排序
- 分配排序
- 多关键字排序
- 基数排序
直接插入排序
假设有n个记录需要排序,初始时直接插入排序认为只有第一个记录有序,后面的n-1个记录都是无序的,然后取无序的第一个元素,与有序的元素作顺序比较,将比他大的数后移一个位置,直到找到合适它的位置插入。
这里从无序记录中获取R[i],从R[i-1]向前进行顺序查找
用直接插入排序实现{54 26 65 77 60 50 30 42}的排序过程(括号内有序)
折半插入排序
折半插入排序是对直接插入排序的改进,部分记录有序时,将无序的记录用折半插入排序插入到合适的位置
用折半插入排序实现{26 30 50 54 60 65 77 42}的排序过程
表插入排序
表插入排序为了减少排序记录的“移动”过程,而改变了存储结构,利用了静态链表进行排序,排序完成后再改变结点的位置,使得每个记录都能在相应的位置。
用表插入排序实现{72 40 18 6 32}的排序过程
希尔排序
希尔排序可以看做是直接排序算法的改进算法,它取不同的间隔的各值进行比较排序,使得序列“基本有序”,每次排序的间隔减少,最后一次为间隔为一即进行直接插入排序
用希尔排序实现{23 56 48 64 10 15 46 78}的排序过程
冒泡排序
从头到尾扫描记录序列,并比较相邻的两个记录的大小,记录大的后移,第一趟就能将记录最大的移动到末尾,第二趟将第二大的值移动到倒数第二位,如此反复直到排序完成
用冒泡排序实现{45 26 78 51 56 78 1 5}的排序过程
快速排序
快速排序是基于分组进行的排序方式,再待排序的记录中取任意一直(比如第一个),以该记录为标准从两端到中间进行比较交换;将记录分为两组,小于或等于该记录的放在左边,大于该记录的放在右边,重复该方法直到以该记录为中间值划分两组记录,小的在左大的在右
用快速排序实现{40 23 46 72 5 51 19 45}的排序过程
第一轮快速排序
40是我们任意取的标准值,low,high向中间扫描并取值与标准值比较,开始时high先向中间扫描,high在标准值的右边所以要找比中间值大的进行交换,45>40不动,19<40两值交换
high进行一次交换后位于标准值的左边,则轮到low向中间扫描,23<40不动,46<40两值交换
low进行一次交换后位于标准值的右边,轮到high向中间扫描,51<40不动,5<40两值交换
low,high都指向标准值是结束改轮排序
整个排序的过程为
简单选择排序
简单选择排序在第i趟时,通过n-i次比较,从n-i+1个记录中选出最小的记录,然后与第i个记录交换
用简单排序实现{45 54 64 23 15 70}的排序过程
第一个实线箭头代表第i个数,后面那个箭头是扫描时,从后往前扫描,到底i个数停止,虚线为该n+i-1个数内的最小值
堆排序
要实现堆排序首先我们要构建堆(完全二叉树),堆分为大顶堆:每个结点都大于或等于左右孩子结点;小顶堆:每个节点都小于或等于左右孩子结点,然后通过输出堆顶元素和重新构建堆,再输出再构建如此反复最后得到顺序序列
我们下面以小顶堆为例
如此反复,直到所有元素输出,得到顺序序列
调整和输出顶堆时,如为小顶堆,比较左右子树,从小的开始调整;如为大顶堆,比较左右子树,从大的开始调整
归并排序
归并排序时将有序的子序列合并,得到一个排好序的完整
用归并排序实现{26 77 16 22 46 53 30 24}的排序过程
该归并排序为二路归并排序,即有两个子序列合并成一个序列的归并排序
多关键字排序
关键字是按照各位的值进行排序的,如关键字k=132,k=(k1, k2, k3)=(1, 3, 2)
k1是最高位关键字,关键字排序一般有两种方法:MSD法,关键字最高为优先排序法;LSD法,关键字最低位优先排序法
使用多关键字LSD法对学生记录排序
设k=(系别,班号,班内序号)=(k1,k2,k3)
基数排序
在多关键字记录的序列中,如果每个关键字取值范围相同,则按LSD排序时可以用“分配-收集”,将记录排序
如对于键值为{156 351 141 259 246 146 341 151}数的范围为[0,999],基数为rd=10即[0~9],键值有效为d=3即有三次收集
用基数排序对上面的记录序列排序的过程