直接插入排序和希尔排序

来源:互联网 发布:centos开机进入grub 编辑:程序博客网 时间:2024/04/16 15:40

插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。

直接插入排序:每次将一个待排序的元素,与已排序的元素从尾到头进行比较,找到合适位置进行插入;


对一个乱序数组进行排序,将第一个元素看作是有序数组,后面的元素是待插入元素,进行直接插入排序,在这个有序数组的基础上插入后面的数据,直到所有数据全部直接插入排序完成。

void SortInsert(int *arr, int length){assert(arr);if (length <= 1)   //数组只有一个元素不需要排序{return;}int index = 0;while (index < length - 1){int end = index;int x = arr[end + 1];for (int i = end; end >= 0;){if (arr[end] > x){arr[end + 1] = arr[end];end--;}else{break;}}//break,出来 x插入在end的下一个位置//for循环走完出来,此时end = -1;x插入在0这个位置,也就是end+1这个位置;arr[end + 1] = x;index++;}}
算法分析:将数组排序成升序的前提下讨论。

1.当数组所有(n个数据)元素为升序排列时,也就是此时数组有序,仅外循环循环n-1次,里边的for循环均只走了一次;此时的时间复杂度为O(N)

2.当数组所有元素为降序排列时,每一次外循环,待插入元素都要和index之前的元素进行比较,并且后移index次。此时的时间复杂度为:1+ 2+3+4+5+6+...+(n-1) = n*(n-1)/2 = O(N*N)

希尔排序:

是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着增量逐渐减小,分组越来越多,当增量减少至1时,排序完成。

大致分为两步完成;

第一步,预排序:使整个数组接近有序,大的数据尽快到后面,小的数据尽快到前面;

第二部,最后排序:此时gap = 1;也就是分组的增量为1,就是直接插入排序;

如果我们有这样一些数据,{2,5,4,9,3,6,8,7,1,0}对其进行一趟希尔排序


进行多趟排序,直至gap = 1时直接插入排序完成,所有的才算正式结束。

代码实现:

void SortShell(int arr[], int length){assert(arr);int gap = length;while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < length - gap; i++){int end = i;int tmp = arr[end + gap];while (end >= 0){if (arr[end] > tmp){  arr[end + gap] = arr[end];end = end - gap;}else{break;}}arr[end + gap] = tmp;}}}
算法分析:

增量:gap

算法最开始以一定的gap进行排序,然后会继续以一定gap进行排序,最终算法以gap为1进行排序。当gap=1时,算法为直接插入排序,这就保证了数据一定会被排序。

希尔排序的时间复杂度与增量序列的选取有关;


 



0 0
原创粉丝点击