排序算法(2)—归并排序,快速排序

面试算法篇-合并两个有序数组 (快速排序、归并排序) package main import "fmt" func main() { arr := []int{2,1,4,3, 5, 6,7, 9} quickSort(arr, 0, len(arr)) fmt.Println(mergeSort(arr, 0, len(arr))) dealSortOrderArrs() } /** 合并两个有序数组 */ func dealSortOrderArrs() { arr1 := []int{1, 3, 5, 7} arr2 := []int. 阅读详情

一.归并排序

分治思想
思想:将两个有序的数组归并成一个有序数组。

原地归并的抽象方法

(下面两种归并方法用到):
创建一个适当大小的数组,然后将两个有序数组一个个有序的放入所创建的数组中(在此造成了额外的空间存储问题)。

方法签名:merge(array,lo,hi),将子数组a[lo...mid],a[mid+1...hi]归并,并将结果放入大a[lo...hi].

原地归并的抽象方法:

    private static int[] aux ;

    public static void mergeSort(int[] a, int lo, int mid, int hi){
        int i = lo,j = mid+1;
        for(int k = 0; k<=hi; k++)
            aux[k] = a[k] ;
        for(int k = lo; k<=hi; k++)
            if(i>mid)   
                a[k] = aux[j++];
            else if(j>hi)   
                a[k] = aux[i++];
            else if(a[j]<a[i])
                a[k] = aux[j++];
            else    
                a[k] = aux[i++];
    }

自顶向下的归并排序

此类排序使用标准的递归方式进行

实现如下:

    //消除输入依赖
    public static void sort(int[] arr)
    {
        aux = new int[arr.length];  创建的额外数组存储新的排序好的数组
        sort(arr, 0, arr.length-1);
    }

    private static void sort(int[] a, int lo, int hi)
    {
        if(hi<=lo)  return;
        int mid = lo+(hi-lo)/2;

        sort(a,lo,mid);
        sort(a,mid+1,hi);

        mergeSort(a,lo,mid,hi);  //调用原始归并的抽象方法
    }

复杂度
时间复杂度:NlogN
空间复杂度:N
对于长度为N的任意数组,需要1/2NlgN到NlgN次比较。
最多需要访问数组6NlgN次。

自底向上的归并排序

思想:先归并微型数组,然后再归并得到的子数组。(翻倍归并)

实现如下:

        public static void sortBU(int[] arr)
        {
        int N = arr.length;
        aux = new int[arr.length];
        for(int size = 1; size < N; size = size+size)
            for(int lo = 0; lo<N-size; lo += size+size)
                mergeSort(arr, lo, lo+size-1, 
                        Math.min(lo+size+size-1, N-1));     
        }  //最后一个子数组的大小,只有在数组大小是size的偶数倍的时候才会等于size(否则它会比size小).

复杂度
时间复杂度:NlogN
空间复杂度:N
对于长度为N的任意数组,需要比较次数和访问数组次数与自顶向下相同。

二.快速排序

运用最为广泛的排序算法
同样是分治算法思想
思想:
根据切分元素,把数组分为两部分,左边小于(大于)切分元素,右边大于(小于)切分元素。
实现如下:

    private static void quickSort(int[] a, int lo,int hi)
    {
        if(lo>=hi) return;
        //partition()是切分方法
        int j = partition(a,lo,hi);
        quickSort(a,lo,j-1);
        quickSort(a,j+1,hi);        
    }

根据切分方法,可以将快速排序分为两类:
常规的切分 and 三向切分

1. 常规切分

    private static int partition(int[] a,int lo, int hi)
    {
        int i = lo,j = hi+1;
        int v = a[lo];
        while(true)
        {
            while(a[++i]<v)
                if(i == hi) break;
            while(v<a[--j]) 
                if(j == lo) break;
            if(i>=j) break;
            exch(a,i,j);
        }
        exch(a,lo,j);
        return j;
    }

复杂度:
时间复杂度:NlgN
空间复杂度:lgN
对于长度为N的无重复数组排序,平均需要~2NlnN次比较,一级1/6的交换。
最多需要N^2次比较,但那时可以用随机打乱数组来防止这种最坏情况。

2. 三向切分

常规切分的改进
对于存在大量相同数据的排序尤为有效快速
实现:

    private static void quick3waySort(int[] a, int lo, int hi){
        if(hi<=lo)
            return;
        int lt = lo,i = lo+1, gt = hi;
        int v = a[lo];
        while(i<=gt)
        {
            int flag = a[i] - v;
            //下面判断决定由小到大.
            if(flag<0)
                exch(a,lt++,i++);  //交换a[lt]和a[i]位置.
            else if(flag>0)
                exch(a,i,gt--);
            else
                i++;
        }
        quick3waySort(a, lo, lt-1);
        quick3waySort(a, gt+1, hi);
    }

复杂度:
时间复杂度:N~NlogN
空间复杂度:lgN
对于大小为N的数组,需要~(2ln2)NH次比较。H为由主键值出现频率定义的香农信息量。
它是对于包含大量重复数据的最优排序算法。

归并算法和快速算法比较
快速排序特点:原地排序,只需要一个很小的辅助栈,空间复杂度仅为lgN。
但是相对于归并排序此类的稳定排序,要更注意避免低劣性能的产生,经常会导致在实际运用中性能只有平方级别。

参照算法第四版


内容原创,转载请注明出处
【C语言】利用指针变量作函数形参,交换两数(2.0版本 ×××)| C语言面试:什么是排序算法?请给出使用C语言实现的排序算法 | 冒泡排序,插入排序,选择排序,归并排序,快速排序 代码如下 首先是之前1.0版本,在这里:【C语言】利用指针变量作函数参数,交换两数 那么,接下来是新的2.0版本,相比1.0版本,本次修改主要是更改了一个小的地方,见代码: //version 2.0:交换两数,能实现吗? (可以实现√) #include <stdio.h> void Swap(int *x,int *y); int main(){ int a,b; printf("Please enter a,b: "); scanf("%d,%d",&a,&b); 阅读详情

相关推荐

告别二极管发热!手把手教你用MOS管搭建同步整流电路(附死区时间设置避坑指南)

本文详细介绍了如何利用MOS管搭建同步整流电路(SR),以替代传统二极管,显著降低导通损耗和发热问题。内容涵盖自驱动方案的选择、关键元件参数计算、PCB布局要点及死区时间设置技巧,帮助工程师优化电源设计效率。

weixin_29540599的博客 455

用信息论理解排序算法

信息论 信息是个很抽象的概念。人们常常说信息很多,或者信息较少,但却很难说清楚信息到底有多少。比如一本五十万字的中文书到底有多少信息量。直到1948年,香农提出了“信息熵”的概念,才解决了对信息的量化度量问题。(摘自百度百科) 一条信息的信息量大小和它的不确定性有直接的关系。比如说,我们要搞清楚一件非常非常不确定的事,或是我们一无所知的事情,就需要了解大量的信息。相反,如果我们对某件事已经有了...

优快云博客 1309

从‘静态拍照’到‘动态录像’:用Malmquist指数讲好你的效率变化故事(附Stata/R代码)

本文深入探讨了如何利用Malmquist指数构建动态效率分析框架,从静态数据到动态叙事的转变。通过分解技术效率变化(EC)和技术进步(TC),结合Stata/R代码实现四种动态可视化方法,帮助研究者更直观地展示效率变化的动态特征。文章还提供了诊断性叙事结构和比较叙事技巧,助力决策者理解效率提升的来源与趋势。

weixin_32678995的博客 605

【数据结构】Java实现各类经典排序算法——快速排序、归并排序

快速排序和归并排序,两种算法都是分治法的经典表现,递归形式写起来也水到渠成。一、快速排序    快速排序的递归程序主要分三部分:驱动程序、递归主程序、中枢点(pivot)选取。前两部分用来实现快排的中心思想,把中枢点放到某个位置,使得该位置左侧元素均不大于中枢元素,右侧元素均不小于右侧元素。算法属于就地排序,通过交换元素在数组中的位置来进行。    中枢点的选取,主要会在原始数组不完全随机的情况下...

ab842022884的博客 373

PotPlayer播放4K HDR电影时,如何正确设置LAV解码器与MadVR渲染器避免色彩失真?

本文详细介绍了如何在PotPlayer中正确配置LAV解码器与MadVR渲染器,以解决播放4K HDR电影时的色彩失真问题。从组件安装、参数设置到显卡协同配置,提供了一套完整的端到端解决方案,帮助影音爱好者获得最佳的视觉体验。

weixin_28732953的博客 442

QT的温湿度显示系统

大家好,这里是石侃侃的博客,欢迎前来讨论这篇文章介绍的是DHT11在2440上的基于Qt5.6的应用基于单片机系统的温湿度监测系统构成框图如图2-1所示。图2-1 系统构成框图该系统采用单片机s3c2440作为了本设计的核心元件。利用LCD作为了显示器件,利用触摸屏作为用户界面输入设备,第一行显示当前实时的温度,湿度,第二行依次显示历史时刻最高的温度值,最高的湿度值。第三行是一个文本框,记录了程...

zxpcus的博客 1万+

Java快速排序和归并排序区别和实现

快速排序与归并排序的概念:        快速排序(Quicksort)是对冒泡排序的一种改进。          快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。      ...

Jet_Green的博客 3035

Pluto SDR新手避坑指南:从环境配置到第一个MATLAB收发程序(附完整代码)

本文为Pluto SDR新手提供全面的避坑指南,从硬件连接到MATLAB环境配置,再到第一个信号收发程序的实现。详细介绍了驱动安装、常见问题排查以及关键参数设置,帮助用户快速上手软件定义无线电(SDR)技术,并附有完整代码示例。

weixin_33168937的博客 325

排序算法二:归并排序与快速排序

文章目录比较三种排序方法一、选择排序二、冒泡排序三、插入排序 比较三种排序方法 排序方法 时间复杂度 最佳情况 额外空间复杂度 是否稳定 归并排序(Merge Sort) O(nlogn)O(nlogn) O(nlogn) O(n2)O(n^{2}) O(n2) T(1)T(1) T(1) 否 快速排序(Quick Sort) O(nlogn)O(nlogn) O(nlogn)...

zealband的博客 286

Zabbix安装与部署 系统环境:centos7.0

Zabbix安装与部署 系统环境:centos7.0

weixin_42485027的博客 2600

YOLO11改进|卷积篇|引入SPDConv

YOLO11中添加SPDConv卷积

A1983Z的博客 3698

03_2排序算法:快速排序、归并排序

开始系统学习算法啦!为后面力扣和蓝桥杯的刷题做准备!这个专栏将记录自己学习算法是的笔记,包括概念,算法运行过程,以及代码实现,希望能给大家带来帮助,感兴趣的小伙伴欢迎评论区留言或者私信博主哦!今天更新的是《03_2排序算法:快速排序、归并排序》

weixin_63866037的博客 653

【虚幻引擎UE】UE5 四步骤实现AI漫游与对话行为(含工程源码)

【虚幻引擎UE】UE5 四步骤实现AI漫游与对话行为(含工程源码)

灵境引路人 3227

[C++]数据结构:排序算法Part2----快速排序、归并排序、箱子排序、基数排序

接上篇博文: [C++]数据结构:排序算法Part1----冒泡排序、选择排序、插入排序、堆排序 5.快速排序: 快速排序的核心思想是分而治之算法。所谓的分而治之,简单来说就是把复杂问题分成几个子问题,然后分别解决小问题,最后再将解组合起来,得到原问题的解。 那么分而治之如何应用到排序算法中呢? 在快速排序中,n个元素被分成了了三段。左端left,右端right,和中段m

汪海的实验室 4011

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

排序算法分析2--归并排序和快速排序

排序算法分析2--归并排序和快速排序0.综述1.归并排序原理分析2.归并排序代码实现 0.综述 在前面一节中,我们分析了三种时间复杂度为O(n²)的排序算法–冒泡排序、插入排序、选择排序,由于这三种算法的时间复杂度较高,因而适用于 小规模数据的排序。而今天分析的两种排序算法适用于大规模数据的排序,因为它们的时间复杂度都是O(nlogn)。它们分别是归并排序和快速排序。 1.归并排序原理分析 归并排...

Hundreays 690

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

排序算法2(归并排序,快速排序)

归并排序的原理和实现 对于归并排序,重点是要理解分治算法和递归处理的思想。如果要排序一个数组,那么我们首先要把数组从中间分成两段,然后对这两段分别进行排序,最后将排序好的两部分进行性别,这样整个数组就是一个有序的了。首先看一个图进行理解。 归并排序使用的是分治算法的思想。分治,就是分而治之,将一个大问题分解成一个小问题来进行解决。分治算法的思想与之前提到的递归很是相似,分治算法就是通过递归来进行实现的,分治是一种解决问题的思想,递归是一种编程技巧。 下面来看看代码 class Test{ ..

weixin_46272350的博客 478

排序算法2-快速排序、归并排序

快速排序的思路是这样的: 假如我从数组中挑出一个数(通常选为第一个数),那么我总可以利用这个数把数组分为两部分:大于这个数的部分和小于这个数的部分。然后对于这个两部分,分别重复前面的步骤,直到每一部分都只剩下2个数为止,我们可以比较出来。一看就知道是一个递归的程序,但是程序的难点在于:如何从用一个数把数组分为两个部分呢?当然。你大可以用一个比较笨的办法:搞一个临时数组,然后把比较的结果放在数组里

thefutureisour的专栏 1000

排序算法2(快速排序,归并排序,基数排序)

排序算法2 目录排序算法2归并排序主要思想代码快速排序主要思想代码基数排序主要思想代码所有代码 归并排序 主要思想 利用分治策略将数组切分至只剩一个元素,再按顺序合并到辅助数组中,最后将数据复制到待排序的数组即可。 代码 static void MergeSort(int[] arr, int left, int right, int[] temp) { if (left < right) { int mid = (left + right) / 2; //中间索引

RoySummy的博客 234

【C语言】几种经典的排序算法(2)/快速排序,归并排序

分治法 | 快速排序,归并排序 | 原理及代码实现

dancehole的博客 500

排序算法(2)—— 归并排序、快速排序

1 归并排序

一角残叶的博客 392

常用的排序算法性能分析(2)—— 归并排序、快速排序

归并排序要将一个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。自顶向下的归并排序归并排序应用了分治的思想,如果它能将两个子数组排序,它就能够通过归并两个子数组来将整个数组排序。命题F:对于长度为 N 的任意数组,自顶向下的归并排序需要 (1/2)*NlgN 到 NlgN 次比较。命题G:对于长度为 N 的人艺术组,自顶向下的归并排序最多需要访问数组 6NlgN 次。因为递归会

HeatDeath的博客 1488

排序算法(2)-时间复杂度为O(nlogn)的排序算法(归并排序、快速排序)

1、归并排序 归并排序算法的核心思想:把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。具体过程如下图所示: 归并排序使用的就是分治思想。分治,顾名思义,就是分而治之,将一个大问题分解成小的子问题来解决。小的子问题解决了,大问题也就解决了。分治算法一般都是用递归来实现的,所以归并排序我们首先考虑用递归实现。 写递归代码的技巧就是,分析得出...

qq_17621363的博客 2643

重拾算法系列之排序算法2(堆排序,归并排序,快速排序)

1.堆排序 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法。 它的特点是:在排序的过程中,将array[0,…,n-1]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲节点和孩子节点之间的内在关系,在当前无序区中选择关键字最大(最小)的元素。 堆 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等...

程序员 378

高级排序算法【2】--快速排序、归并排序、堆排序

4、快速排序 从数列中挑出一个元素,称为基准;  重新排列数列,所有元素比基准小的摆放在基准前面,所有元素比基准大的摆在基准后面;  在这个分区结束之后,该基准就位于数列的中间位置;  递归地对基准左右两边的数列进行排序。 快速排序代码——第一步 def quick_sort(data, left, right): if left &lt; right: mid...

不曾走远的博客 383

数据结构—排序算法2(归并排序与快速排序)

归并排序、快速排序算法的思路及代码实现,快速排序的优化

weixin_68908154的博客 236

排序算法总结(2):快速排序,归并排序,堆排序

快速排序,归并排序,堆排序

m0_64568089的博客 356
上一篇: 排序算法(1)—选择,插入,希尔
下一篇: 排序算法(3)—优先队列,堆排序
luoz_python
博客等级 码龄10年 57粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值