zoukankan      html  css  js  c++  java
  • 归并排序

    归并排序完全遵循分治模式,直观上操作可分为:

      分解:分解待排序的n个元素的序列各具有n/2个元素的两个子序列。

      解决:使用归并排序递归的排序两个子序列。

      合并:合并两个已排好序的子序列以产生已排序的答案。

    当递归到序列长度为1时,递归回升,此时不需要做任何操作,因为长度为1的每个序列都已排好序。

    归并算法的关键操作是"合并"步骤中两个已排序序列的合并。我们通过Merge(A, p, q, r)来完成合并,其中A是一个数组,p、q、和 r是一个数组的下标,满足p<=q<r。该过程假设子数组A[p..q],和A[q+1...r]都已排

    好序。它合并这两个子数组形成单一的已排好序的数组并代替当前的子数组A[p...r]。

    时间复杂度 O(n*log(n)),【空间复杂度O(n),】稳定排序。

    伪代码:

    Merge (A, p, q, r)
        n1 = p - q + 1
        n2 = r - q
        let L[1...n1+1] and R[1...n2+1] be new arrays
        for i = 1 to n1
            L[i] = A[p + i - 1]
        for j = 1 to n2
            R[j] = A[q + j]
        L[n1 + 1] = inf
        R[n2 + 1] = inf
        i = 1
        j = 1
        for k = p to r
            if L[i] <= R[j]
                A[k++] = L[i]
                i++
            else
                A[k++] = R[j]
                j++
    
    
    MergeSort(A, p, r)
        if p < r
            q = int((p + r)/2)
          MergeSort(A, p, q)
          MergeSort(A, q+1, r)
          Merge(A, p, q, r)
    

    示例代码:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    
    int num[1010], temp[1010];
    
    void Merge(int A[], int p, int q, int r) {
        int i = p;
        int j = q + 1;
        int k = 0;
        while(i <= q && j <= r) {
            if (A[i] < A[j])
                temp[k++] = A[i++];
            else temp[k++] = A[j++];
        }
        while(i <= q) {
            temp[k++] = A[i++];
        }
        while(j <= r) {
            temp[k++] = A[j++];
        }
        for (int i=0; i<k; ++i) {
            A[p+i] = temp[i];
        }
    }
    
    void MergeSort(int A[], int p, int r) {
        int q;
        if (p < r) {
            q = (p + r) / 2;
            MergeSort(A, p, q);
            MergeSort(A, q+1, r);
            Merge(A, p, q, r);
        }
    }
    
    int main() {
        freopen("1.in.cpp", "r", stdin);
        int n;
        while(~scanf("%d", &n)) {
            for (int i=0; i<n; ++i) {
                scanf("%d", &num[i]);
            }
            MergeSort(num, 0, n-1);
            for (int i=0; i<n; ++i) {
                printf("%d ", num[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    【洛谷P2660烤鸡】
    cogs448
    排队打水
    洛谷U36590搬书
    NOIP2012借教室
    归并排序模版
    NOIP2015神奇的幻方
    NOIP2006能量项链
    NOIP2003加分二叉树
    NOI1995石子合并&多种石子合并
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5738312.html
Copyright © 2011-2022 走看看