2路插入排序实现

1,2路插入排序的思想:

在折半插入排序的基础上改进,目的是减少排序过程中激动记录的次数,既然是在折半的基础上,那么应该也能减少查找操作。

具体做法:

另设一个和原数组L同类型的数组D,将L[1]赋值给D[0],并将D[0]看成是在排好序的序列中处于中间的位置,即当L中来一个数和D[0]比较,大往D[0]后放,小往前放,这时候把D看成是个循环向量。因为在以D[0]分隔的两边都是有序序列,我们可以通过折半查找,找到L[i]要插入的位置,然后移动。但是要折半查找得先找到比D[0]小的那一边的第一个数以及比D[0]大的那一边最后一个数,所以因此first和final两个向量,分别表示排序过程中得到的有序序列中第一个记录和最后一个记录的位置。

下边是具体代码:


#include "stdafx.h" #include #include #include using namespace std; int Bsearch(int *H,int i,int j,int key) { int low = i,high = j; while(low <= high) { int mid = (low + high)/2; if(key <= H[mid])high = mid - 1; else low = mid + 1; } return high; } void Binsertsort(int *H,int length) { void print(int *H,int length); int first = 0,final = 0; int *obj = new int[length]; obj[0] = H[1];//枢轴 int locat; int i; int j; for(i = 2;i <= length;i ++) { if(H[i] >= obj[0])//放在枢轴右边有序序列中 { locat = Bsearch(obj,1,final,H[i]);//找到插入位置,然后要移位 for(j = final;j >= locat + 1;j --) { obj[j + 1] = obj[j]; } obj[locat + 1] = H[i]; final++; } else if(H[i] < obj[0]) { if(first == 0) { first = (first - 1 + length) % length; obj[first] = H[i]; } else { locat = Bsearch(obj,first,length - 1,H[i]); for(j = first;j <= locat;j ++) { obj[j - 1] = obj[j]; } obj[locat] = H[i]; first--; } } } int t; for(t = 0;t <= length - 1;t ++) { H[t + 1] = obj[t]; } } void print(int *H,int length) { int i; for(i = 0;i <= length;i ++) { cout<> num; int j = 1; int *H = new int[num + 1]; H[0] = 0; //cout<<"输入数组!"<> H[j]; //} srand((int)time(0)); cout<<"产生随机数!"<

插入排序适应小规模排序,测试了十万个随机数,时间为:4771毫秒!

2路插入排序的时间代价仍是O(n2),空间代价为o(n);实际移动记录的次数约为n2 / 8;但是当第一个记录是关键字中最小或最大的记录时,2路插入排序就完全失去了优越性。

2,在网上看到一个版本,操作大概如下:

(1),先和final值比较,若大则直接在final++上插入

(2),再和first值比较,若小则直接在first--(可能要取模)上插入

(3),若都不满足,则表示在first和final中间,通过从final开始一步步往first找插入位置

没有用折半操作,我觉得应该要有折半查找的操作。

你可能感兴趣的:(校招常考算法)