算法 - 归并排序(C#)

/*
 * MergeSorter.cs - by Chimomo
 *
 * 归并排序是建立在归并操作上的排序算法,该算法是分而治之策略(Divide and Conquer)的一个非常典型的应用。
 *
 * 归并操作的基本原理:
 * 1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放归并后的序列。
 * 2、设置两个指针,最初位置分别为两个已经排序序列的起始位置。
 * 3、比较两个指针所指向的元素,选择相对小的元素放入归并序列,并移动指针到下一位置。
 * 4、重复步骤3直到某一指针超出序列尾部。
 * 5、将另一序列剩下的所有元素直接复制到归并序列尾部。
 *
 * 归并排序的基本原理(假设序列共有n个元素):
 * 1、将序列每相邻两个数字进行归并操作(Merge),形成Floor(n/2)个序列,排序后每个序列包含两个无素。
 * 2、将上述序列再次归并,形成Floor(n/4)个序列,每个序列包含四个元素。
 * 3、重复步骤2,直到所有元素排序完毕。
 *
 * 归并排序速度仅次于快速排序,是一种稳定的排序算法,一般用于对总体无序,但是各子项相对有序的序列。
*/

using System;

namespace Sort
{
    public static class MergeSorter
    {
        /// <summary>
        /// 二路归并:将两个有序序列归并成一个有序序列。
        /// </summary>
        /// <param name="a">待归并序列</param>
        /// <param name="s1">第一个有序序列的起始下标</param>
        /// <param name="s2">第二个有序序列的起始下标</param>
        /// <param name="e2">第二个有序序列的结束下标</param>
        private static void Merge(int[] a, int s1, int s2, int e2)
        {
            int[] tmp = new int[e2 - s1 + 1];
            int i = s1, j = s2, k = 0;
            while (i < s2 && j <= e2)
            {
                if (a[i] <= a[j])
                {
                    tmp[k] = a[i];
                    k++;
                    i++;
                }
                else
                {
                    tmp[k] = a[j];
                    j++;
                    k++;
                }
            }
            while (i < s2)
            {
                tmp[k] = a[i];
                i++;
                k++;
            }
            while (j <= e2)
            {
                tmp[k] = a[j];
                j++;
                k++;
            }
            Array.Copy(tmp, 0, a, s1, tmp.Length);
        }

        /// <summary>
        /// 归并排序算法。
        /// </summary>
        /// <param name="a">待排序序列</param>
        /// <param name="s">待排序序列的起始下标</param>
        /// <param name="length">每次要归并的有序集合的长度</param>
        public static void MergeSort(int[] a, int s, int length)
        {
            int size = a.Length;
            int mid = size / (length << 1);
            int c = size & ((length << 1) - 1);
            // 归并到只剩一个有序序列的时候结束算法。
            if (mid == 0)
            {
                return;
            }
            // 进行一趟归并排序。
            for (int i = 0; i < mid; ++i)
            {
                s = i * 2 * length;
                Merge(a, s, s + length, (length << 1) + s - 1);
            }
            // 将剩下的元素和倒数一个有序集合归并。
            if (c != 0)
            {
                Merge(a, size - c - 2 * length, size - c, size - 1);
            }
            // 递归执行下一趟归并排序。
            MergeSort(a, 0, 2 * length);
        }
    }
}
/*
 * Program.cs - by Chimomo
 *
*/

using System;

namespace Sort
{
    static class Program
    {
        static void Main()
        {
            int[] a = { 4, 3, 6, 1, 2, 5, 34, 7, -1, 340, -234, -9, 909 };
            MergeSorter.MergeSort(a, 0, 1);
            foreach (var i in a)
            {
                Console.Write(i + " ");
            }
            Console.WriteLine();
        }
    }
}

/*
Output:
-234 -9 -1 1 2 3 4 5 6 7 34 340 909
*/
时间: 2024-10-12 10:01:19

算法 - 归并排序(C#)的相关文章

排序算法——归并排序

归并排序是分治法的典型举例. 分治法的思想是,将原有问题分解为几个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 分治模式在每层递归时都有三个步骤: 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例. 解决这些子问题,递归地求解各子问题.然而,若子问题的规模足够小,则直接求解. 合并这些子问题的解成原问题的解. 归并排序算法完全遵循分治模式.直观上其操作如下: 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列. 解决:使用

经典排序算法 - 归并排序Merge sort

经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 4 1 5 9] 先看一下每一个步骤下的状态,完了再看合并细节 第一步 [6 2 4 1 5 9]原始状态 第二步 [2 6] [1 4] [5 9]两两合并排序,排序细节后边介绍 第三步 [1 2 4 6] [5 9]继续两组两组合并 第四步 [1 2 4 5 6 9]合并完成,排序完成 输出结

Java实现算法归并排序(MergeSort)

归并排序 归并排序 (merge sort) 是一类与插入排序.交换排序.选择排序不同的另一种排序方法.归并的含义是将两个或两个以上的有序表合并成一个新的有序表.归并排序有多路归并排序.两路归并排序 , 可用于内排序,也可以用于外排序.这里仅对内排序的两路归并方法进行讨论. 1.两路归并排序算法思路 ①把 n 个记录看成 n 个长度为1的有序子表: ②进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表: ③重复第②步直到所有记录归并成一个长度为 n 的有序表为止. 实例: 2.

[算法]——归并排序(Merge Sort)

归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlogn),但是归并排序除了递归调用间接使用了辅助空间栈,还需要额外的O(n)空间进行临时存储.从此角度归并排序略逊于快速排序,但是归并排序是一种稳定的排序算法,快速排序则不然. 所谓稳定排序,表示对于具有相同值的多个元素,其间的先后顺序保持不变.对于基本数据类型而言,一个排序算法是否稳定,影响很小,但是

我实现的第一个算法----归并排序

今天听了卜东坡老师的算法课,讲的是归并算法,那个动画演示,终于让我开窍了,于是乎,赶紧今天就编了个C++的程序.我知道可能这个程序还比较粗糙,但是这是第一次实现了算法导论上的东东,心里那个激动啊,,,哎,我也终于能实现个算法了,以前总认为自己很菜,其实真的很菜,,,算了,直接上程序吧,,, #include<iostream> using namespace std; int a[100]; int flag; int n; void vector_initial(); void print_

算法--归并排序(链表)

归并排序 http://blog.csdn.net/morewindows/article/details/6678165 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 归并操作: http://www.tuicool.com/articles/iy2QRn6 归并操作 归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法. 如:设有数列 [6,202,100,301,38,8,1]

python数据结构与算法——归并排序

归并排序: 原理与C语言实现 参考:白话经典算法系列之五 归并排序的实现 1. 容易对有序数组A,B进行排序. 2. 为了使得A,B组内数据有序:可以将A,B组各自再分成二组. 3. 经过不断分组,当分出来的小组只有一个数据时(有序),合并相邻二个小组. 这样通过先递归的分解数列,再合并数列就完成了归并排序. 代码摘自<Python Algorithm> 1 # 对数组seq进行归并排序 2 # 返回排序后数组 3 def mergesort(seq): 4 mid = len(seq)//2

算法-归并排序

归并排序是建立在归并操作上的一种有效的排序算法,算法主要采用分治法(Divide and Conquer)的一个非常典型的应用.归并排序的算法复杂度为O(N*logN),需要的额外的空间跟数组的长度N有关系,实现归并排序最简单的方法是将两个数组重新整合到第三个数组中.通常对于一个数组我们对前半部分进行排序,然后惊醒后半部分进行排序,实现原地归并操作,不过需要额外的空间存储数组.假设数据中有8个元素,先分为四组进行比较,之后分为两组进行比较,最后分为一组进行比较,这样就衍生出来两种方法,一种是自顶

算法—归并排序的改进及排序算法的极致

1.对小规模子数组使用插入排序 用不同的方法处理小规模问题能改进大多数递归算法的性能,因为递归会使小规模问题中方法的调用过于频繁,所以改进对它们的处理方法就能改进整个算法.对排序来说,我们已经知道插入排序(或者选择排序)非常简单,因此很可能在小数组上比归并排序更快.和之前一样,一幅可视轨迹图能够很好地说明归并排序的行为方式.图中的可视轨迹图显示的是改良后的归并排序的所有操作.使用插入排序处理小规模的子数组(比如长度小于15)一般可以将归并排序的运行时间缩短10%~15%. 2.测试数组是否已经有

[经典算法] 归并排序

题目说明: 归并排序是建立在归并操作上的一种有效的排序算法.该算法也是采用分治法(Divide and Conquer)的一个非常典型的应用.算法复杂度为O(N*logN). 题目解析: 归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列. 归并排序包括两个步骤: 1)划分子表 2)合并半子表 伪代码: 合并排序伪代码(使用哨兵): merge(A,p,q,r): n1 <-- q-p+1 n2 <-