精华内容
下载资源
问答
  • 归并排序 稳定

    2017-07-27 15:42:00
    速度仅次于快排,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列 转载于:https://www.cnblogs.com/zawjdbb/p/7245219.html

    速度仅次于快排,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列

    转载于:https://www.cnblogs.com/zawjdbb/p/7245219.html

    展开全文
  • 归并排序稳定性分析

    2021-05-29 10:38:51
    归并排序稳不稳定关键要看 merge() 函数,也就是两个有序子数组合并成一个有序数组的那部分代码。在合并的过程中,如果 A[p…m]和 A[m+1…r]之间有值相同的元素,那我们可以像伪代码中那样,先把 A[p…q]中的元素放...

    归并排序稳不稳定关键要看 merge() 函数,也就是两个有序子数组合并成一个有序数组的那部分代码。在合并的过程中,如果 A[p…m]和 A[m+1…r]之间有值相同的元素,那我们可以像伪代码中那样,先把 A[p…q]中的元素放入 tmp 数组。这样就保证了值相同的元素,在合并前后的先后顺序不变。所以,归并排序是一个稳定的排序算法

    def merge(lst1, lst2):  # 有序列表lst1 lst2 合并成lst3
        lst3 = []
        i1, i2 = 0, 0  # 追踪每个列表当前的位置
        n1, n2 = len(lst1), len(lst2)
        while i1 < n1 and i2 < n2:  # lst1 和lst2 都拥有更多元素
            if lst1[i1] < lst2[i2]:  # lst1 的第一个元素更小
                lst3.append(lst1[i1])  # 把这个小的追加到临时列表
                i1 = i1 + 1
            else:  # lst2 的第一个元素更小
                lst3.append(lst2[i2])
                i2 = i2 + 1
        if i1 == n1:
            for i in lst2[i2:]:
                lst3.append(i)
        else:
            for i in lst1[i1:]:
                lst3.append(i)
        return lst3
    
    
    def mergeSort(nums):
        n = len(nums)
        if n <= 1:
            return nums
        m = n // 2
        left = mergeSort(nums[:m])
        right = mergeSort(nums[m:])
        return merge(left, right)
    
    
    print(mergeSort([1, 3, 2, 4, 5, 7, 9,2]))
    
    

    总结

    • 先操作左半部分,再操作右半部分,归并排序就是稳定的
    展开全文
  • 一、归并排序 1、介绍。 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,... 归并排序稳定排序,需...

    一、归并排序

    1、介绍。

            归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。

            归并排序是稳定排序,需要额外内存,空间复杂度O(n)。时间复杂度,最佳情况:O(nlogn)  最差情况:O(nlogn)  平均情况:O(nlogn)。

    2、步骤。

        (1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。
        (2)设定两个指针,最初位置分别为两个已经排序序列的起始位置。
        (3)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置。
        (4)重复步骤3直到某一指针超出序列尾,将另一序列剩下的所有元素直接复制到合并序列尾。

    3、代码。

    public static void main(String[] args) {
            System.out.println("------开始------");
            //生成生成两份一模一样的随机数组,其中一组用系统自带的方法进行排序,到时候进行验证。
            final int number = 100000;
            int[] sortArray = new int[number];
            int[] sortArrayCopy = new int[number];
            for (int i = 0; i < sortArray.length; i++) {
                sortArray[i] = (int) (Math.random() * number);
            }
            System.arraycopy(sortArray, 0, sortArrayCopy, 0, number);//数组复制
            Arrays.sort(sortArrayCopy);
    
            //开始排序
            long startTime = System.currentTimeMillis();
            mergeSort(sortArray);//归并(合并)排序
            System.out.println("花费时间:" + (System.currentTimeMillis() - startTime));
    
            //跟系统排序之后数组进行比较,查看是否排序成功。
            if (Arrays.equals(sortArray, sortArrayCopy)) {
                System.out.println("排序成功");
            } else {
                System.out.println("排序失败");
            }
            System.out.println("------结束------");
        }
    //归并(合并)排序 最佳情况:T(n) = O(n)  最差情况:T(n) = O(nlogn)  平均情况:T(n) = O(nlogn)
    private static void mergeSort(int[] array) {
        //只剩一个数了
        if (array.length < 2) {
            return;
        }
        //将array数组,切成left和right两个数组
        int middle = array.length / 2;
        int[] left = new int[middle];
        int[] right = new int[array.length - middle];
        for (int i = 0; i < array.length; i++) {
            if (i < middle) {
                left[i] = array[i];
            } else {
                right[i - middle] = array[i];
            }
        }
        //递归
        mergeSort(left);
        mergeSort(right);
        merge(array, left, right);
    }
    private static void merge(int[] array, int[] left, int[] right) {
        int leftIndex = 0, rightIndex = 0;
        for (int i = 0; i < array.length; i++) {
            if (leftIndex >= left.length) {//left数组已经排完了
                array[i] = right[rightIndex++];
            } else if (rightIndex >= right.length) {//right数组已经排完了
                array[i] = left[leftIndex++];
            } else if (left[leftIndex] < right[rightIndex]) {//left数组的值小于right数组的值
                array[i] = left[leftIndex++];
            } else {//left数组的值大于等于right数组的值
                array[i] = right[rightIndex++];
            }
        }
    }

    4、结果。

    二、自然归并排序

    1、介绍。

            自然归并排序:对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段.例如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段有{4,8},{3,7},{1,5,6},{2}.用一次对数组a的线性扫描就足以找出所有这些排好序的子数组段.然后将相邻的排好序的子数组段两两合并,构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6}).继续合并相邻排好序的子数组段,直至整个数组已排好序。

            自然归并排序是稳定排序,需要额外内存,空间复杂度O(n)。时间复杂度,最佳情况:O(nlogn)  最差情况:O(nlogn)  平均情况:O(nlogn)。

    2、步骤。

            跟归并排序的步骤一样,只不过在选择middle的时候,将前面已经排序好的作为一个数组。

    3、代码。

    public static void main(String[] args) {
            System.out.println("------开始------");
            //生成生成两份一模一样的随机数组,其中一组用系统自带的方法进行排序,到时候进行验证。
            final int number = 100000;
            int[] sortArray = new int[number];
            int[] sortArrayCopy = new int[number];
            for (int i = 0; i < sortArray.length; i++) {
                sortArray[i] = (int) (Math.random() * number);
            }
            System.arraycopy(sortArray, 0, sortArrayCopy, 0, number);//数组复制
            Arrays.sort(sortArrayCopy);
    
            //开始排序
            long startTime = System.currentTimeMillis();
            natureMergeSort(sortArray);//自然归并(合并)排序
            System.out.println("花费时间:" + (System.currentTimeMillis() - startTime));
    
            //跟系统排序之后数组进行比较,查看是否排序成功。
            if (Arrays.equals(sortArray, sortArrayCopy)) {
                System.out.println("排序成功");
            } else {
                System.out.println("排序失败");
            }
            System.out.println("------结束------");
        }
    //自然归并(合并)排序 最佳情况:T(n) = O(n)  最差情况:T(n) = O(nlogn)  平均情况:T(n) = O(nlogn)
    private static void natureMergeSort(int[] array) {
        //只剩一个数了
        if (array.length < 2) {
            return;
        }
        //将array数组,切成left和right两个数组
        int middle = array.length / 2;
        for (int i = 0; i < array.length - 1; i++) {
            if (array[i] > array[i + 1]) {
                middle = i;
                break;
            }
        }
        int[] left = new int[middle];
        int[] right = new int[array.length - middle];
        for (int i = 0; i < array.length; i++) {
            if (i < middle) {
                left[i] = array[i];
            } else {
                right[i - middle] = array[i];
            }
        }
        //递归
        mergeSort(left);
        mergeSort(right);
        merge(array, left, right);
    }
    private static void merge(int[] array, int[] left, int[] right) {
        int leftIndex = 0, rightIndex = 0;
        for (int i = 0; i < array.length; i++) {
            if (leftIndex >= left.length) {//left数组已经排完了
                array[i] = right[rightIndex++];
            } else if (rightIndex >= right.length) {//right数组已经排完了
                array[i] = left[leftIndex++];
            } else if (left[leftIndex] < right[rightIndex]) {//left数组的值小于right数组的值
                array[i] = left[leftIndex++];
            } else {//left数组的值大于等于right数组的值
                array[i] = right[rightIndex++];
            }
        }
    }

    4、结果。

    展开全文
  • 归并排序稳定的排序.即相等的元素的顺序不会改变.如输入记录 1(1) 3(2) 2(3) 2(4) 5(5) (括号中是记录的关键字)时输出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按输入的顺序.这对要排序数据包含多个信息而要按...

    归并排序是稳定的排序.即相等的元素的顺序不会改变.如输入记录 1(1) 3(2) 2(3) 2(4) 5(5) (括号中是记录的关键字)时输出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按输入的顺序.这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其它信息尽量按输入的顺序排列时很重要。归并排序的比较次数小于快速排序的比较次数,移动次数一般多于快速排序的移动次数。

    展开全文
  • 稳定排序:归并排序

    2017-04-20 16:02:20
    归并排序:对于给定的一组长度为n的记录,利用分治和递归的思想,将记录分为一个个长度为1的子序列,最后再用递归方法将排好序的子序列合并成为越来越大的有序序列。此方法称为2-路归并排序 归并排序一般会用在...
  • 归并排序

    千次阅读 2020-01-21 20:04:09
    归并排序 归并排序归并排序采用的是分治算法的思想,先把这个要排序...归并排序是一种稳定的排序算法,相对其他排序算法而言,是一种速度比较快的算法,时间复杂度为 O(n×log(n))O(n \times log(n))O(n×log(n))...
  • C语言实现归并排序 文章目录C语言实现归并排序2路归并排序算法1.定义动态数组2.初始化动态数组3.归并操作4.归并排序算法实现项目完整代码运行效果图 2路归并排序算法 1.定义动态数组 //定义一个动态数组 typedef ...
  • 稳定排序之归并排序

    2016-04-11 22:04:06
    首先要介绍如何将两个已排序的数组合并,因为这是递归排序的核心思想:首先要介绍如何将两个已排序的数组合并,因为这是递归排序的核心思想:void merge_array(int a[], int first, int mid, int last, int temp[]){...
  • 归并排序归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序...
  • 归并排序 基本思路: 假设初始序列有n个记录,则可看成是n个有序的子序列,每个序列长度为1,然后两两归并,得到个长度为2或者是1的有序子序列;再两两归并,,,,如此重复,直到得到一个长度为n的有序序列为止,...
  • 归并排序算法

    2016-04-11 21:10:01
    归并排序算法概论归并排序是不稳定的排序算法,
  • 【Java常用排序算法】归并排序(二路归并排序

    千次阅读 多人点赞 2017-02-27 23:17:10
    归并排序 二路归并排序 Java实现

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 38,656
精华内容 15,462
关键字:

归并排序稳定吗