数学建模社区-数学中国
标题:
神级基础排序——归并排序
[打印本页]
作者:
杨利霞
时间:
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 R
6 ] 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- p
import 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
2020-3-30 17:02 上传
下载附件
(89.18 KB)
7 h: k5 Z0 I/ y' r4 ?3 z
$ u# a" G- O& _! C
1、以上就是今天分享的归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)
* {/ T0 [: _3 f# y
2、归并排序的额外空间复杂度可以做到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