码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 对分段有序的数组排序(前、后部分分别递增)


    文章目录

    • 1 题目
    • 2 思路
      • 2.1 思路1(直接插入法)
      • 2.2 思路2(归并)
    • 3 实现
      • 3.1 思路1
      • 3.2 思路2

    1 题目

    设m+n个元素顺序存放在数组A[1…m+n]中,前m个元素递增有序,后n个元素递增有序,试设计一个在时间和空间两方面都尽可能高效的算法,使得整个顺序表递增有序。

    2 思路

    2.1 思路1(直接插入法)

    把数组A看作是两个长度分别为m和n的有序表L1、L2,把L2的每个元素依次插入到L1中的合适位置即可。

    • 1,取表L2中第一个元素A[m+1],暂存为tmp,把tmp插入到L1中合适的位置(L[i]
    • 2,重复操作1,把A[m+2]、A[m+3]…A[m+n]依次插入到L1中,直至整个数组有序。

    时间复杂度:O(mn)
    空间复杂度:O(1)

    2.2 思路2(归并)

    • 1,把数组A前m个元素和后n个元素视为两个归并段L1、L2,增加一个辅助数组B[1…m+n]存储临时归并的结果。设k1、k2、k3分别指向L1,L2的首位和数组B的下一个结果位置。
    • 2,当k1<=m并且k2<=m+n时,执行3,否则执行4:
      • 3,比较两个归并段指针所指元素的大小,若A[k1]
      • 4,若k1>m,则把第二归并段剩余的元素复制到数组B末尾;若k2>m+n,则把第一个归并段剩余的元素复制到数组B,最后把数组B复制到数组A。

    时间复杂度:O(m+n)
    空间复杂度:O(m+n)

    3 实现

    3.1 思路1

    #include
    
    void solution1(int *A, int m, int n){
        int tmp, j;
        for(int i = m+1; i <= m+n;i++){
            tmp = A[i];//暂存元素,防止后面移动元素时,元素丢失
            for(j = i-1;j > 0 && A[j] > tmp;j--)//当L1中的元素大于tmp时,就是插入tmp的位置
                A[j+1] = A[j];
            A[j+1] = tmp;
        }
    }
    
    void print(int* A, int n){
        for(int i = 0;i < n;i++)
        {
            printf("%d ", A[i]);
        }
        printf("\n");
    }
    
    int main(){
        int A[] = {0, 1,4,7,2,3,6};
        solution(A, 3, 3);
        print(A, sizeof(A)/sizeof(A[0]));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3.2 思路2

    #include
    
    void solution2(int *A, int m, int n){
        int B[m+n+1];
        int k1 = 1, k2 = m+1, k3 = 1;//三个指针
        while(k1<=m && k2<= m+ n){//归并,把较小的元素复制到B中
            if(A[k1] < A[k2]) B[k3++] = A[k1++];
            else B[k3++] = A[k2++];
        }
        if(k1 > m) //把没有比较完的归并段的剩余元素复制到B中
            while(k2 <= m+n) B[k3++] = A[k2++];
        if(k2 > m+n)
            while(k1 <= m) B[k3++] = A[k1++];
        for(int i = 1;i <= m+n;i++){//把数组B复制到数组A中
            A[i] = B[i];
        }
    } 
    
    void print(int* A, int n){
        for(int i = 0;i < n;i++)
        {
            printf("%d ", A[i]);
        }
        printf("\n");
    }
    
    int main(){
        int A[] = {0, 1,4,7,2,3,6};
        solution2(A, 3, 3);
        print(A, sizeof(A)/sizeof(A[0]));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    谷歌浏览器无法使用翻译功能的解决方案,谷歌浏览器无法翻译怎么办?谷歌浏览器右键翻译失效了?
    传统分拣弊端明显,AI机器视觉赋能物流行业包裹分类产线数智化升级
    Scala Iterator(迭代器)
    91、Redis - 事务 与 订阅-发布 相关的命令 及 演示
    Seata源码研读#01-详解配置管理机制
    C系统编程:从零手搓一个shell
    软件测试要达到一个什么水平才能找到一份9K的工作?
    微信小程序开发学习文档(万字总结,一篇搞定前端开发)
    Java-Day16 日期和时间相关API、数字格式化相关API
    文件分割与合并
  • 原文地址:https://blog.csdn.net/qq_33375598/article/details/132462444
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号