前言

本文章是建立在 插入排序 的基础上写的,如果还有不懂 插入排序 的童鞋先停下脚步,可以先看看这里~ 直接/折半插入排序


2路插入排序解释

插入排序 中,当待插入元素需要插入的位置位于当前有序序列的首位时,我们需要进行更多的元素后移操作。过多的交换操作消耗了很多时间,因此可以着眼于减少交换次数这个方面,提高 插入排序 的效率。这就是为什么出现了 2路插入排序

2路插入排序 是对 插入排序 的进一步改进,它是通过在首尾两路同时进行插入操作,来减少插入过程中移动的次数。

那么具体如何实现呢?

我们用一个临时数组 tmp 来存储当前已排序序列,每次插入元素后有序序列的长度都会 +1。因为要进行首尾两路的插入操作,我们需要将临时数组 tmp 作为一个循环数组来处理,同时定义 frontrear 来标记当前有序序列中的头尾。这是 2路插入排序 的核心。


2路插入排序动态演示

我们需要一个循环数组 tmp,因此有了下图

我们以 [5, 3, 8, 2, 7, 4, 1, 6] 为例进行动态演示

第一次插入

第二次插入

第三次插入

第四次插入

第五次插入

第六次插入

第七次插入

第八次插入


2路插入排序核心代码

void TwoInsertSort(int a[], int n){
int *tmp = new int[n]; //临时数组
int front = 0, rear = 0; //记录当前tmp数组中最大值和最小值的位置
tmp[0] = a[0]; //初始化tmp for(int i = 1; i < n; i++){
int key = a[i];
//如果当前插入的元素比最小的元素更小
if(key < tmp[front]){
front = (front - 1 + n) % n;
tmp[front] = key;
}
//如果当前插入元素比最大元素更大
else if(key > tmp[rear]){
rear = (rear + 1 + n) % n;
tmp[rear] = key;
}
//如果在当前最小和最大之间
else{
int k = (rear + n) % n;
//将比当前插入值key大的进行后移
while(tmp[(k + n) % n] > key){
tmp[(k + 1 + n) % n] = tmp[(k + n) % n];
k = (k - 1 + n) % n;
} tmp[(k + 1 + n) % n] = key; //当前插入值放到合适位置
rear = (rear + 1 + n) % n; //更新最大值位置(有序序列长度+1)
}
} //复制临时数组到原数组中
for(int k = 0; k < n; k++)
a[k] = tmp[(front + k) % n];
delete[] tmp;
}

完整程序源代码

#include<iostream>
#include<ctime>
using namespace std; //临时数组作为循环数组操作
void TwoInsertSort(int a[], int n){
int *tmp = new int[n]; //临时数组
int front = 0, rear = 0; //记录当前tmp数组中最大值和最小值的位置
tmp[0] = a[0]; //初始化tmp for(int i = 1; i < n; i++){
int key = a[i];
//如果当前插入的元素比最小的元素更小
if(key < tmp[front]){
front = (front - 1 + n) % n;
tmp[front] = key;
}
//如果当前插入元素比最大元素更大
else if(key > tmp[rear]){
rear = (rear + 1 + n) % n;
tmp[rear] = key;
}
//如果在当前最小和最大之间
else{
int k = (rear + n) % n;
//将比当前插入值key大的进行后移
while(tmp[(k + n) % n] > key){
tmp[(k + 1 + n) % n] = tmp[(k + n) % n];
k = (k - 1 + n) % n;
} tmp[(k + 1 + n) % n] = key; //当前插入值放到合适位置
rear = (rear + 1 + n) % n; //更新最大值位置(有序序列长度+1)
}
} //复制临时数组到原数组中
for(int k = 0; k < n; k++)
a[k] = tmp[(front + k) % n];
delete[] tmp;
} void show(int *a, int n){
for(int i = 0; i < n; i++)
cout<<*(a + i)<<" ";
cout<<endl;
} main(){
int a[50];
srand((int)time(0));
int k = 0;
while(k < 50)
a[k++] = rand() % 100 + 1; //数字范围[1,100] show(a, 50); TwoInsertSort(a, 50); cout<<endl<<endl;
show(a, 50);
}

程序运行结果图

[排序算法] 2路插入排序 (C++)的更多相关文章

  1. [4] 算法之路 - 插入排序之Shell间隔与Sedgewick间隔

    题目 插入排序法由未排序的后半部前端取出一个值.插入已排序前半部的适当位置.概念简单但速度不快. 排序要加快的基本原则之中的一个: 是让后一次的排序进行时,尽量利用前一次排序后的结果,以加快排序的速度 ...

  2. Java常见排序算法之折半插入排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  3. Java常见排序算法之直接插入排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  4. 排序算法之直接插入排序Java实现

    排序算法之直接插入排序 舞蹈演示排序: 冒泡排序: http://t.cn/hrf58M 希尔排序:http://t.cn/hrosvb  选择排序:http://t.cn/hros6e  插入排序: ...

  5. 七内部排序算法汇总(插入排序、Shell排序、冒泡排序、请选择类别、、高速分拣合并排序、堆排序)

    写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的随意序列,又一次排列成一个按keyword有序的序列.因此排序掌握各种排序算法很重要. 对以下介绍的各个排序,我们假定全部排 ...

  6. 结构-行为-样式-Js排序算法之 直接插入排序

    最新因工作原因需要接触到算法,之前学习C++的时候有接触过算法,Javascript中实现算法其实也是大同小异.下面我讲下第一个实现的排序算法--直接插入排序.基本实现思路:假定一个数组中前n(n&g ...

  7. 排序算法之折半插入排序的思想以及Java实现

    1 基本思想 折半插入排序(binary insertion sort)的基本原理与直接插入排序相同,不同之处在于,确定当前记录在前面有序子数组中的位置时,直接插入排序是采用顺序查找的方法,而折半插入 ...

  8. 基本的排序算法C++实现(插入排序,选择排序,冒泡排序,归并排序,快速排序,最大堆排序,希尔排序)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/8529525.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  9. 我的Java开发学习之旅------>Java经典排序算法之二分插入排序

    一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为采用折半比较,即可得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比较, ...

  10. 八大排序算法之直接插入排序(InsertionSort)

    常见的排序算法 今天复习[直接插入排序] 核心思想:有序数组中 找位置 -- 给无序数组第一个 找位置 ` public class InsertionSort { // 核心思想:有序数组中 找位置 ...

随机推荐

  1. 踩坑之旅:配置 ROS 环境

    以下内容为本人的著作,如需要转载,请声明原文链接微信公众号「englyf」https://www.cnblogs.com/englyf/p/16660252.html 最近在学习机器人相关的导航算法, ...

  2. OpenDataV低代码平台新增组件流程

    OpenDataV计划采用子库的方式添加子组件,即每一个组件都当做一个子库,子库有自己的依赖,而项目本身的依赖只针对框架,因此每一个组件我们都当做一个子库来开发.下面我带着大家一步步详细的开发一个数字 ...

  3. CentOS7使用yum方式安装Containerd

    # 安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的 yum install -y yum-utils device-m ...

  4. echarts 饼图中间添加图片

    饼图添加图片只需要配置两部分 option = { graphic: { // 这个属性可以在饼图内部填充图片,文字等 elements: [{ type: 'image',//需要填充图片,配置im ...

  5. 谣言检测——(PSA)《Probing Spurious Correlations in Popular Event-Based Rumor Detection Benchmarks》

    论文信息 论文标题:Probing Spurious Correlations in Popular Event-Based Rumor Detection Benchmarks论文作者:Jiayin ...

  6. PAT (Basic Level) Practice 1032 挖掘机技术哪家强 分数 20

    为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛.现请你根据比赛结果统计出技术最强的那个学校. 输入格式: 输入在第 1 行给出不超过 105 的正整数 N,即参赛人数.随后 N  ...

  7. 220514 T2 画画 (二维差分)

    首先我们需要特判只涂了一种颜色的情况: (1)k=1,此时答案就是1:(2)k>1,涂的这种颜色肯定不能是第一个,答案是k-1; 对于其他正常情况,我们对于每个颜色找到一个最小的矩形(这个矩形内 ...

  8. P3998 [SHOI2013]发微博 方法记录

    原题链接 [SHOI2013]发微博 题目描述 刚开通的 SH 微博共有 \(n\) 个用户(\(1\sim n\) 标号),在这短短一个月的时间内,用户们活动频繁,共有 \(m\) 条按时间顺序的记 ...

  9. vivo互联网机器学习平台的建设与实践

    vivo 互联网产品团队 - Wang xiao 随着广告和内容等推荐场景的扩展,算法模型也在不断演进迭代中.业务的不断增长,模型的训练.产出迫切需要进行平台化管理.vivo互联网机器学习平台主要业务 ...

  10. SpringBoot 自定义注解 实现多数据源

    SpringBoot自定义注解实现多数据源 前置学习 需要了解 注解.Aop.SpringBoot整合Mybatis的使用. 数据准备 基础项目代码:https://gitee.com/J_look/ ...