二分法插入排序算法的尝试
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分法插入排序算法的尝试相关的知识,希望对你有一定的参考价值。
这是一个《算法导论》上的练习,可将插入排序的总体运行时间降至Θ(nlgn),我们先看看插入排序的算法代码:
#include <stdio.h> int main(void) { int arr[] = {6,3,1,5,4,2}; int i, j; int temp; for(i = 1; i < sizeof(arr)/sizeof(int); i++) //运行时间Θ(n) { temp = arr[i]; j = i - 1; while(j >= 0 && arr[j] > temp) //这里线性时间进行查找移动,运行时间Θ(n),所以整体运行时间Θ(n^2) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = temp; } for(i = 0; i < sizeof(arr)/sizeof(int); i++) printf("%d ", arr[i]); printf("\n"); return 0; }
从代码可以看出,arr[j] > temp的判断查找是在前面所有小于 j 的部分中进行移动和查找的,而小于的 j 部分都是已经排好序的,因此我们可设计使用二分查找带进行更快速的处理。但我的尝试出现了问题:
/** * 二分法+插入排序 - Θ(nlgn) * */ #include <stdio.h> int main(void) { int arr[] = {6,3,1,5,4,2}; int i, j; int mid, left; int temp; left = 0; for(i = 1; i < sizeof(arr)/sizeof(int); i++) { temp = arr[i]; j = i - 1; mid = (left + j) / 2; while(temp > arr[mid + 1] || temp < arr[mid - 1])
//情况是这样的,比如:进行到 123645,当把4进行比较后,从1236中查找位置时
//只有当同时不满足循环条件,即 3 < 4 < 6 时,不满足条件 ,就可以退出了,当前的 mid 就是4可以插入的位置。 { if(arr[mid] > temp) mid = (mid + j) / 2; else if(arr[mid] < temp) mid = (left + mid) / 2; } for(j = i - 1; j >= mid; j--){ //移动要插入的位置以后且小于当前比较数以前的位置 arr[j + 1] = arr[j]; } arr[j] = temp; //把比较数插入其中 } for(i = 0; i < sizeof(arr)/sizeof(int); i++) printf("%d ", arr[i]); printf("\n"); return 0; }
然而,我的尝试失败了,代码看上去好像没什么问题,但while还是陷入了死循环,不知道什么原因...这个循环条件的判断难道有什么问题吗?我暂时先记录下来吧,改天再继续思考这个问题...
以上是关于二分法插入排序算法的尝试的主要内容,如果未能解决你的问题,请参考以下文章
Java八股文面试题 基础篇 -- 二分查找算法冒泡排序选择排序插入排序希尔排序快速排序