折半插入排序
折半插入排序是对直接插入排序的优化,折半插入排序所需附加存储空间和直接插入排序相同,从时间上比较,折半插入排序仅减少了关键字间的比较次数,而记录的移动次数不变。因此,折半插入排序的时间复杂度仍为O(n2)。
直接插入排序可参考:https://blog.csdn.net/ZipayYu/article/details/98245056
示例:
此处以数据2的排序为例,用i从左到右遍历到下标为5的位置,发现此处的值2小于前一位的值5
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 1 | 3 | 4 | 5 | 2 | 6 | |
遍历位置 | i |
将2放到缓存0的位置,下限low从下标1开始,上限high从下标i-1开始
计算折半位置为m = (low + high) / 2=2
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 3 | 4 | 5 | 2 | 6 |
遍历位置 | low | m | high | i |
比较r[0]与r[m],发现r[0]<r[m],插入点在低半区,上限high 移到 m - 1的位置
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 3 | 4 | 5 | 2 | 6 |
遍历位置 | low,high | m,high+1 | i-1 | i |
此时下限与上限相等了,r[high+1]~r[i-1]的记录后移,即上表数据3,4,5向后移动,移动结果见下表
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 3 | 3 | 4 | 5 | 6 |
遍历位置 | low,high | m,high+1 | i |
然后将a[0]插入到high+1的位置,数据2的排序过程结束
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
数据 | 2 | 1 | 2 | 3 | 4 | 5 | 6 |
遍历位置 | low,high | m,high+1 | i |
代码实现:
说明:本博客的代码实现贴近数据结构(C语言版) 课本代码风格,使用抽象数据类型。
项目结构
status.h
#pragma once
#include <stdarg.h>
#include <stdlib.h>
#include <iostream>
#define TRUE 1 //真
#define FALSE 0 //假
#define YES 1 //是
#define NO 0 //否
#define OK 1 //通过
#define ERROR 0 //错误
#define SUCCESS 1 //成功
#define INFEASIBLE -1