2-路插入排序(Two-Way Insertion Sort)

简介: 算法介绍算法描述算法分析代码实现参考

算法介绍


     2-路插入排序是在折半插入排序的基础上改进的,插入排序的时间主要花在比较和移动这两种操作上。2-路插入排序可以减少排序过程中移动记录的次数,但为此需要借助n个记录的辅助空间。


算法描述


     利用一个与排序序列一样大小的数组作为辅助空间,设置first和final指针标记辅助数组开始位置和最后位置。遍历未排序序列,如果待插入元素比已排序序列最小的元素(first位置)小,则first位置前移,将待排序元素插入first位置;如果待插入元素比已排序序列最大的元素(final位置)大,则final位置后移,将待排序元素插入final位置;如果待插入元素比最小大,比最大小,则需要移动元素,过程类似直接插入排序,不过考虑到循环使用数组,对于下标的处理有些许不同。处理完最后一个元素后,将排序记录复制到原来的顺序表里。


算法分析


 时间复杂度:O(N2)


 空间复杂度:O(N)


 稳定性:稳定


     虽然减少了移动次数,但移动次数还是占大部分,移动次数大约为N2/8次,并不能避免移动操作。并且当第一个元素是最大或最小关键字时,2-路插入排序就完全失去了它的优越性。

代码实现


// C++
void twoWayInsertionSort(int array[], int length) {
    const int len = length;  // 用于定义辅助数组 
    int temp[len];  // 辅助数组 
    int first = 0;  // 指示开始位置 
    int final = 0;  // 指示最后位置 
    temp[0] = array[0];  // 加入第一个元素    
    for (int i = 1; i < length; ++i) {  // 遍历未排序序列 
        // 由于循环使用数组,以下过程都需要取余操作保证数组下标合法 
        if (array[i] < temp[first]) {  // 待插入元素比最小的元素小
            first = (first - 1 + length) % length;  // 开始位置前移 
            temp[first] = array[i];  // 插入元素 
        } else if (array[i] > temp[final]) {  // 待插入元素比最大的元素大 
            final = (final + 1 + length) % length;  // 最后位置后移 
            temp[final] = array[i];  // 插入元素
        } else {// 插入元素比最小大,比最大小
            int j = (final + 1 + length) % length;  // 用于移动元素 
            while (temp[(j - 1) % length] > array[i]) {  // 元素后移 
                temp[(j + length) % length] = temp[(j - 1 + length) % length];
                j = (j - 1 + length) % length;
            }
            temp[(j + length) % length] = array[i];  // 插入元素 
            final = (final + 1 + length) % length;  // 最后位置后移
        }
    }
    // 将排序记录复制到原来的顺序表里
    for (int k = 0; k < length; ++k) {
        array[k] = temp[(first + k) % length];
    }
}


参考


数据结构(C语言版)

————————————————

版权声明:本文为CSDN博主「Acx7」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Acx77/article/details/116850562

相关文章
|
存储 SQL 缓存
Hadoop入门(一篇就够了)
Hadoop入门(一篇就够了)
43224 6
Hadoop入门(一篇就够了)
|
算法 定位技术 C++
基本算法-回溯法(迷宫问题)
基本算法-回溯法(迷宫问题)
2010 0
|
Java 微服务 Spring
FeignClient GET请求方式无法解析对象参数
FeignClient GET请求方式无法解析对象参数,报java.lang.IllegalArgumentException: method GET must not have a request body
1625 0
|
机器人
如何查询OpenAI账户余额?ChatGPT怎么查看账户余额的方法
ChatGPT是美国OpenAI研发的聊天机器人程序,也是最近火爆全网的热门应用和话题之王。很多用户在使用openai的时候不知道如何查询OpenAI账户余额?
4169 0
|
存储 人工智能 数据管理
DeepSeek生成的图片如何导出使用
本文详解DeepSeek图片导出的三大技术路径:网页下载、API集成与本地部署,并提供元数据管理、命名规范、格式选择等最佳实践,助力开发者高效利用AI绘图成果。
926 0
|
存储 边缘计算 物联网
RFID技术是如何让仓库实现无人化管理?
RFID技术通过自动识别、实时数据交互和智能调度,实现仓库无人化管理。结合物联网与自动化设备,RFID可完成无人出入库、盘点、分拣与货位管理,提升效率、降低成本,广泛应用于电商、制造、冷链等领域,是智能仓储的核心支撑技术。
|
机器学习/深度学习 人工智能 Cloud Native
2024阿里云天池大学生竞赛正式开赛,全网招募高校最强大脑!
2024阿里云天池大学生竞赛正式开赛,全网招募高校最强大脑!
|
存储 安全 Java
Java——String类详解
String 是 Java 中的一个类,用于表示字符串,属于引用数据类型。字符串可以通过多种方式定义,如直接赋值、创建对象、传入 char 或 byte 类型数组。直接赋值会将字符串存储在串池中,复用相同的字符串以节省内存。String 类提供了丰富的方法,如比较(equals() 和 compareTo())、查找(charAt() 和 indexOf())、转换(valueOf() 和 format())、拆分(split())和截取(substring())。此外,还介绍了 StringBuilder 和 StringJoiner 类,前者用于高效拼接字符串,后者用于按指定格式拼接字符串
1765 1
Java——String类详解
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
1221 0
|
机器学习/深度学习 存储 自然语言处理
深度学习之少样本学习
少样本学习(Few-Shot Learning, FSL)是深度学习中的一个重要研究领域,其目标是在只有少量标注样本的情况下,训练出能够很好地泛化到新类别或新任务的模型。
888 2