C++ 折半插入排序

  • Post author:
  • Post category:其他




总结归纳

  • 折半插入排序是直接插入排序的优化,查找待插入元素的位置时使用折半查找。
  • 折半插入排序仅减少了比较次数,并未改变移动次数,故时间复杂度仍为



    O

    (

    n

    2

    )

    O(n^2)






    O


    (



    n










    2









    )





  • 算法原理如下:

    1.设置第一个元素为有序区域,有序区域之后的第一个元素设为“标兵”。

    2.使用折半查找遍历有序区域,找到对应位置后右移后面的元素进行插入。

    3.当“标兵”大于某一元素时,将“标兵”插入该位置(因为是有序区域,“标兵”前面的数据一定是有序排列的)。

    4.更新有序区域和“标兵”, 持续遍历。
  • 下面的代码实现浪费了一个 A[0] ,用于存储“标兵”的数值,插入时直接赋值 A[0]。
  • A[high + 1] 为插入位置,因为折半查找停止的条件为;high 位于 low 的左边第一位。移动元素时只需让出 A[high + 1] 后即可停止。
  • 折半插入排序是一种稳定的排序算法。



代码实现

/*
折半插入排序
*/

#include <iostream>
#include <time.h>

using namespace std;

typedef int ElemType;

// 折半插入排序
void InsertSort(ElemType A[], int len) {
    int i, j, low, high, mid;
    for (i = 2; i < len; i++) {
        A[0] = A[i]; // 将A[i]暂存至A[0]
        low = 1;
        high = i - 1;
        while (low <= high) {
            mid = (low + high) / 2;
            if (A[mid] > A[0]) {
                high = mid - 1; // 查找左半子表
            } else {
                low = mid + 1; // 查找右半子表
            }
        }

        for (j = i - 1; j >= high + 1; --j) {   //从最右边开始,直到让出A[high + 1]的位置
            A[j + 1] = A[j]; // 元素后移
        }
        A[high + 1] = A[0]; // A[high + 1]为插入位置,因为在折半查找停止时,high位于low的左边一位

        for (int i = 1; i < len; i++) {
            cout << A[i] << ' ';
        }
        cout << endl;
    }
}

int main() {
    int len = 10;
    ElemType arr[len] = {};
    srand(time(NULL));
    for (int i = 1; i < len; i++) {
        arr[i] = rand() % 100; // 随机生成
        cout << arr[i] << ' ';
    }
    cout << endl;

    InsertSort(arr, len);
    for (int i = 1; i < len; i++) {
        cout << arr[i] << ' ';
    }

    return 0;
}



版权声明:本文为qq_43650934原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。