数学建模社区-数学中国

标题: 神级基础排序——归并排序 [打印本页]

作者: 杨利霞    时间: 2020-3-30 17:02
标题: 神级基础排序——归并排序
2 I2 `) \% a! e% c7 c4 v
! F6 i. R; o; K
神级基础排序——归并排序
3 z! u$ U1 e6 y6 |  R" X: U% t! O% S
归并排序的介绍+ _) V0 n* U6 c" U
+ c7 G# K* |% ]7 {
归并排序(英语:Merge sort,或Mergesort),是创建在归并操作上的一种有效的排序算法,其时间复杂度为O(N*logN)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。
# m7 L: K+ E/ z" i- i8 d概念$ k5 X' M, K. @1 e2 @: V
9 D1 F- k: m: f/ k2 u* W- j: C
是利用递归与分治的技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好序的半子表合并成越来越大的有序序列。
0 u9 Z" N+ ~* E/ D3 @1 ^1 e3 [5 E核心思想
: T# ?/ Q# V* [) v9 T2 R6 ]  V# A/ p# V6 `" D8 ]2 H9 w& N. a
将两个有序的数列合并成一个大的有序的序列。通过递归,层层合并,即为归并。
4 [* J% m+ d9 w# |7 w2 a
# Z8 L5 ~/ q& c& {5 v" g, A$ e8 V+ L) ^
实现代码
/ s0 x" ~% K8 @/ O, z- pimport java.util.Arrays;% \+ c, r- f9 W% G4 u
7 Q8 V. W2 E, y+ |
/**
) d: l) z" _% q: _7 j8 H  d * @Author god-jiang
6 }. C( P, v& O/ m9 U * @date 2020/1/13
* Y3 V( ?/ z8 ^. | */
0 `/ b$ `3 G- p0 f//归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)4 _4 e7 d0 S- C( Z
public class MergeSort {6 [5 X" a' S; B: c# R
    public static void MergeSort(int[] arr, int start, int end) {
1 K9 `5 K4 V& }/ F        //分治的结束条件: S) F! C5 T7 \0 I  q% c2 k
        if (start >= end) {
$ M; X  X6 S! [+ D  _! I5 T% x* p            return;% K6 |) }* h1 h" y9 \
        }+ D" K" a6 p$ B( @3 D" k; h: d
        //保证不溢出取start和end的中位数, [" Q8 p: ]+ J# v& D' O0 D
        int mid = start + ((end - start) >> 1);
/ L  \1 `" P  Y# ~' S  w4 }) k: V        //递归排序并且合并) Q; x; ~1 X3 y) }& n
        MergeSort(arr, start, mid);7 Q6 U. h" F' J$ @# R7 S$ o4 H
        MergeSort(arr, mid + 1, end);: [0 {- ?; ^( y! I' f) f
        Merge(arr, start, mid, end);2 O) ~9 a: j* N, {
    }
- O: T: E/ m* b  c" U) Q
. h; a7 v; Q# f  [. q    //合并5 M$ G1 e/ \" L9 y% p
    public static void Merge(int[] arr, int start, int mid, int end) {
" S2 E( b6 ?! q9 f        int[] temp = new int[end - start + 1];
' l8 l6 F2 o7 K/ z8 w$ z# x+ F        int p1 = start;; c  M) j2 X9 G/ T) h
        int p2 = mid + 1;
1 [- F/ N& i8 h1 U) f4 x- ]        int p = 0;
6 @) D0 u1 k6 d        while (p1 <= mid && p2 <= end) {7 m. d; w- T2 E! e# w
            if (arr[p1] > arr[p2]) {: `) Q! J, q0 ~
                temp[p++] = arr[p2++];
) N' O$ l$ R, }* g. `            } else {
$ S# V1 V6 ?, W4 q% \                temp[p++] = arr[p1++];; i" y0 K  \- }2 d5 D4 |- @
            }" [- B$ l9 X; c) r" |; x
        }
  H+ k3 D9 V' ~5 U7 s, a        while (p1 <= mid) {
3 q- {# P7 [7 y            temp[p++] = arr[p1++];/ x  i+ [8 V4 [0 u
        }) E3 K8 c  J2 q4 b. F* t- R
        while (p2 <= end) {- C6 V& Y3 h, p0 ~
            temp[p++] = arr[p2++];
( b! s* }% F, T4 Q; d  l        }7 `9 `$ E) I1 t+ T! _
        for (int i = 0; i < temp.length; i++) {, i: s# n( Y( q- \0 B& ~+ D
            arr[i + start] = temp;6 ?: ^0 T' h- H  ?* T6 W: p2 B" \
        }
- B8 J1 X7 @7 U    }
, V5 ?& V& R' R+ z6 K: ]7 b- J' ?7 n  l3 r  E8 M
    public static void main(String[] args) {4 k/ K' K3 o" L+ U! S8 I
        int[] a = {2, 4, 6, 1, 3, 7, 9, 8, 5};( E. {: P) p9 {6 h0 Q  f
        MergeSort(a, 0, a.length - 1);! E3 o3 E5 x9 a, d( l
        System.out.println(Arrays.toString(a));
. z( \$ T& B: G* j( U' @3 @    }9 v2 B3 ^+ o" V# A& H1 v: s
}2 E( X% ~0 |) J) n! O$ u% V" K2 d

7 A% t# \# I; T& W- ?$ X) h5 e/ |- Y3 g% r
运行截图
9 P( O) s0 L! B( W7 j4 i1 e" t& m
+ G' V' q# Z4 }" t* S 1.png 7 h: k5 Z0 I/ y' r4 ?3 z

$ u# a" G- O& _! C1、以上就是今天分享的归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)
* {/ T0 [: _3 f# y2、归并排序的额外空间复杂度可以做到O(1),但是非常难,不需要掌握,有一篇论文”归并排序内部缓存法”可以做到- D5 H: a2 v: A, a

0 W- B" O. P" y1 P原文链接:https://blog.csdn.net/weixin_37686415/article/details/105180035
: V  f9 _% L; w- s: b
7 y$ G# ]5 ^1 @: `. e2 Q( W# f7 H& \( e& N: O  E4 n6 `





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5