• C#排序算法之归并排序


    排序规则:

      1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

      2、设定两个指针,最初位置分别为两个已经排序序列的起始位置

      3、比较两个指针所指向的元素,选择相对小的元素放入合并空间,并移动指针到下一位置。

      4、重复步骤3直到指针达到序列末尾

      5、将另一序列剩下的所有元素直接复制到合并序列末尾

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace 排序算法
    {
        class MergeSort1
        {
            public static void Sort(int[] arr)
            {
                int n = arr.Length;
                int[] temp = new int[n];
                Sort(arr, temp, 0, n - 1);
            }
            private static void Sort(int[] arr, int[] temp, int l,int r)
            {
                int mid = l + (r - l) / 2;
                Merge(arr, temp, l, mid, r);
            }
            private static void Merge(int[] arr, int[] temp, int l, int mid, int r)
            {
                int i = l;
                int j = mid + 1;
                int k = l;
                //左右半边都有元素
                while(i <= mid && j <= r)
                {
                    if(arr[i] < arr[j])
                    {
                        temp[k++] = arr[i++];
                    }
                    else
                    {
                        temp[k++] = arr[j++];
                    }
                }
                //左半边还有元素,右半边用尽
                while(i <= mid)
                {
                    temp[k++] = arr[i++];
                 }
                //右半边还有元素,左半边用尽
                while(j <= r)
                {
                    temp[k++] = arr[j++];
                }
                //将temp数组覆盖到arr数组中
               for(int z = l; z <= r; z++)
                {
                    arr[z] = temp[z];
                }
            }
    
        }
    }

    上面代码中左右两边都必须有序才能排序。如何保证左右有序?

    递归分割:

       将数组拆分成许多小的子数组每个子数组中只有两个元素,这样子数组的左右半边只有一个元素

       当左右半边只有一个元素时,即可看作左右有序

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace 排序算法
    {
        class MergeSort2
        {
            public static void Sort(int[] arr)
            {
                int n = arr.Length;
                int[] temp = new int[n];
                Sort(arr, temp, 0, n - 1);
            }
            //递归分割
            private static void Sort(int[] arr, int[] temp, int l,int r)
            {
                if(l >= r)
                {
                    return;
                }
                int mid = l + (r - l) / 2;
                Sort(arr, temp, l, mid);
                Sort(arr, temp, mid + 1, r);
                Merge(arr, temp, l, mid, r);
            }
            private static void Merge(int[] arr, int[] temp, int l, int mid, int r)
            {
                int i = l;
                int j = mid + 1;
                int k = l;
                //左右半边都有元素
                while(i <= mid && j <= r)
                {
                    if(arr[i] < arr[j])
                    {
                        temp[k++] = arr[i++];
                    }
                    else
                    {
                        temp[k++] = arr[j++];
                    }
                }
                //左半边还有元素,右半边用尽
                while(i <= mid)
                {
                    temp[k++] = arr[i++];
                 }
                //右半边还有元素,左半边用尽
                while(j <= r)
                {
                    temp[k++] = arr[j++];
                }
                //将temp数组覆盖到arr数组中
               for(int z = l; z <= r; z++)
                {
                    arr[z] = temp[z];
                }
            }
    
        }
    }

    优化归并排序:

      1、对小规模的子数组时使用插入排序,因为递归会在小规模数组中调用过于频繁

      2、子数组本来就是有序的,就不再进行归并操作就是子数组的左半边最后一个元素小于右半边第一个元素

    namespace 排序算法
    {
        /*
         * 时间复杂度O(nlogn)
         * 空间复杂度O(n)需要借助一个同样长度的辅助数组进行排序。
         * 1、对小规模的子数组时使用插入排序,因为递归会在小规模数组中调用过于频繁
         * 2、子数组本来就是有序的,就不再进行归并操作就是子数组的左半边最后一个元素小于右半边第一个元素
         */
        class MergeSort
        {
            public static void Sort(int[] arr)
            {
                int n = arr.Length;
                int[] temp = new int[n];
                Sort(arr, temp, 0, n - 1);
            }
            //递归分割
            private static void Sort(int[] arr, int[] temp, int l,int r)
            {
                //优化点1
                if(r - l + 1 <= 15)
                {
                    InsertSort(arr, l, r);
                    return;
                }
                int mid = l + (r - l) / 2;
                Sort(arr, temp, l, mid);
                Sort(arr, temp, mid + 1, r);
                // 优化点2
                if(arr[mid] > arr[mid + 1])
                {
                    Merge(arr, temp, l, mid, r);
                }
            }
            private static void Merge(int[] arr, int[] temp, int l, int mid, int r)
            {
                int i = l;
                int j = mid + 1;
                int k = l;
                //左右半边都有元素
                while(i <= mid && j <= r)
                {
                    if(arr[i] < arr[j])
                    {
                        temp[k++] = arr[i++];
                    }
                    else
                    {
                        temp[k++] = arr[j++];
                    }
                }
                //左半边还有元素,右半边用尽
                while(i <= mid)
                {
                    temp[k++] = arr[i++];
                 }
                //右半边还有元素,左半边用尽
                while(j <= r)
                {
                    temp[k++] = arr[j++];
                }
                //将temp数组覆盖到arr数组中
               for(int z = l; z <= r; z++)
                {
                    arr[z] = temp[z];
                }
            }
            //插入排序
            public static void InsertSort(int[] arr, int l, int r)
            {
                for (int i = l + 1; i <= r; i++)
                {
                    int e = arr[i];
                    int j;
                    for (j = i; j > l; j--)
                    {
                        if (e < arr[j - 1])
                        {
                            arr[j] = arr[j - 1];
                        }
                        else
                        {
                            break;
                        }
                    }
                    arr[j] = e;
                }
            }
        }
    }
    • 添加到短语集
       
      • 没有此单词集: -> ...
         
      • 创建新的单词集...
    • 拷贝
    • 添加到短语集
       
      • 没有此单词集: -> ...
         
      • 创建新的单词集...
    • 拷贝
    • 添加到短语集
       
      • 没有此单词集: -> ...
         
      • 创建新的单词集...
    • 拷贝
  • 相关阅读:
    js数据类型的转换
    个人总结css中的四种position定位
    c3和js写的切割轮播图 喜欢宋仲基的妹子汉子们来,观看效果需要引入jQuery^^
    立体骰子(css3和js)
    友善串口调试助手
    Pixhawk之调试方法
    深度学习论文笔记:Deep Residual Networks with Dynamically Weighted Wavelet Coefficients for Fault Diagnosis of Planetary Gearboxes
    Sublime Text 插件之常用20个插件
    lll
    浅谈jQuery的对象构成1
  • 原文地址:https://www.cnblogs.com/sy-liu/p/13266857.html
Copyright © 2020-2023  润新知