算法 - 排序 - 二路归并排序 (Two-way Merge Sort)

【二路归并算法】 【二路归并算法】 两路合并排序是时间复杂度为O(n* log2 n)的排序方法。 基本思想:将有n个元素的序列看成是n个长度为1的有序序列,然后两两合并序列,得到 n/2个长度为2或1的有序序列,然后在进行两两合并,直到得到一个长度为n的有序序列。 (1)eg: #include<stdio.h> #define MAXSIZE 5 void Merging(int *list1, int list1Size, int *list2, int list2Size) { int i, j, 阅读详情

算法 - 排序 - 二路归并排序 (Two-way Merge Sort)

返回分类:全部文章 >> 基础知识

返回上级:算法 - 查找与排序 (Searching and Sorting)

本文将用C++实现插入二路归并排序算法。

在查看本文之前,需要一些程序语言的基础。

所有排序方法中,统一使用如下库与结构:

// Author: https://blog.youkuaiyun.com/DarkRabbit
// Sorted Dependency

#pragma once

#include <algorithm>
#include <vector>
#include <stack>

template<typename T>
struct MyItem
{
    int key;
    T data;

    MyItem(){ key = -1; }
    MyItem(const int& k) : key(k){ }
    MyItem(const int& k, const T& d) : key(k), data(d){ }
};

数据表统一使用了std::vector<MyItem<T>>,如果你使用静态数组MyItem<T>[]或指针数组MyItem<T>*,那么还要传入元素数量size。

示例所用数据:

  • 元素数量为size = 15;

  • 关键字为key = { 123, 122, 565, 22, 3, 64, 73, 44, 287, 6, 9, 83, 25, 42, 13 }。



1 二路归并排序简述 (Introduction)

归并排序,是将两个以上的有序表组合成一个新的有序表。

二路归并基本思想是将数据表的每个元素看成是只有一个元素的有序数据表,然后两两合并,重复过程,直到合并成一个数据表。

其详细过程:

key = { 123, 122, 565, 22, 3, 64, 73, 44, 287, 6, 9, 83, 25, 42, 13 }

两路归并排序,首先将每个元素当成一个有序数据表
     0: {123}{122}{565}{ 22}{  3}{ 64}{ 73}{ 44}{287}{  6}{  9}{ 83}{ 25}{ 42}{ 13}
左子表长度:1,两两合并
     1: {122, 123}{565,  22}{  3,  64}{ 73,  44}{287,   6}{  9,  83}{ 25,  42}{ 13}
     2: {122, 123}{ 22, 565}{  3,  64}{ 73,  44}{287,   6}{  9,  83}{ 25,  42}{ 13}
     3: {122, 123}{ 22, 565}{  3,  64}{ 73,  44}{287,   6}{  9,  83}{ 25,  42}{ 13}
     4: {122, 123}{ 22, 565}{  3,  64}{ 44,  73}{287,   6}{  9,  83}{ 25,  42}{ 13}
     5: {122, 123}{ 22, 565}{  3,  64}{ 44,  73}{  6, 287}{  9,  83}{ 25,  42}{ 13}
     6: {122, 123}{ 22, 565}{  3,  64}{ 44,  73}{  6, 287}{  9,  83}{ 25,  42}{ 13}
     7: {122, 123}{ 22, 565}{  3,  64}{ 44,  73}{  6, 287}{  9,  83}{ 25,  42}{ 13}
左子表子表长度:2,两两合并
     8: { 22, 122, 123, 565}{  3,  64,  44,  73}{  6, 287,   9,  83}{ 25,  42,  13}
     9: { 22, 122, 123, 565}{  3,  44,  64,  73}{  6, 287,   9,  83}{ 25,  42,  13}
    10: { 22, 122, 123, 565}{  3,  44,  64,  73}{  6,   9,  83, 287}{ 25,  42,  13}
    11: { 22, 122, 123, 565}{  3,  44,  64,  73}{  6,   9,  83, 287}{ 13,  25,  42}
左子表子表长度:4,两两合并
    12: {  3,  22,  44,  64,  73, 122, 123, 565}{  6,   9,  83, 287,  13,  25,  42}
    13: {  3,  22,  44,  64,  73, 122, 123, 565}{  6,   9,  13,  25,  42,  83, 287}
左子表长度:8,两两合并
    14: {  3,   6,   9,  13,  22,  25,  42,  44,  64,  73,  83, 122, 123, 287, 565}


2 性能分析 (Performance Analysis)

排序方法最好时间最差时间平均时间辅助空间稳定性
归并排序O(n log2n)O(n log2n)O(n log2n)O(n)稳定

3 简单选择排序C++代码 (Selection Sort C++ Code)

// Author: https://blog.youkuaiyun.com/DarkRabbit
// Two-way Merge Sort

// 合并子表
// params:
//      list:       整表
//      first:      第一个表开始下标
//      second:     第二个表开始下标
//      firstSize:  第一个子表的长度
template<typename T>
void TwowayMerge(std::vector<MyItem<T>>& list,
                 int first,
                 int second,
                 int firstSize)
{
    int size = list.size(); // 表长

    int secondSize = firstSize; // 第二个子表长度
    if (second + firstSize > size) // 如果第二个子表超出范围
    {
        secondSize = size - second; // 重新计算长度
    }

    std::vector<MyItem<T>> tmpList(firstSize + secondSize); // 合并后的临时表
    int left = 0;
    int right = 0;
    while (left < firstSize && right < secondSize) // 依次比较两个子表关键字
    {
        if (list[first + left].key <= list[second + right].key)
        {
            tmpList[left + right] = list[first + left]; // 将第一子表元素添加到临时表
            left++;
        }
        else
        {
            tmpList[left + right] = list[second + right]; // 将第二子表元素添加到临时表
            right++;
        }
    }

    while (left < firstSize) // 第一子表还有元素,且全比临时表元素大
    {
        tmpList[left + right] = list[first + left];
        left++;
    }

    while (right < secondSize) // 第二子表还有元素,且全比临时表元素大
    {
        tmpList[left + right] = list[second + right];
        right++;
    }

    for (int i = 0; i < tmpList.size(); i++) // 将临时表元素放回原表
    {
        list[first + i] = tmpList[i];
    }
    tmpList.clear();
}

template<typename T>
void TwowayMergeSort(std::vector<MyItem<T>>& list)
{
    int size = list.size();
    int firstSize = 1; // 首次子表长度为1,即每个元素为一个表
    while (firstSize < size)
    {
        // 两两比较子表
        for (int i = 0; i < size - firstSize; i += firstSize * 2)
        {
            TwowayMerge(list, i, i + firstSize, firstSize);
        }

        firstSize *= 2; // 更新子表长度
    }

}

逆概率加权法(Inverse Probability Weighting, IPW)的原理及R实现 逆概率加权(IPW)是一种用于解释由于非随机选择观测值或人群信息的非随机缺失而造成的缺失和选择偏差的方法。原理:这种方法可以通过对观察值的加权来修正分析,使其具有被选中的概率。IPW是基于这样一个假设,即整个研究人群都有可以预测纳入概率(非遗漏)的个体信息,因此,在考虑到这些信息后,我们可以仅从非遗漏的观察值开始对整个目标人群进行推断。计算的程序如下:首先,我们考虑整个研究人群,用逻辑回归模型计算非失访信息的概率,其中响应是非失访,协变量是其可能的预测因素。每个受试者的权重是由预测概率的倒数给出的。然后使用 阅读详情

相关推荐

我用WorkBuddy“克隆“了一个我,从此每句话像我自己说的

各位,做这件事花了多长时间?准备样本可能要半小时,提炼风格十分钟,保存固化再花十分钟。加起来不到一个小时。但这一个小时之后呢?你就拥有了一个"永远在线的文字替身"。以后写口播稿,打开WorkBuddy跟它说;写课程逐字稿,跟它说;写公众号文章,也跟它说。写出来的东西,你的学员一看——“嘿,这不就是翟猛老师说的嘛。说到这儿,可能有人会问:老师,我的风格有那么重要吗?AI写的不都挺好的吗?各位你想想看,你为什么愿意听某个老师的课?不只是因为他讲的内容好,更是因为你喜欢他讲话的方式。

weixin_39284145的博客 822

字符串查询算法

glibc中的strstr的two-way算法,two-way算法主要依据Critical Factorization理论。 要理解Critical Factorization理论,先要理解字符串的period:     设w是定义在字符集A上的非空字符串。设|w|是w的长度。存在正整数p,对所有满足模p同余的     非负整数i,j (i,j         w[i] = w[j]

ang639 2792

MT5交易软件系统源码

Manager配置的功能及权限:管理客户、开户,销户、入金、信用额度、修改定单、人工交易报表、设定点差、强制平仓、修改密码,设定持仓交割单或挂单小止盈止损点数;26、修改价格 27、更改K线图历史价格 28、同步历史数据;2、系统设置 3、交易管理 4、交易柜台 5、价格更改 6、多台服。务器联机 7、恢复交易历史 8、数据源调整 9、备份服务调整 10、交易市场设定 11、交易单更改 12、平台时间设定(全世界) 13、可添加商品;15、设置商品利息;独立主机(服务器、VPS、VM)

tutujunjun的博客 904

字符串匹配:two-way算法

<br />字符串匹配是一维模式匹配的特例;是查找在字符串text中是否存在字符串pattern的一种操作。<br /> 字符串匹配的形式化定义大体如下:<br />     设字符集合A。text和pattern是定义在字符集合A上的两个字符串;设|text|是text的长度,<br />     |pattern|是pattern的长度。找到非负整数pos(pos < |text|-|pattern|),使等式:<br />         pattern[i] = text[pos+i]   

leeshuheng的专栏 4795

初识Classic AUTOSAR开发工具链

在过去,软件和硬件之间具有很强的耦合性,阻碍了软件组件在不同硬件平台上的可移植性和重用性。而AUTOSAR作为汽车电子行业的标准,提供标准的软件接口定义,工程师可以根据需求将软件组件分配到汽车的ECU中,实现标准软件组件的可重用性。

怿星科技的博客 8095

STM32入门教程:人脸识别

STM32CubeMX配置 打开STM32CubeMX,创建一个新的工程,并选择你使用的STM32系列和具体型号。根据摄像头模块的规格,将摄像头的输出引脚连接到相应的STM32引脚上。人脸识别是一种非常常见的人工智能应用,它可以通过摄像头捕捉到的图像,识别出图像中的人脸并进行相关的分析和处理。在本教程中,我们将使用STM32开发板和相关传感器,通过指导你搭建一个基于STM32的简单人脸识别系统,并编写相应的代码来实现该功能。另外,为了达到更好的人脸识别效果,可能需要使用更高性能的处理器和更复杂的算法。

吃不胖. 374

数据结构与算法:二路归并排序(合并排序)

数据结构与算法:二路归并排序/合并排序概述:图解: 概述: List item 图解: 假设我们有这样一组数据 A[9] = {4,3,6,7,9,1,2},他在内存中这样排序

weixin_42585456的博客 4万+

【ChangeCLIP】Remote sensing change detection with multimodal vision-language representation learning

ChangeCLIP论文及代码使用详解。持续更新变化检测最新论文,欢迎订阅本专栏。

向上生长的程序媛的博客 1338

基础班 strStr算法实现

hash function 把一个string对应到某一个位置 ,然后下次他来的时候还是这个位置,可以检查看是否存在于整个数组当中 字符转换成整数 0-255 一个字节 可以直接乘 出来就是整数 语言会自动转换 乘以任何数字都可以 这里31是常用的,基数num 效率最高,效果最好 这个结果可能很大 超出证书的范围 取模 模2出来一半是0一半是1 不够比较 除以一个比较大的数...

qq_40647378的博客 244

【人工智能】《Deep Dive into LLMs like ChatGPT 》—— Andrej Karpathy 第三阶段:强化学习(Reinforcement Learning, RL)

摘要:强化学习(RL)阶段通过让模型自主生成并验证答案,突破SFT阶段的模仿局限,使其在数学、代码等领域形成独特的推理路径。RL流程包括批量生成解答、自动批改筛选正确路径,并采用PPO/GRPO算法优化模型。模型会自发涌现自我检查、回滚等策略,显著提升正确率(如AIME竞赛准确率从15%升至56%)。与SFT模型相比,RL模型具备主动链式思维、验算能力,响应时间更长但效果更优,形成真正的“思考模型”。三阶段对比显示,RL通过可验证题的对错奖励机制,赋予模型超越人类范式的推理能力。

奶爸的编程之路,也就一周冷个三天 150

基于simulink创建一个针对双馈异步风力发电机并网运行的仿真模型

摘要:本文详细介绍了基于Simulink的双馈异步风力发电机(DFIG)并网运行仿真建模方法。系统包含风速输入、风力机、双馈发电机、电力电子变换器、控制器和并网接口等模块,通过8个步骤完整呈现了建模流程,包括风速模拟、机械功率计算、发电机特性建模、变流器控制策略设计等关键环节。仿真可评估系统在不同风速条件下的动态响应、最大功率跟踪能力和发电效率,为风力发电系统的优化设计提供有效验证手段。模型可根据实际需求扩展环境因素和电网交互等细节,提高仿真精度。

amy_mhd的博客 335

排序算法——归并、快排

归并、快排归并排序快速排序 归并排序 归并排序的思想是分治法,如果想要将一个数组排序,那么将这个数组分为左区间和右区间,左区间一定是小于右区间的,再将左区间继续划分,右区间也继续划分。。。 最后将排好序的数组全都归并起来,这样听起来像是从上向下划分,其实归并排序主要是是从下向上,合并的过程。 先将单个元素的数组归并为两个元素的有序数组 再将包含两个元素的有序数组归并为四个元素的有序数组 … 最后...

u014792301的博客 881

Open-Sora代码详细解读(2):时空3D VAE

目前开源的DiT视频生成模型不是很多,Open-Sora是开发者生态最好的一个,涵盖了DiT、时空DiT、3D VAE、Rectified Flow、因果卷积等Diffusion视频生成的经典知识点。本篇博客从Open-Sora的代码出发,深入解读背后的原理。

沉迷单车的追风少年 2054

二路归并排序(Two-way Merge Sort)

* 二 路 归 并 排 序(Two-way Merge Sort)*归并关键思想时间复杂度空间复杂度稳定性 √实例:[15 18 25 60 18 75 100 23 64 8 150](Java) 归并 将两个或两个以上的有序序列合并成一个新的有序序列。 关键思想 首先将整个序列看成是nnn个有序子序列,每一个子序列的长度是111,然后两两归并,获得n/2n/2n/2个长度是222的有序子...

JM_1013的博客 1489

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

实现归并排序的openmp程序_算法随笔1 - 归并排序的进化史 - Part1 Natural Merge Sort...

系列文章的导航链接:张浩驰:《趣味算法》专栏所有文章分类 - 导航​zhuanlan.zhihu.com作者: @张靖昆编辑: @张浩驰一、前言距离上次更新过去了10天时间,主要是这段时间太忙了,身体还不舒服,因此就断更了。这里我开一个随笔系列,是将一些有意思的算法分享给大家,这里会涉及到我所读的,我非常感兴趣的论文。这10天,我读了关于归并排序算法的进化史,大家可能都听过非常著名的TimSort...

weixin_39710991的博客 314

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

排序算法之二路归并排序

排序算法之二分归并排序 上学期的数据结构已经讲过归并排序了,但是上学期太懒了,所以没有动手把代码写出来2333。今天在写算法设计的第二章作业,讲的是分治思想。而归并排序的思想就是分治,便乘此机会动手实际写一下归并排序。 大学入学以来好吃懒做,算法方面根本没有什么进步,排序还只会高中学的冒泡排序和选择排序…在之后的学习生活中,一定要重视算法,动手实操并真正理解算法。 以下是我写的二分归并排序的代码 #include <iostream> #include <cstdlib>

wuuconix's blog 636

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

【华科复试】【贪心算法】最优二路归并树&二路归并排序

二路归并模式:每次仅作两个文件的归并;当有多个文件时,采用两两归并的模式,最终得到一个完整的记录文件。 二元归并树:二路归并模式的归并过程可以用一个二元树的形式描述,称之为二元归并树。 贪心求解: 任意两个文件的归并所需的元素移动次数与这两个文件的长度之和成正比。度量规则:每次选择需要移动次数最少的两个集合进行归并。处理规则:每次选择长度最小的两个文件进行归并。 为得到归并树根结点表示的归并文件...

weixin_44225940的博客 2625

合并排序——二路合并排序

什么是合并排序:合并排序就是将两个或多个有序表合并成一个有序表,将两个有序表合并成一个有序表称为二路合并算法描述 :二路合并排序的基本思想是:对于两个有序表合并,初始时, 把含有n个结点的待排序序列看作有n个长度为1的有序子表所组成,将它们依次两两合并,得到长度为2的若干有序子表,再对这些子表进行两两合并,一直重复到长度为n,排序完成。合并排序过程:初始序列:二路合并排序需...

weixin_33875839的博客 772

memchr源码解析:Rabin-Karp与Two-Way算法的巧妙结合

memchr是一个为Rust优化的字符串搜索库,它巧妙结合了Rabin-Karp与Two-Way算法,提供高效的子字符串查找功能。本文将深入解析这两种算法在memchr中的实现原理和协同工作机制,帮助开发者理解如何在实际项目中应用这些经典算法解决性能瓶颈。 ## 为什么选择Rabin-Karp算法? Rabin-Karp算法通过计算 needle 的哈希值并在 haystack 中滚动计算窗口

gitblog_00499的博客 1064

归并排序算法

十大经典排序算法之归并排序详解,对归并排序进行原理分析、复杂度分析,列举归并排序的优缺点,内附有C语言描述的实现代码,并对代码进行了全面解析。

先写一个BUG吧 1420

排序算法7--二路归并排序(C++完整代码实现)

#include <iostream> using namespace std; //归并函数 void merge(int *R, int low, int high) { int mid = (low + high) / 2; //需要定义一个额外的数组,临时存放归并的结果 int maxSize = high - low + 1; int temp[maxSize]; int k = 0; int i = low; int j = mid + 1; while (i &l.

weixin_45482422的博客 3761

常见的五类排序算法图解和实现(归并类:二路归并排序)

归并类的排序算法 归并:将两个或两个以上的有序表组合成一个新的有序表。 内部排序中,通常采用的是 2-路归并排序。即:将两个位置相邻的记录有序子序列归并为一个记录有序的序列。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 图解如下 看成是 n 个有序的子序列(长度为 1),然后两两归并。 ...

diaoyanqin5061的博客 1292

快速排序和两路合并排序速度_经典排序算法——快速排序、归并排序、堆排序...

“快速排序、归并排序、堆排序”01—快速排序算法思想快排(quicksort)过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在简单排序基础上的递归分治法。算法...

weixin_42524792的博客 642

2-路插入排序(2-way Insertion Sort)的C语言实现

原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 2-路插入排序(2-way Insertion Sort)的基本思想: 比fisrt小的元素,插入first前面; 比final大的元素,插入final后面, 比fisrt大且比final小的元素插中间 演示实例: C语言实...

weixin_30362801的博客 317

二路归并排序及时间复杂度分析

二路归并排序C++代码及详细分析

weixin_44870613的博客 4389

算法整理:内排序篇-二路归并排序&线性时间排序

本文主要介绍了二路归并排序和一些线性时间排序(计数排序、基数排序和桶排序)。

ReDreamme的博客 1870
上一篇: 算法 - 排序 - 选择排序 (Selection Sort)
下一篇: 数据结构 - 图 I (Graph I)
沙沙的兔子
博客等级 码龄17年 359粉丝 135原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值