数学建模社区-数学中国
标题:
神级基础排序——归并排序
[打印本页]
作者:
杨利霞
时间:
2020-3-30 17:02
标题:
神级基础排序——归并排序
* Y# N" ^2 J+ X T" Q$ T
* r. u- } p' i* p, j9 C- v
神级基础排序——归并排序
9 p5 U9 K0 N6 n3 i6 V2 V
4 s. {% J: m: z( l$ g! g& ~
归并排序的介绍
5 j, c, U. o& V# z
E+ u, k8 ?8 \+ v7 a0 a
归并排序(英语:Merge sort,或Mergesort),是创建在归并操作上的一种有效的排序算法,其时间复杂度为O(N*logN)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。
% S' Y5 t+ C6 o2 w+ P
概念
: Z9 c1 T' x( j5 v& y( }
' R$ H8 I2 ?: N" B
是利用递归与分治的技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好序的半子表合并成越来越大的有序序列。
! J3 S5 U4 d* w. f6 K( ?) V1 K
核心思想
7 L. a3 q, j/ h9 r7 L
8 R& ]0 `$ D1 `% b, P
将两个有序的数列合并成一个大的有序的序列。通过递归,层层合并,即为归并。
+ H5 J+ ^* Z0 F1 D" L
) \* V4 t+ Z# R0 e
2 B1 Z: v* a2 @1 d& j/ Z
实现代码
+ p' j; k8 V% Q1 s
import java.util.Arrays;
# H# o* E) _5 m9 m
/ Q- }1 e. l$ ~5 l$ H' R2 c
/**
: J4 F$ R5 o3 V- P# V9 Z2 G3 d
*
@Author
god-jiang
" `7 d# d o* u% c) }- u2 J3 i
* @date 2020/1/13
+ B' w9 q- a: m* G
*/
0 T! |9 M" i7 I0 P
//归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)
5 Y" t# u" O4 i0 g+ X# W+ i" n
public class MergeSort {
) U) F# y3 U2 j. p8 {% s* L9 z4 ]
public static void MergeSort(int[] arr, int start, int end) {
% ]1 m2 I, ] [
//分治的结束条件
- F! \9 u2 i7 B* Q
if (start >= end) {
, M) n7 D0 w& M- T
return;
) C/ A2 Y* n4 M: ^
}
* |: ]) h$ ?2 T
//保证不溢出取start和end的中位数
, `% K8 S6 a. \" o
int mid = start + ((end - start) >> 1);
h1 C: d( o2 o5 |* ^
//递归排序并且合并
( j6 E, r e, r3 c" E
MergeSort(arr, start, mid);
' a" z$ O5 {( A- O
MergeSort(arr, mid + 1, end);
7 {4 ^# ?3 R. i' |
Merge(arr, start, mid, end);
& a8 \! L% k; A
}
5 ~% Q+ t' L( U) D
: Z+ b) X: V$ I# c2 q Z
//合并
c- v( R) I" v* |1 h
public static void Merge(int[] arr, int start, int mid, int end) {
2 y6 a2 }1 }# r- b; |+ \1 L( Q
int[] temp = new int[end - start + 1];
i' Z- _& Y: Q9 K. a$ e n5 g+ Q
int p1 = start;
! s% Y B% B1 a
int p2 = mid + 1;
8 V- z1 u2 C A1 L$ X" P
int p = 0;
. q0 `# }/ Y. g4 N
while (p1 <= mid && p2 <= end) {
8 e# Y' G% X, W( p0 j6 {
if (arr[p1] > arr[p2]) {
5 S: `2 H2 C! [& V' s V
temp[p++] = arr[p2++];
& f' v! Z$ F. D+ F- e! L
} else {
1 t B1 w" S# a2 g3 H3 } t) m# W
temp[p++] = arr[p1++];
2 I) v, a. P, w4 U
}
) N, O* n2 N4 _, R4 \9 X; D9 Z
}
* F' J1 G* [* I5 T4 ~3 h" r# i7 r3 |
while (p1 <= mid) {
% n. F) L6 n$ x+ d+ o# i2 q
temp[p++] = arr[p1++];
: D* Z; ?4 {# N5 z: E
}
. Q0 F8 d9 u: u5 k$ b) `# j: }6 r
while (p2 <= end) {
* X8 _/ T+ [ L# q/ e {+ L* l& o3 c/ ?
temp[p++] = arr[p2++];
1 d) y, g# b& G! @9 C$ H
}
* T- t' a! x* Q6 }$ ~8 \# X/ t5 ?
for (int i = 0; i < temp.length; i++) {
; v$ T7 n6 U: w1 z1 [$ D6 w
arr[i + start] = temp
;
7 ]* ]8 x+ B+ d9 z0 p l
}
S" x: l/ t' x: J9 U4 R. w
}
# k7 E; S0 Z: H9 h* j [, }: q
0 h$ q5 [' B/ V! z4 ^9 ?1 M+ y
public static void main(String[] args) {
6 [! v" x5 e# [" \; [, P( L
int[] a = {2, 4, 6, 1, 3, 7, 9, 8, 5};
! ]+ ]0 @9 e+ y2 N
MergeSort(a, 0, a.length - 1);
; N V( o, e# ]$ k! }. r! ^9 ^
System.out.println(Arrays.toString(a));
& ]* _5 c/ K) E: x* r* R( }2 @' J
}
, P3 g% u; @4 q4 w; D+ l& D
}
8 z8 q' i7 J$ @* a. L+ m% e& _
" S0 z2 Z7 z# S. u) B7 u3 C& z$ c
4 u, A1 \9 [; ?5 C
运行截图
& A# O1 F4 `- N; n; J6 }: t) V8 \
3 a2 q* V" l: _; h# T/ L E& x* n
2020-3-30 17:02 上传
下载附件
(89.18 KB)
2 b" V T/ Q( u$ e% K: V: `. t0 \, d: s; h8 Q
7 J; k; B# A& ~/ m# B
1、以上就是今天分享的归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)
$ R; P7 Y$ }) ?4 t. v- A% q
2、归并排序的额外空间复杂度可以做到O(1),但是非常难,不需要掌握,有一篇论文”归并排序内部缓存法”可以做到
& W- A3 Q) I# ?8 g. `
。
6 x0 ~7 z. J! ^6 I) r
原文链接:https://blog.csdn.net/weixin_37686415/article/details/105180035
/ R, _& j: t6 [* |. c/ d2 {
" C7 z4 }3 _% T
: V3 p1 a, L" L7 u
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5