简单选择排序和直接插入排序
Posted zhlabcd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单选择排序和直接插入排序相关的知识,希望对你有一定的参考价值。
简单选择排序
简单选择排序就是通过关键字之间的比较,在记录里面找到最小(或者最大)的数字,并同当前位置交换之。
贴个代码:
void SelectSort(SqList *L) { int i, j, min; for (i = 0; i < L->length - 1; i++) { min = i; for (j = i + 1; j < L->length; j++) { if (L->r[min] > L->r[j]) { min = j; } } if (i != min) swap(L, i, min); } }
分析一下:很显然,对于一个无序数组来说,把第一个数的下标暂且作为值最小的下标,然后通过与其后的数据对比,找出真正的最小的数组的下标,如果找到,就交换,如果没找到,说明当前数据是最小的,那么就不用交换。然后下标递增,再次比较。就这样实现排序。
复杂度分析:
我们知道,交换最多需要n - 1次(最少需要0次)。而第i次排序需要n - i 次比较,那么总共有 (n - 1) + (n - 2) + (n - 3) +..... + 1 = n * (n - 1) / 2次比较,显然时间复杂度就是O(n ^ 2)(但是比起冒泡排序来说,简单选择的性能还是要比冒泡好一点。
直接插入排序
直接插入排序,就是将一个记录插入到已经排好序的有序表中,从而得到一个新的有序表。
先给出代码,稍后分析:
void InsertSort(SqList *L) { int i, j; for (i = 2; i < L->length; i++) //下标从2开始。 { if ( L->r[i] < L->r[i - 1]) { L->r[0] = L->r[i]; for (j = i - 1; L->r[j] > L->r[0]; j--) L->r[j + 1] = L->r[j]; L->r[j + 1] = L-> r[0]; //注意上面有j--,所以这里空出来的位置应该是j + 1 } }
代码分析:如上(升序排序),我们举个栗子,有一个无序数组{5, 3, 2, 4 , 6},现在要把它给拍好,怎么做呢?
首先,我们把r[1] = 5当作是有序的一个数组(这里的L->r[0]必须要空出来当哨兵),即:{ 5 };那么现在我们需要将剩下的{3, 2, 4, 6}插入到{5}这个有序表中,显然现在的问题就是插入到5左边还是右边了,为此,下标从2开始,循环比较两两之间的大小,如果后者比前者小,那么就把后者的值赋值给哨兵,再把前者适当的往后移动(这里的适当是有条件的,也就是L->r[j] > L->r[0],即到出现比哨兵小的数据为止)。移动完之后再把哨兵的值赋值给移动出来的空位。
复杂度分析:如果要排序的数组一开始就是有序的,那么只需要比较次数,时间复杂度为O(n),而最坏的情况(数组完全逆序),那么这个时候,当外循环等于2(总共执行n - 2次)时,内循环执行了n - 1次,当外循环等于3时,执行了n - 2次。。。。。。所以,总的执行次数为 n - 2 + n - 3 + ....+ 1 = ( n-1) * (n - 2) / 2,也就是O(n^2)。虽然是平方阶,但是它的性能比冒泡和简单选择要好的多。
以上。
下次写希尔排序和堆排序
以上是关于简单选择排序和直接插入排序的主要内容,如果未能解决你的问题,请参考以下文章
插入排序(直接插入排序希尔排序);交换排序(冒泡排序快速排序);选择排序(简单选择排序堆排序);归并排序和基数排序;基于关键词比较的排序算法下界分析
八大基础排序中(直接插入排序,希尔排序,冒泡排序, 快速排序,归并排序,简单选择排序)