当前位置: 首页 > news >正文

排序详解之归并排序

归并排序

本文章将介绍归并排序,时间复杂度为n*lg(n)的归并排序,不仅效率高,而且是稳定的(而堆排序,快排是不稳定的)。

要排序的数组:

5 , 1, 9 ,3, 7 , 4 , 8 ,6 , 2

 

归并排序过程:

1.      计算组元素个数,count ,count=2为起始个数,每次count*=2,count[2,arr.Count]

2.      每次把数组元素以count为一组,进行分组,对每一组进行排序

3.      把排序好的组与相邻的组进行归并,合并为同一组,同时count*=2

4.      不断分组,增加count个数,直到countarr.Count(即数组长度)为止

 

现在我们过一遍这个流程。

 

 

 


至于归并两个组的过程,就不详细讨论了,可以选择插入排序,把第二个组的数组插入到第一个组。

 

参考代码:

public List<int>MergeSort(List<int> arr)
        {
            List<int> lastOne = null;
            if (arr.Count % 2 != 0)
            {
                lastOne = new List<int> {arr[arr.Count - 1] };
                arr.RemoveAt(arr.Count - 1);
            }
 
            var groups = newQueue<List<int>>();
            foreach (var a in arr)
            {
                groups.Enqueue(newList<int> { a });
            }
 
            if (lastOne == null)
            {
                while (groups.Count > 1)
                {
                    var ret =Merge2Arr(groups.Dequeue(), groups.Dequeue());
                    groups.Enqueue(ret);
                }
                return groups.Dequeue();
            }
 
            while (groups.Count > 1)
            {
                var ret =Merge2Arr(groups.Dequeue(), groups.Dequeue());
                groups.Enqueue(ret);
            }
            return Merge2Arr(groups.Dequeue(),lastOne);
        }
 
        private List<int>Merge2Arr(List<int> arr1, List<int> arr2)
        {
            var ret = new List<int>();
            if (arr1.Count == 1)
            {
                if (arr1[0] > arr2[0])
                {
                    ret.Add(arr2[0]);
                    ret.Add(arr1[0]);
                }
                else
                {
                    ret.Add(arr1[0]);
                    ret.Add(arr2[0]);
                }
                return ret;
            }
 
            if (arr1[0] > arr2[0])
            {
                arr2.ForEach(ret.Add);
               
                for (int j = 0; j <arr1.Count; j++)
                {
                    var isInserted = false;
                    for (int i = 0; i <ret.Count - 1; i++)
                    {
                        if (ret[i] < arr1[j]&& ret[i + 1] >= arr1[j])
                        {
                            ret.Insert(i+1, arr1[j]);
                            isInserted = true;
                            break;
                        }
                    }
                    if (!isInserted)
                    {
                        if(arr1[j] <ret[ret.Count - 1]) ret.Insert(0,arr1[j]);
                        else   ret.Add(arr1[j]);
                       
                    }
                     
                }
            }
            else
            {
                arr1.ForEach(ret.Add);
                for (int j = 0; j <arr2.Count; j++)
                {
                    var isInserted = false;
                    for (int i = 0; i <ret.Count - 1; i++)
                    {
                        if (ret[i] < arr2[j] && ret[i +1] >= arr2[j])
                        {
                            ret.Insert(i+1,arr2[j]);
                            isInserted = true;
                            break;
                        }
                    }
                    if (!isInserted)
                    {
                        if (arr2[j] <ret[ret.Count - 1]) ret.Insert(0, arr2[j]);
                        else ret.Add(arr2[j]);
                    }
                }
            }
            return ret;
        }


 

相信你现在已经明白了归并排序。

感谢您的阅读!

 

相关文章:

  • 排序详解之快速排序
  • 价差100元 性能相当 蓝宝HD4830白金版 PK 9800GT显卡
  • 软件周周侃
  • 新的威胁!智能手机将成为黑客的下一个目标
  • 无资无本如何赚钱?——当一名“淘客”走上网络打工之路
  • Asp.net Design Pattern study notes -- PART 2
  • 利用Excel巧制抽奖器
  • XnView调整图片不失真
  • 物尽其才 用PotPlayer免费转录高清电影
  • 一句话技巧
  • How to use Interface
  • 无需第三方软件 用ScreenToaster在线进行视频录制
  • 将你的收藏共享给QQ好友
  • 你不在线,文件我照样传
  • 轻松发送语音邮件
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • 230. Kth Smallest Element in a BST
  • Consul Config 使用Git做版本控制的实现
  • HTTP中的ETag在移动客户端的应用
  • jQuery(一)
  • leetcode388. Longest Absolute File Path
  • MySQL几个简单SQL的优化
  • SpingCloudBus整合RabbitMQ
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • windows下使用nginx调试简介
  • 服务器之间,相同帐号,实现免密钥登录
  • 和 || 运算
  • 坑!为什么View.startAnimation不起作用?
  • 如何正确配置 Ubuntu 14.04 服务器?
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (16)Reactor的测试——响应式Spring的道法术器
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (function(){})()的分步解析
  • (ibm)Java 语言的 XPath API
  • (libusb) usb口自动刷新
  • (补)B+树一些思想
  • (第61天)多租户架构(CDB/PDB)
  • (二)JAVA使用POI操作excel
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (三)elasticsearch 源码之启动流程分析
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (转)jdk与jre的区别
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET Framework 服务实现监控可观测性最佳实践
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .NET6实现破解Modbus poll点表配置文件
  • .Net小白的大学四年,内含面经
  • .NET运行机制
  • @Bean, @Component, @Configuration简析