zoukankan      html  css  js  c++  java
  • 数据结构和算法系列8 七大排序之归并排序

    这一篇要总结的是归并排序算法,这也是七大排序的最后一种排序算法。

    首先来看一下归并排序(Merge Sort)的基本原理。它的原理是假设初始序列有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两合并,得到n/2个长度为2或1的有序子序列;再两两归并,… … ,如此重复,直至得到一个长度为n的有序序列为止,这两排序方法就称为归并排序。

    下面以一张图来说明归并排序的数据交换过程:

    ds30

    C#版实现代码:

    namespace MergeSort.CSharp
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] array = { 50,10,90,30,70,40,80,60,20 };
    
                Console.WriteLine("********************归并排序********************");
                Console.WriteLine("排序前:");
                Display(array);
    
                MergeSort(array, new int[array.Length], 0, array.Length - 1);
                Console.WriteLine("排序后:");
                Display(array);
    
                Console.ReadKey();
            }
    
            /// <summary>
            /// 归并排序算法
            /// </summary>
            /// <param name="array">待排序的数组</param>
            /// <param name="temparray">临时数组</param>
            /// <param name="head">列表开始位置</param>
            /// <param name="rear">列表结束位置</param>
            public static void MergeSort(int[] array, int[] temparray, int head, int rear)
            {
                if (head < rear)
                {
                    //取分割位置
                    int middle = (head + rear) / 2;
    
                    //递归划分数组左序列
                    MergeSort(array, temparray, head, middle);
    
                    //递归划分数组右序列
                    MergeSort(array, temparray, middle + 1, rear);
    
                    //数组合并操作
                    Merge(array, temparray, head, middle + 1, rear);
                }
            }
    
            /// <summary>
            /// 合并操作(列表的两两合并)
            /// </summary>
            /// <param name="array"></param>
            /// <param name="temparray"></param>
            /// <param name="head"></param>
            /// <param name="middle"></param>
            /// <param name="rear"></param>
            public static void Merge(int[] array, int[] temparray, int head, int middle, int rear)
            {
                //左指针尾
                int headEnd = middle - 1;
    
                //右指针头
                int rearStart = middle;
    
                //临时数组的下标
                int tempIndex = head;
    
                //数组合并后的length长度
                int tempLength = rear - head + 1;
    
                //先循环两个区间段都没有结束的情况
                while ((headEnd>=head) && (rearStart <= rear))
                {
                    //如果发现有序列大,则将此数放入临时数组
                    if (array[head] < array[rearStart])
                        temparray[tempIndex++] = array[head++];
                    else
                        temparray[tempIndex++] = array[rearStart++];
                }
    
                //判断左序列是否结束
                while (head <= headEnd)
                    temparray[tempIndex++] = array[head++];
    
                //判断右序列是否结束
                while (rearStart <= rear)
                    temparray[tempIndex++] = array[rearStart++];
    
                //交换数据
                for (int i = 0; i < tempLength; i++)
                {
                    array[rear] = temparray[rear];
                    rear--;
                }
            }
    
            private static void Display(IList<int> list)
            {
                Console.WriteLine("
    **********展示结果**********
    ");
    
                if (list != null && list.Count > 0)
                {
                    foreach (var item in list)
                    {
                        Console.Write("{0} ", item);
                    }
                }
                Console.WriteLine("
    **********展示完毕**********
    ");
            }
        }
    }

    程序输出结果为:

    ds31

     

    C语言版:

    /*包含头文件*/
    #include "stdio.h"
    #include "stdlib.h"   
    #include "io.h"
    #include "math.h" 
    #include "time.h"
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    #define MAXSIZE 100
    
    typedef int Status; 
    typedef struct
    {
        int data[MAXSIZE];
        int length;    
    }SeqList;
    
    /* 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] */
    void Merge(int SR[],int TR[],int i,int m,int n)
    {
        int j,k,l;
        for(j=m+1,k=i;i<=m && j<=n;k++)    /* 将SR中记录由小到大地并入TR */
        {
            if (SR[i]<SR[j])
                TR[k]=SR[i++];
            else
                TR[k]=SR[j++];
        }
        if(i<=m)
        {
            for(l=0;l<=m-i;l++)
                TR[k+l]=SR[i+l];        /* 将剩余的SR[i..m]复制到TR */
        }
        if(j<=n)
        {
            for(l=0;l<=n-j;l++)
                TR[k+l]=SR[j+l];        /* 将剩余的SR[j..n]复制到TR */
        }
    }
    
    /*归并排序算法*/
    void MSort(int SR[],int TR1[],int s, int t)
    {
        int m;
        int TR2[MAXSIZE+1];
        if(s==t)
            TR1[s]=SR[s];
        else
        {
            m=(s+t)/2;                /* 将SR[s..t]平分为SR[s..m]和SR[m+1..t] */
            MSort(SR,TR2,s,m);        /* 递归地将SR[s..m]归并为有序的TR2[s..m] */
            MSort(SR,TR2,m+1,t);    /* 递归地将SR[m+1..t]归并为有序的TR2[m+1..t] */
            Merge(TR2,TR1,s,m,t);    /* 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] */
        }
    }
    
    /* 对顺序表L作归并排序 */
    void MergeSort(SeqList *seqList)
    { 
        MSort(seqList->data,seqList->data,0,seqList->length-1);
    }
    
    
    /*打印结果*/
    void Display(SeqList *seqList)
    {
        int i;
        printf("
    **********展示结果**********
    ");
    
        for (i=0;i<seqList->length;i++)
        {
            printf("%d ",seqList->data[i]);
        }
    
        printf("
    **********展示完毕**********
    ");
    }
    
    #define N 9
    void main()
    {
        int i,j;
        SeqList seqList;
    
        //定义数组和初始化SeqList
        int d[N]={50,10,90,30,70,40,80,60,20};
    
        for (i=0;i<N;i++)
        {
            seqList.data[i]=d[i];
        }
        seqList.length=N;
    
        printf("***************归并排序***************
    ");
        printf("排序前:");
        Display(&seqList);
    
        MergeSort(&seqList);
        printf("
    排序后:");
        Display(&seqList);
    
        getchar();
    }

    输出结果同上。

  • 相关阅读:
    使用urllib
    spring常用的45个注解
    音痴
    android与JS函数传参遗留问题
    方舟编译器源码过一遍流程
    什么是语义学,解释器
    synchronized,ReentrantLock解决锁冲突,脏读的问题
    【Unity3d】ScrollRect自动定位到某点
    计算点到直线的距离】 C#实现
    理财-房月供占工资多少比较合适?
  • 原文地址:https://www.cnblogs.com/mcgrady/p/3263663.html
Copyright © 2011-2022 走看看