插入排序的思想很简单:假设前N-1个数据已经排好序了,第N个数据插到前面已经排好序的数组中。这和生活中一件事情有着异曲同工之妙:玩扑克牌的时候,很多人(包括我)都会按照花色从大小(或反之)进行排序,而每次再拿到新的牌,则插入到合适的位置,其实这就是插入排序的思想。
因此插入排序的过程可以分为两个步骤:1)找到新元素的插入位置;2)将将元素插入到1)中确定的位置,这就需要移动元素了。1)中确定位置我们可以采用简单的顺序遍历的方法得到,但是注意到由于前N-1个元素已经排好序,因此可以使用二分查找的方式实现。前者就是普通的插入排序,而后者就是二分插入排序。两者的实现源码为:
|
template <class Item> void InsertSort(Item* data,int len) { for (int i = 1; i < len; ++i) { Item tmp = data[i]; int j; //记录插入的位置 //找到插入的位置 for (j = 0; j < i; ++j) { if (data[i] < data[j]) break; } for (int k = i; k > j; --k) { data[k] = data[k - 1]; } data[j] = tmp; } } |
二分插入排序:
|
template <class Item> BInsertSort(Item* data,int len) { Item tmp; int idx; int l,r; for (int i = 1; i < len; ++i) { tmp = data[i]; l = 0; r = i - 1; //二分查找获得插入位置 while (l <= r) { idx = (l + r)/2;
if (data[idx] < tmp) { l = idx + 1; } else { r = idx - 1; } } for (int k = i; k > l; --k) { data[k] = data[k - 1]; } data[l] = tmp; } } |
测试程序为:
|
int main(int argc,char* argv[]) { int* data = InitData<int>(10,100); PrintData<int>(data,10,"before BubbleSort");
// InsertSort(data,10); // BInsertSort(data,10);
PrintData<int>(data,10,"after BubbleSort"); return 0; } |
需要说明和注意的是:InitData 和PrintData定义和实现在排序与查找——备用函数给出的,请参考上一篇文章。
浙公网安备 33010602011771号