- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564650 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174618
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
& q% Y0 @4 y1 _! i! \4 }' w: w9 p3 x$ E, l% p1 h2 X
神级基础排序——归并排序
; Y4 o) ]6 [& j2 h
/ p7 \/ ?4 `& d: S1 k0 h' h2 K归并排序的介绍( S. A( r8 ]) l
8 W+ j. b4 H) }' b/ V# q归并排序(英语:Merge sort,或Mergesort),是创建在归并操作上的一种有效的排序算法,其时间复杂度为O(N*logN)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。
' F9 I6 x* b9 H概念
+ s4 x( s- D, f& i. T, {
, ?6 u/ d, U6 n2 f& |, [8 _是利用递归与分治的技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好序的半子表合并成越来越大的有序序列。+ M2 U1 E$ D2 g2 g0 d I
核心思想
7 M" H( Y6 s/ R+ H+ |$ K% n! Y" P4 m& N2 k
将两个有序的数列合并成一个大的有序的序列。通过递归,层层合并,即为归并。4 U: D3 o' L7 a+ |
, k6 M/ d3 B' j2 W! S. j
, U# P: k7 w$ n; D5 X实现代码0 \8 y4 `6 K/ ]3 t. D7 f: h: F
import java.util.Arrays;
# l. G" h/ k& q4 v6 c* }) e% @6 u% H9 S8 h# N, t3 ~
/**) \6 j* w9 m0 c5 f o/ M X
* @Author god-jiang
9 O) F) H1 x9 X! T8 D * @date 2020/1/13' }* W. f0 d4 _
*/
G% P0 M* H# E% @( k//归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)
$ e' _! y3 l/ b1 K; ]public class MergeSort {3 y, K3 X% j! ?9 d4 I
public static void MergeSort(int[] arr, int start, int end) {+ g) M; [9 g& n0 W; ~3 U' {! Y
//分治的结束条件* `: u7 o$ ^3 H0 U2 ^
if (start >= end) {
+ G0 |, w6 ]: K6 N return;+ t3 n, z/ b, J5 D
}. x( V9 H! M( m
//保证不溢出取start和end的中位数
# U G$ W+ _- I int mid = start + ((end - start) >> 1);
% L; h" w3 W. X/ N# ]1 C7 ]( ^ //递归排序并且合并
3 W5 J9 L( {, ~1 }- {& X% W MergeSort(arr, start, mid);, p1 R. X' U! f1 z9 |% {
MergeSort(arr, mid + 1, end);' p% S% w) b* Z( d, s8 U! X+ G* `
Merge(arr, start, mid, end);
) d. x: D( _0 z5 b }8 C& P$ ]2 q0 v- Q: }
5 f4 r* K" [- R" K: ]* d //合并- s( p! s" E% W1 _9 n& V
public static void Merge(int[] arr, int start, int mid, int end) {, J8 ] H+ \7 F0 a% l h# l3 J
int[] temp = new int[end - start + 1];6 b) s) Y1 Z7 I1 B/ _
int p1 = start;
5 C" y) d6 z- m* i2 V& o2 r int p2 = mid + 1;
+ R3 Z8 o. ~* y1 ^. ? int p = 0;
4 p* Y; t: \) m; s" q8 S2 Q1 [ R* \ while (p1 <= mid && p2 <= end) {& Q, d* O+ }+ q7 ~& G- ^ Q" V
if (arr[p1] > arr[p2]) {% @. t5 e2 @! K, h+ K
temp[p++] = arr[p2++];# X& @; f! ^& d. l- d. \& V8 K! [
} else {' j0 H6 b% v, R
temp[p++] = arr[p1++];
/ q" h+ ?9 M% v7 v { }
+ W5 `# f! V, @. m! E+ q }
6 D" K8 z4 r* K3 w; B: T while (p1 <= mid) {3 q, k' X' a2 W C) Y$ F3 `
temp[p++] = arr[p1++];
Y3 V$ Q" S/ P6 d7 `& Z' R }
5 D: u o+ f( Q! J- R7 R# H7 P; D" ] while (p2 <= end) {0 Y3 U% f/ g" L: k+ \; `/ i# N
temp[p++] = arr[p2++];
/ D* c( }& p; |# I# L }" e3 X, t1 H$ d: e9 N9 Y4 U8 F
for (int i = 0; i < temp.length; i++) {
, R0 J7 j* W. r; V* _, ? arr[i + start] = temp;! K# A2 i' r9 s2 |* j( N
}) k: ?2 B4 N, }' m+ J% g+ p
}( r; \% E) w& q; D$ `* a' r
. T5 H5 c, [' C& l+ t* C
public static void main(String[] args) {' n5 F3 m; O: P" y
int[] a = {2, 4, 6, 1, 3, 7, 9, 8, 5};
( Z3 o3 q( r$ k* H/ F# {! w MergeSort(a, 0, a.length - 1);2 ], Z/ L5 {' h$ p) x/ Y: k" }
System.out.println(Arrays.toString(a));
2 I+ f5 ~: q! R }% j4 ~! G# g' V$ Z
}
2 q5 b- m% ~; j. h" b8 F0 G! V/ I7 M% V5 V7 `, @0 N
- b( F* G' O3 ?6 N; v$ Y6 d运行截图
( T+ h/ B# M$ W4 a# C& s0 D& h6 n- P; H u1 W/ p: p7 V& R
$ m( p) s4 c9 Y
6 U! q: a0 H5 D1、以上就是今天分享的归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)
, L' s0 M q9 t, q2、归并排序的额外空间复杂度可以做到O(1),但是非常难,不需要掌握,有一篇论文”归并排序内部缓存法”可以做到, i* O" Y, w b: Y9 a. U
。
4 T0 g: ]% J+ [. Y& d原文链接:https://blog.csdn.net/weixin_37686415/article/details/105180035( f: q& q. _# W' |4 B
: `5 b7 p# N& R
8 C# g( I# ~- i0 V8 ?6 q! p" D/ h |
zan
|