数据结构——排序
1、基数排序
数据:5 45 81 27 61 91 93 42 28 36
step1:建0~9 的空队列
step2:按个位数放入 取出
取出后:81 61 91 42 93 5 45 36 27 28
step3:按十位数放入 取出
取出后:5 27 28 36 45 61 81 91 93
排序完毕
2、堆排序(只有根节点的值对整个排序过程有意义)
初始数据:75 35 50 20 25 9 60 99 33
step1:向量的堆化
step2:从最下面开始一小堆一小堆排序
每一个小子堆的比较:最上面节点与左右两节点比较,与较大的交换,交换后的位置再与其下的左右节点比较。
排序后:99 75 60 35 25 9 50 20 33 得到最大数据
3、快速排序
取中间数与数列第一个数交换(偶个则一直取靠前那个或一直取后面那个)
int h(ead),t(ail);
1、h从前往后遍历,t从后往前遍历,不断与交换后的第一个数比较;
h所指值若比第一个数大则停止,t所指值若比第一个数小则停止;
交换h与t所指的值。
2、不断重复1过程,直到h所指下标大于t所指下标。
3、交换第一个数的值和 t 所指的值。
中间数的位置即是最终位置,以中间数为划分将数列分段,重复上述过程。
排序数据:800 150 300 650 550 500 400 350 450 900
排序完毕
ps:快速排序可以应用于找k th-largest element
实现代码:
4、选择排序
类似于扑克牌的理牌方法,遍历选出最小数据放到前面。
数据:5 45 81 27 61 91 93 42 28 36
5 45 81 27 61 91 93 42 28 36
5 45 81 27 61 91 93 42 28 36
5 27 81 45 61 91 93 42 28 36
5 27 28 45 61 91 93 42 81 36
……
5、插入排序
一个一个取数,与前一位比较,小则交换,大则取下一个数。
数据:5 45 81 27 61 91 93 42 28 36
5 45 81 27 61 91 93 42 28 36
5 45 81 27 61 91 93 42 28 36
5 45 81 27 61 91 93 42 28 36
5 45 27 81 61 91 93 42 28 36
5 27 45 81 61 91 93 42 28 36
5 27 45 81 61 91 93 42 28 36
……
写代码时记得交换位置后动态更新所指下标
6、冒泡算法
优化过程:若一趟遍历没有一次交换则说明已经排好,break。
7、归并排序
两段已经排好的子列
不断比较indexA和indexB指向的数值,小的push back进tempVector,小的index++;
有余的子列直接将剩余数放入。
子列的产生与以上原理相同,并不是用其他方法排序。
将数据不断分割直到只有一个数据,再层层归并。
排序完毕后要将数据拷贝回原数列。
代码实现:
8、希尔排序
将n个元素分成n个子表
0:a[0],a[k+0],a[2k+0],……
1:a[1],a[k+1],a[2k+1],……
2:a[2],a[k+2],a[2k+2],……
……
k-1:a[k-1],a[k+k-1],a[2k+k-1],……
用插入排序法排每一个子表,
再用更小的k值重复直到k=1。
排序数据:7 5 8 6 2 4 9 1 3 0 k=4
0: 7 2 3 -> 2 3 7
1: 5 4 0 -> 0 4 5
2: 8 9 -> 8 9
3: 6 1 -> 1 6
按下标取回后:2 0 8 1 3 4 9 6 7 5 k=1
即直接进行插入排序。
//此方法的效率体现我们可以看0这个数据,若直接用插入排序要换9次位置,而用希尔排序则优化到只用3次。
关于k的取值:
1,4,13,40,121,364,1093,4193,16577……
实际取k时用n/9,从上列中找小于等于n/9且差最小的数
之后用k/3代替k进行迭代。