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入门(一篇就够了)
37117 4
Hadoop入门(一篇就够了)
|
Java 微服务 Spring
FeignClient GET请求方式无法解析对象参数
FeignClient GET请求方式无法解析对象参数,报java.lang.IllegalArgumentException: method GET must not have a request body
1429 0
|
存储 安全 Java
Java——String类详解
String 是 Java 中的一个类,用于表示字符串,属于引用数据类型。字符串可以通过多种方式定义,如直接赋值、创建对象、传入 char 或 byte 类型数组。直接赋值会将字符串存储在串池中,复用相同的字符串以节省内存。String 类提供了丰富的方法,如比较(equals() 和 compareTo())、查找(charAt() 和 indexOf())、转换(valueOf() 和 format())、拆分(split())和截取(substring())。此外,还介绍了 StringBuilder 和 StringJoiner 类,前者用于高效拼接字符串,后者用于按指定格式拼接字符串
1584 1
Java——String类详解
|
人工智能 算法 Java
Java高级应用开发:AI赋能下的智能代码生成与优化
本文探讨了AI技术,特别是像DeepSeek这样的智能工具,在Java高级应用开发中的应用。AI在代码生成、优化、自动化测试等方面发挥重要作用,可自动生成高质量代码片段、提出优化建议并检测潜在错误,显著提升开发效率与代码质量。未来,AI将进一步推动Java开发的智能化和自动化,为开发者带来全新的开发体验。
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
972 0
|
XML Java API
List与String相互转化方法汇总
本文汇总了List与String相互转化的多种方法,包括使用`String.join()`、`StringBuilder`、Java 8的Stream API、Apache Commons Lang3的`StringUtils.join()`以及Guava的`Joiner.on()`方法实现List转String;同时介绍了使用`split()`方法、正则表达式、Apache Commons Lang3的`StringUtils.split()`及Guava的`Splitter.on()`方法实现String转List。
2572 1
List与String相互转化方法汇总
|
搜索推荐
九大排序算法时间复杂度、空间复杂度、稳定性
九大排序算法的时间复杂度、空间复杂度和稳定性,提供了对各种排序方法效率和特性的比较分析。
1543 1
|
安全 Java Android开发
【Android 逆向】APK 加壳脱壳现状 | 判断 APK 是否加壳 | APK 逆向流程
【Android 逆向】APK 加壳脱壳现状 | 判断 APK 是否加壳 | APK 逆向流程
1592 0
|
存储 算法
有向图和无向图的表示方式(邻接矩阵,邻接表)
有向图和无向图的表示方式(邻接矩阵,邻接表)
2907 0
|
芯片 内存技术
STM32速成笔记(十三)—低功耗模式
本文介绍了三种STM32低功耗模式的进入和退出方法,针对待机唤醒给出了程序设计。
1651 0
STM32速成笔记(十三)—低功耗模式

热门文章

最新文章