首页 后端开发 php教程 排序算法—归并排序【附代码】

排序算法—归并排序【附代码】

Aug 22, 2019 pm 05:06 PM
排序算法

排序算法—归并排序【附代码】

什么是归并排序?

  归并排序简单来讲,就是将两个有序的序列整合到一起。

推荐教程:PHP视频教程

如何将两个有序的序列整合到一起呢?

  那么我们假设,现在有 M={m1 ,m2,m3,....,mx}序列和 N = {n1,n2,n3,....,ny}序列,这两个序列已经是有序的序列,首先创建一个空序列 K = {},那么接着将 m1 和 n1 进行比较,加入 m1 < n1 那么将 m1 放入 K 序列中,然后 M 序列游标后移,即下一次将进行 m2 和 n1 的比较,直到全部比较完毕,并填入序列 K 中。

既然归并排序是整合有序序列,那么岂不是不能排序无序序列,这条件也太苛刻了点吧?

  归并排序是建立在分治法的基础上进行操作的,也就是可以将一个完全无序的序列进行无线分割以达到有序序列,比如:现在有 M={m1 ,m2,m3,....,mx},M序列是完全无序的序列,那么此时可以将 M 序列分成若干个小序列——{m1,m2},{m3,m4}....{mx-1,mx};此时这些序列就是有序的,那么就可以通过归并操作进行排序,所以归并排序也可以排序无序序列,且速度仅次于快速排序,属于稳定排序。

如何分割序列?

  上个问题已经提过,归并排序是建立在分治的基础上进行操作的,其中分治的体现就体现在分割序列上,比如:现在有M={m1 ,m2,m3,....,mx},第一次分割:M1 = {m1,m2,...,m(x+1)/2},M2 = {m(x+1)/2 +1,m(x+1)/2 +2,...,mx},第一次分割之后得到 M1 和 M2 序列,然后再分割 M1 和 M2 ,分割若干次之后得到 x/2 + x%2 个序列,然后再逐一进行归并操作。

该算法具体步骤:

  1、规定首指针 left 和mid(left指向序列1的首元素,right 指向序列2的首元素)

  2、比较 left 和 mid 的大小,将小的元素放入新建的空间中

  3、重复步骤2,直到其中一个序列遍历完毕

  4、将剩下的未加入新建空间中的元素直接复制粘贴进新建空间

该算法的核心步骤:

  1、使用分治法(递归)分割序列

  2、比较 left 和 mid 的大小 , 将小的元素的添加进入新建空间

讲述完毕,贴上代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 排序__归并排序
{
    class 归并
    {

        public static int[] arr = { 6, 202, 301, 100, 38, 8, 1 ,-1,1000};
        static void Main(string[] args)
        {
            Sort(arr, 0, arr.Length -1);
            foreach (var item in arr)
            {
                Console.Write(item + "  ");
            }
            Console.ReadKey();
        }

        public static void Sort(int []a,int left,int right)
        {
            if (left >= right) return;
            else
            {
                int mid = (left + right) / 2;                //@1
                Sort(a, left, mid);
                Sort(a, mid + 1, right);
                MergeSort(a, left, mid, right);
            }
        }

        public static void MergeSort(int []a,int left,int mid,int right)
        {
            int[] Arr = new int[right - left + 1];
            int l = left, m = mid +1 , k = 0;           //@2
            while ( m <= right && l <= mid )          //@3
            {
                if (a[l] > a[m]) Arr[k++] = a[m++];
                else Arr[k++] = a[l++];
            }
            while (m < right +1)                           //@4
            {
                Arr[k++] = a[m++];
            }
            while (l < mid +1 )  Arr[k++] = a[l++];        //@4
            for (k = 0, l = left; l < right + 1; k++, l++) a[l] = Arr[k];
        }
    }
}
登录后复制

代码解读:

  @1 :Sort()函数完成了序列的分割,每一次递归都将序列分成两半,直到不能分隔为止。

  @2 :l 代表序列1的首元素,m 代表序列2的首元素,k代表新建数组Arr的已有元素个数

  @3 :序列1的首元素和序列2的首元素进行比较,将小的放入 Arr 中,且序列游标后移,直到其中一个序列的元素遍比较完毕

  @4 :在序列1 和序列2的比较过程中,可能出现序列1已经全部添加进了 Arr 中,但是序列2还没有,则将剩下的未比较的元素直接复制进入 Arr 中

总结:

  以上代码并不是真正意义上的分割数组,只是做了一个逻辑分割,没有像其他代码一样将分割后的数组填入一个新的数组,那样做的话会对速度和内存产生一点影响,虽然微乎其微,但是总归是没这么好的,在归并操作上,需要注意的是参数不要越界(我当时就想了很久为什么 @2 上面的 m 要等于 mid +1 而不是 mid ,其实道理很简单,因为mid是属于左序列,从 mid+1 开始才属于右序列,将m = mid +1  改成 m = mid 不是不行,只是后面的代码也需要改,但是没有必要多做一次无用比较,这个问题我当时真是想了半天...),其实只要理清楚其中的逻辑关系,这样代码就能做到信手拈来。

以上是排序算法—归并排序【附代码】的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

快手双边市场的复杂实验设计问题 快手双边市场的复杂实验设计问题 Apr 15, 2023 pm 07:40 PM

一、问题背景1、双边市场实验介绍双边市场,即平台,包含生产者与消费者两方参与者,双方相互促进。比如快手有视频的生产者,视频的消费者,两种身份可能存在一定程度重合。双边实验是在生产者和消费者端组合分组的实验方式。双边实验具有以下优点:(1)可以同时检测新策略对两方面的影响,例如产品DAU和上传作品人数变化。双边平台往往有跨边网络效应,读者越多,作者越活跃,作者越活跃,读者也会跟着增加。(2)可以检测效果溢出和转移。(3)帮助我们更好得理解作用的机制,AB实验本身不能告诉我们原因和结果之间的关系,只

谷歌借AI打破十年排序算法封印,每天被执行数万亿次,网友却说是最不切实际的研究? 谷歌借AI打破十年排序算法封印,每天被执行数万亿次,网友却说是最不切实际的研究? Jun 22, 2023 pm 09:18 PM

整理|核子可乐,褚杏娟接触过基础计算机科学课程的朋友们,肯定都曾亲自动手设计排序算法——也就是借助代码将无序列表中的各个条目按升序或降序方式重新排列。这是个有趣的挑战,可行的操作方法也多种多样。人们曾投入大量时间探索如何更高效地完成排序任务。作为一项基础操作,大多数编程语言的标准库中都内置有排序算法。世界各地的代码库中使用了许多不同的排序技术和算法来在线组织大量数据,但至少就与LLVM编译器配套使用的C++库而言,排序代码已经有十多年没有任何变化了。近日,谷歌DeepMindAI小组如今开发出一

Vue技术开发中如何进行数据筛选和排序 Vue技术开发中如何进行数据筛选和排序 Oct 09, 2023 pm 01:25 PM

Vue技术开发中如何进行数据筛选和排序在Vue技术开发中,数据筛选和排序是非常常见和重要的功能。通过数据筛选和排序,我们可以快速查询和展示我们需要的信息,提高用户体验。本文将介绍在Vue中如何进行数据筛选和排序,并提供具体的代码示例,帮助读者更好地理解和运用这些功能。一、数据筛选数据筛选是指根据特定的条件筛选出符合要求的数据。在Vue中,我们可以通过comp

如何实现C#中的选择排序算法 如何实现C#中的选择排序算法 Sep 20, 2023 pm 01:33 PM

如何实现C#中的选择排序算法选择排序(SelectionSort)是一种简单直观的排序算法,其基本思想是每次从待排序元素中选择最小(或最大)的元素,放到已排序的序列末尾。通过重复这个过程,直到所有元素都排序完成。下面我们来详细了解如何在C#中实现选择排序算法,同时附上具体的代码示例。创建选择排序方法首先,我们需要创建一个用于实现选择排序的方法。该方法接受一

数组的排序算法有哪些? 数组的排序算法有哪些? Jun 02, 2024 pm 10:33 PM

数组排序算法用于按特定顺序排列元素。常见的算法类型包括:冒泡排序:通过比较相邻元素交换位置。选择排序:找出最小元素交换到当前位置。插入排序:逐个插入元素到正确位置。快速排序:分治法,选择枢纽元素划分数组。合并排序:分治法,递归排序和合并子数组。

Swoole进阶:如何使用多线程实现高速排序算法 Swoole进阶:如何使用多线程实现高速排序算法 Jun 14, 2023 pm 09:16 PM

Swoole是一款基于PHP语言的高性能网络通信框架,它支持多种异步IO模式和多种高级网络协议的实现。在Swoole的基础上,我们可以利用其多线程功能实现高效的算法运算,例如高速排序算法。高速排序算法(QuickSort)是一种常见的排序算法,通过定位一个基准元素,将元素分为两个子序列,小于基准元素的放在左侧,大于等于基准元素的放在右侧,再对左右子序列递归

如何使用C++中的基数排序算法 如何使用C++中的基数排序算法 Sep 19, 2023 pm 12:15 PM

如何使用C++中的基数排序算法基数排序算法是一种非比较性的排序算法,它通过将待排序的元素分割成一组有限的数字位来完成排序。在C++中,我们可以使用基数排序算法来对一组整数进行排序。下面我们将详细讨论如何实现基数排序算法,并附上具体的代码示例。算法思想基数排序算法的思想是将待排序的元素分割成一组有限的数字位,然后依次对每个位上的元素进行排序。在每个位上的排序完

如何使用MySQL和Java实现一个简单的排序算法功能 如何使用MySQL和Java实现一个简单的排序算法功能 Sep 20, 2023 am 09:45 AM

如何使用MySQL和Java实现一个简单的排序算法功能导言:在软件开发中,排序算法是非常基础且常用的功能之一。本文将介绍如何使用MySQL和Java实现一个简单的排序算法功能,并提供具体代码示例。一、排序算法概述排序算法是将一组数据按照特定规则进行排列的算法,常用的排序算法有冒泡排序、插入排序、选择排序、快速排序等。本文将以冒泡排序为例进行讲解及实现。二、M

See all articles