简介
上篇发布的插入排序,属于直接插入排序,本期文章是对直接插入排序的优化。
算法思想
插入排序有个明显的特征:局部有序。可以利用二分(或叫折半)法减少比较次数。依旧以打扑克牌为例:通过折半查找确定新取到牌的插入位置,根据手中已有扑克牌的中间牌,比较新牌与中间牌的大小,若新牌 >= 中间牌,则插入位置在中间牌的右侧;否则,在在左侧。
时间复杂度上:折半插入排序,虽然减少了比较次数,但移动次数不变,复杂度依旧为O(n^2)
代码实现
public static void binaryInsetSort(int[] pokerArr) {
for ( int i = 1; i < pokerArr.length; i++ ) {
//新取到的牌
int newPoker = pokerArr[i];
int left = 0;
int right = i - 1;
while (left <= right) {
//取中间位
int m = (left + right) / 2;
//新取到的牌 >= 当前中间位置牌 说明在右半部分,否则在左半部分
//循环直到left = right 即:筛选到最后只剩一张牌了,newProker >= 最后一张牌 就放他后面,反之放左边( >= 在牌相等的情况下,相等牌不用移动哦)
if (newPoker >= pokerArr[m]) {
left = m + 1;
}else {
right = m - 1;
}
}
//此时left就是newProker需要插入的位置,将left ~ i-1位置的牌,全部向后移动一位
for (int j = i; j > left; j--) {
pokerArr[j] = pokerArr[j-1];
}
//将newProker插入
pokerArr[left] = newPoker;
}
}