- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563404 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174244
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
: N/ X+ S0 b. d3 U# p4 ^3 f, g- Y X9 h9 p+ I7 A
神级基础排序——归并排序
" M( ~' z+ L+ i; G# L& {" F' R! u9 m; G( ]' v& I
归并排序的介绍
2 F' r; T' |. y% {. _% z3 q; ^3 x7 e/ n H$ V: T0 E4 `
归并排序(英语:Merge sort,或Mergesort),是创建在归并操作上的一种有效的排序算法,其时间复杂度为O(N*logN)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。
/ A1 D, s7 B7 o; j概念6 x# m' @' M. h% m
" z- y6 P5 i0 w( z! ~
是利用递归与分治的技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好序的半子表合并成越来越大的有序序列。
1 Y, j+ U X# _. @, p5 p核心思想
( }0 |6 N. b3 w& D+ j K1 ~2 l5 {4 l' N
将两个有序的数列合并成一个大的有序的序列。通过递归,层层合并,即为归并。
& R( f" `* D6 |
+ s+ F) _" W H
, `* Y5 z% g2 \' h. g" K/ y+ c实现代码
$ o: X; s! Y$ l: simport java.util.Arrays;
^8 x: d' D9 A: u' b
% M$ w/ Y5 v: }, a/**7 _( Q% H; M. L3 ]- A
* @Author god-jiang7 P( a; |" x: [7 X. L
* @date 2020/1/138 ?5 U" W; k- [! f+ \# B
*/! n) K1 d4 B0 _- q8 B
//归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)7 g) S+ v9 j: H6 k. y, Q6 l2 H
public class MergeSort {
. A- H& k C+ Z" u2 s public static void MergeSort(int[] arr, int start, int end) {
; I( d6 R% F$ ^4 \ x+ R7 g3 a7 B //分治的结束条件5 C% @7 d# x* {& O( M2 S
if (start >= end) {6 N, G- @. E: N( q
return;1 L) C/ P5 f p8 a0 o2 p: B* `4 l
}3 f" G' b- I) z
//保证不溢出取start和end的中位数0 w/ d1 M) X6 n, d Z2 Q
int mid = start + ((end - start) >> 1);
- V( q/ X5 Y; E: e; A% X. C //递归排序并且合并
( E2 J7 Z& a' Z) G+ Y2 s+ O4 A0 b. w$ U MergeSort(arr, start, mid);; ]2 G- ^7 w& j" Z
MergeSort(arr, mid + 1, end);7 X1 G2 V1 p' x5 F f4 ?+ E* T
Merge(arr, start, mid, end);
+ W/ @* Q) S2 P) Q. K }
0 K9 I* H7 X4 I: S
1 t0 L2 }5 \0 L: D9 [6 @ W //合并
6 A$ y% ^! [( r5 w1 G. @: I6 ^ public static void Merge(int[] arr, int start, int mid, int end) {9 m) P' |+ T; X7 \# K9 x
int[] temp = new int[end - start + 1];5 j' F" I! O7 e+ A! f9 S. J# y
int p1 = start;
' L' R! z. A0 J+ b/ `# y) I# ^: w int p2 = mid + 1;
! s8 X6 _+ X7 {2 X int p = 0;0 C4 o& W$ a7 e) d& A( ?, J' p
while (p1 <= mid && p2 <= end) {$ `) y- [- i+ P7 E) X6 F4 K
if (arr[p1] > arr[p2]) {
m1 x% \6 C7 B- I. A6 p7 }& u$ M temp[p++] = arr[p2++];
: {! \: G" r5 ~$ a* t } else {
; z" g0 v: _4 L temp[p++] = arr[p1++];
& r, j& \) W6 l' ?6 i: {* t# c }8 J$ c! z0 U6 }/ d2 l% }
}
" E5 a; L' G; R while (p1 <= mid) {
( m" ^4 V& R3 H& \ temp[p++] = arr[p1++];$ i& J Z! o6 r" H* d1 e! p
}$ ~1 X4 Q$ W9 j' p O" {5 n9 v: C' h
while (p2 <= end) {. H/ g% U+ s2 q* L- `8 V# N
temp[p++] = arr[p2++];8 f$ g' t5 ^( x. ]7 h7 Q
}
2 p7 b5 ^ g5 ?3 ?. y W for (int i = 0; i < temp.length; i++) {5 s# X5 V0 v. \& Z1 l# J
arr[i + start] = temp;
9 |/ L1 g1 p/ d* F8 S. E5 I# W( A% [ }
8 J% P0 Q: `$ ?" D; O2 m. n [5 d: ` }- l& q: R+ J6 g4 t( z. r: q' v# v
3 _ L+ }, o7 c public static void main(String[] args) {
1 q* Q- {5 k7 m int[] a = {2, 4, 6, 1, 3, 7, 9, 8, 5};; p, e8 [3 B9 P) h, l
MergeSort(a, 0, a.length - 1);# X9 d: }! S' h" C( C2 \$ e
System.out.println(Arrays.toString(a));" A2 y& H" ]- x2 k
}
% |; C+ Y; m* f& n" _}
g6 o( O9 x4 Z2 ?* U) J& o
) G0 z. _: M; b/ q( O, O3 O/ Q! B4 q9 i6 a; |0 V
运行截图
2 B5 ~1 Q+ d, }
' {* k0 E6 F' J, C4 `* N0 E. s( b
" M8 O6 Q% C! v2 U% F- _
4 W3 M5 O& q- K7 r9 H* \! W
1、以上就是今天分享的归并排序,时间复杂度为O(N*logN),空间复杂度为O(N)0 ~" O4 l) T( K9 Q
2、归并排序的额外空间复杂度可以做到O(1),但是非常难,不需要掌握,有一篇论文”归并排序内部缓存法”可以做到( V0 @6 ~( D8 i" ?
。3 n$ i( v% k2 s! p" S5 Z, a1 ]
原文链接:https://blog.csdn.net/weixin_37686415/article/details/105180035
7 d c, w% J: A) C! ]/ A5 f% b& p$ m& }
; q# r% m7 p, T) C7 p* h6 q
|
zan
|