- 在线时间
- 480 小时
- 最后登录
- 2026-6-1
- 注册时间
- 2023-7-11
- 听众数
- 4
- 收听数
- 0
- 能力
- 0 分
- 体力
- 7823 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 2934
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1174
- 主题
- 1189
- 精华
- 0
- 分享
- 0
- 好友
- 1
该用户从未签到
 |
1 基础介绍
6 l. e9 G$ f: D# R$ T- m# e排序算法是很常见的一类问题,主要是将一组数据按照某种规则进行排序。
) |. {3 K5 h8 T+ Y7 ?& e7 b$ k1 W% Q# W& e$ J) O8 {1 ^
以下是一些常见的排序算法:$ Z0 _7 H9 O8 A6 g3 F/ K% `
+ S1 U/ m6 c" l+ N+ p冒泡排序(Bubble Sort)
% f0 ]2 C) A; y$ a
5 ]6 Y) ~" m3 R3 M* y* Z插入排序(Insertion Sort)
% r) K' X* ?: n1 ?" h& t: j/ a! I
9 o% B# ~( N, n+ P8 A选择排序(Selection Sort)4 Q. c2 n) f5 D; D+ s# `% C
- C2 \% D9 W( X: h! a$ N
归并排序(Merge Sort). y+ e4 ]7 s" B8 [$ ?' o
3 y, L& x# M7 X快速排序(Quick Sort)
% C8 U9 S/ \- W/ n7 [0 V+ R/ K7 r, i6 O$ N; i9 p
堆排序(Heap Sort). G. Y! ?( [' ~7 M: ]
4 s8 R1 q4 B, c
一、基本介绍介绍
! K' r" D3 H# ?. D7 J7 W k% K8 t1.1 原理介绍
4 @ ?4 h' B, Z8 D4 K. E( i归并排序(Merge Sort)是一种基于分治思想的排序算法,它将待排序的数组分成两部分,分别对这两部分递归地进行排序,最后将两个有序子数组合并成一个有序数组。它的时间复杂度为 O(nlogn)。
& X+ h" t0 I& ?2 `4 D
0 H1 x0 W# m# R# a归并排序的基本思路是将待排序的数组分成两个部分,分别对这两部分进行排序,然后将排好序的两部分合并成一个有序数组。这个过程可以用递归来实现。具体的实现步骤如下:# w$ n" r" J9 P d
- Q; B2 V% d) d
分解:将待排序的数组不断分成两个子数组,直到每个子数组只有一个元素为止。
" N( t+ J& [- ~9 s
! ?0 n% T9 Z# y3 G7 ~0 T' w; [5 v3 Z4 P合并:将相邻的两个子数组合并成一个有序数组,直到最后只剩下一个有序数组为止。
4 w' t* B4 @, s2 S7 }& v6 x$ | `4 a" N+ b k" X
合并的过程中,需要用到一个辅助数组来暂存合并后的有序数组。具体来说,假设待合并的两个有序数组分别为 A 和 B,它们的长度分别为 n 和 m,合并后的有序数组为 C,那么合并的过程可以按如下步骤进行:
- N& e0 S* b- t, q D- Z/ [! ^" s. p2 W! d" k4 V; a/ i
定义三个指针 i、j 和 k,分别指向数组 A、B 和 C 的起始位置。
% Y/ Q5 {3 p8 v" O
2 U+ v9 g( j: ?比较 A 和 B[j] 的大小,将小的元素放入 C[k] 中,并将对应指针向后移动一位。2 B& r, }0 `: t6 [$ w
# q; D/ q. j, K7 C; J
重复步骤 2,直到其中一个数组的元素全部放入 C 中。
j- E7 [$ V8 n, G7 V4 L3 h1 P/ t, Q! L
将另一个数组中剩余的元素放入 C 中。! f1 q @9 _' x$ T! h
/ k+ E$ e. \8 F# p7 M! ?& ^) h归并排序的优点是稳定性好,即对于相等的元素,在排序前后它们的相对位置不会改变。缺点是需要额外的空间来存储辅助数组。
# m2 S# a2 J2 V o+ w( i
2 ^0 {1 Y! q* X& w! P7 e$ C原理简单示例 4 x$ k) Z. r, m1 x. `
以下是一个示例,演示了如何使用归并排序对一个数组进行排序:
9 m+ e i$ i/ f+ _) {
, O3 T8 U ?8 o) T. I, d" L假设要对数组 [5, 2, 4, 6, 1, 3] 进行排序。: d) ~0 \; w7 @( t9 n& T
& N- H; M: x; T首先将数组分成两部分:[5, 2, 4] 和 [6, 1, 3]。
: t. |% P! u; g) e9 h/ p, c* H4 L- l
对左右两部分分别递归调用归并排序。对于左半部分,继续进行分解,将其分成两部分:[5] 和 [2, 4]。对于右半部分,也进行相同的操作,将其分成两部分:[6] 和 [1, 3]。
5 x6 n6 s4 v) A1 X6 `0 X/ R! s2 R/ v( q3 f$ w
对于 [5] 和 [2, 4],由于它们的长度都小于等于 1,因此直接返回它们本身。对于 [6] 和 [1, 3],同样返回它们本身。: j( z7 U4 x4 i/ n u) l3 h
1 s: R$ U5 V, B) J
接下来将排好序的左右两部分合并成一个有序数组。对于左半部分,由于它只有一个元素,因此可以直接将其作为有序数组。对于右半部分,需要将 [1, 3] 进行排序,排序后得到 [1, 3, 6]。
- x7 u) Z6 N$ {
( c6 |5 d% `* W9 E/ G/ M将排好序的左右两部分合并成一个有序数组。对于左半部分,指针 i 指向其起始位置,即 0;对于右半部分,指针 j 指向其起始位置,即 0。比较左右两部分的元素大小,发现左半部分的第一个元素 5 大于右半部分的第一个元素 1,因此将 1 添加到新的数组 sorted_arr 中,并将右半部分的指针 j 向后移动一位。此时,sorted_arr 的内容为 [1]。接着比较左半部分的第二个元素 2 和右半部分的第一个元素 3,发现左半部分的元素较小,因此将 2 添加到 sorted_arr 中,并将左半部分的指针 i 向后移动一位。此时,sorted_arr 的内容为 [1, 2]。接着继续比较左右两部分的元素大小,将它们依次添加到 sorted_arr 中。最终得到排好序的数组 [1, 2, 3, 5, 6]。
8 z9 H1 W+ c2 |7 c! o9 m% n5 N& [% n8 q; a% Q9 c Z4 |
因此,对于输入的数组 [5, 2, 4, 6, 1, 3],使用归并排序后得到的排好序的数组为 [1, 2, 3, 4, 5, 6]。4 i" l4 C* T7 Z6 f# V
7 a. ~$ z: I! E* }& x6 m1.2 复杂度 ! h' }* k" Z. _' {2 @7 t' J8 J7 V* r
归并排序的时间复杂度为 O(nlogn),其中 n 是待排序数组的长度。: d: [' k& d: f7 t8 d3 i# |
3 s# f% H5 x# S9 y
这个复杂度可以通过分治的思想来解释。
* j8 Q7 C4 G6 u5 `3 ^1 c+ e) T b1 R W+ }" X
首先将待排序的数组分成两部分,对每一部分递归调用归并排序,然后将两部分合并成一个有序数组。
, O2 o( a' L, C
4 i' N/ q9 x* b) i8 S每次递归调用都将数组的长度减半,因此需要进行 logn 次递归调用。在每个递归层次中,需要将两个有序数组合并成一个有序数组,这一过程需要线性时间 O(n)。因此,归并排序的总时间复杂度为 O(nlogn)。+ c5 W$ T& [6 r% t. }. G" U( G' p t
5 @* r% u& A" R& y- C
归并排序的空间复杂度为 O(n),其中 n 是待排序数组的长度。在排序过程中,需要使用一个辅助数组来存储合并后的有序数组。
& l) i, b) @- L6 p+ z) ^. T
A0 e5 n1 [+ x3 q' m8 X8 N这个辅助数组的长度等于待排序数组的长度,因此归并排序的空间复杂度为 O(n)。如果实现中使用链表来存储数据,空间复杂度可以降低为 O(1)。4 U* W, V$ C6 F
! o) ]2 K4 a% k3 V8 J0 S
1.3使用场景& ^ r; {& W; S* ~" f
归并排序的应用场景比较广泛,主要适用于以下几种情况:
, _% D, x8 w4 M a7 X0 m$ { x+ \& r0 M/ L: V
对于大规模的数据排序:归并排序的时间复杂度为 O(nlogn),相比于其他排序算法如冒泡排序、插入排序等,它在处理大规模数据时更加高效。) {& j+ {( x% z
* o3 C; s9 j$ G* Z* R+ ~
对于稳定排序的需求:归并排序是一种稳定排序算法,即对于相等的元素,在排序前后它们的相对位置不会改变。: B8 Y1 m, |7 I& A1 M' ]. x
" Y: R5 j. j F# t
对于需要保证排序稳定性的需求:归并排序是一种基于比较的排序算法,不依赖于数据的初始状态,具有较好的稳定性。
6 G. j% b$ I. s$ B ]! k' i3 F" v0 q( Q
对于需要多路排序的需求:归并排序可以轻松地扩展到多路排序,即将待排序的数组分成多个子数组,对每个子数组分别进行归并排序,然后将它们合并成一个有序数组。
% B1 W; K v1 E( ]. k4 w$ Y% Q0 v
6 G' Q1 O' U8 D% [, T" j对于需要外部排序的需求:归并排序可以应用于外部排序,即在排序过程中将数据存储在外部存储器中,而不是在内存中。在外部排序中,需要使用多路归并排序来合并不同的子文件。
( _- w4 y3 T) ~ O0 R# A4 ?6 @9 |) z: s( _4 V; [. C
总的来说,归并排序是一种高效、稳定的排序算法,适用于大规模数据的排序、需要保证排序稳定性的需求以及外部排序等场景。/ [, h8 D& \6 `" p
8 x6 F! A) X! r5 j7 Z- ]
二、代码实现
4 Z D9 X& l9 q1 c1 u2.1 Python 实现
: A: s2 s- l9 }8 f+ @以下是使用 Python 实现归并排序的完整代码:- def merge_sort(arr):
9 C, x8 g3 L( m% F | - if len(arr) <= 1:! |8 e. x g- X* F7 B
- return arr
; k; ]- S1 {0 I9 y' e -
( a- U6 B4 X, i* [* p5 z1 y - # 将数组分成两个部分
8 O0 U\" ?! W+ m0 z' V& i- u/ N - mid = len(arr) // 2
, s\" Q. W6 p, g# y4 w\" B - left_half = arr[:mid]
+ C! N. U( t' p- V - right_half = arr[mid:]# N4 P% r\" B. ]. q6 V\" z$ B
-
6 Y# l ^0 @( v( g1 A- _ - # 对左右两部分分别递归调用归并排序
* B: V) Q6 z- t - left_half = merge_sort(left_half) E6 q' @8 m, \* J0 l5 F& A
- right_half = merge_sort(right_half)+ P2 ~* K5 y4 u% @3 E% U, j( k
- : F/ ~/ h h C- f5 `
- # 合并左右两部分
. @8 [4 R. G2 ]% u - return merge(left_half, right_half)
6 P; Z7 ]\" y\" w2 S, d' i - , v2 s6 w* e; F
- def merge(left_half, right_half): n1 L5 [1 O' D: ?7 O9 I7 A% p
- i = j = 0 p$ M- s. `4 b* x2 E3 U6 a
- merged = []
6 t) R% z/ y& l7 O N - E( O+ X7 H' o* J- f8 i- K8 y% u
- # 比较左右两部分的元素,将较小的元素添加到 merged 中1 \' k* d# N) f# Y% K6 J: w
- while i < len(left_half) and j < len(right_half):
2 E/ E1 O ]8 z3 e8 D - if left_half[i] < right_half[j]:5 q% G5 w v1 u& }' C. T# }& |
- merged.append(left_half[i])/ F+ @9 x) `$ J4 `3 I, r' J; X0 E
- i += 1, X4 o8 I. }( B
- else:
6 }4 j1 l( Y0 | - merged.append(right_half[j])0 B0 s: z6 N0 k, e! z* ]4 V& A
- j += 1& D/ E! D\" K& r \- C9 d8 F0 M
- ; I5 m( H) z/ t. ~2 W5 j
- # 将左右两部分中剩余的元素添加到 merged 中
+ Z$ `! |* t; `1 Z! {\" U5 T; n9 E\" z - merged += left_half[i:]$ ~3 [. N; J+ z\" J, T
- merged += right_half[j:]\" n6 D% I8 n' {$ `
- # U* F\" D: W: K& h
- return merged
复制代码 代码讲解 这个实现使用了两个函数,一个是 merge_sort() 函数,用于进行递归调用,另一个是 merge() 函数,用于合并两个有序数组。下面对这两个函数进行详细讲解: merge_sort() 函数- def merge_sort(arr):7 ?, z( ?4 i! H$ t1 L7 Q$ _
- if len(arr) <= 1:
- t( @) S( Q- _' S' ~4 V) d - return arr
4 U) I& ]% C* E& \/ g$ p0 b - ! g5 ?0 m5 S4 d( o9 S0 `
- # 将数组分成两个部分 t% ]: V# W/ A) p) D2 t6 Y
- mid = len(arr) // 29 @) O0 ~% j\" |7 V% ~+ { O. v3 P
- left_half = arr[:mid]
q7 s6 j: u0 ^. |9 y - right_half = arr[mid:]
3 y, A- R6 D5 ^) S. ? -
/ ?$ R! D7 X0 H* x - # 对左右两部分分别递归调用归并排序
$ e0 J. G7 A% M) E& g, i W - left_half = merge_sort(left_half)
# N; W- _* f# A+ V2 I+ @6 V! @ - right_half = merge_sort(right_half), G, x( _! d L* Q1 I
- & f H$ J Y# z( I- p8 P
- # 合并左右两部分* M. b2 f3 j* V) I
- return merge(left_half, right_half)
\" q! V* x# L+ |8 m - ```
+ a+ I7 L! e5 A* H -
/ f/ e$ M6 C8 _3 ]5 _( N* @4 R - 这个函数使用递归的方式对数组进行排序。对于输入的数组,首先判断其长度是否小于等于 1,如果是,则直接返回该数组。否则,将数组分成两个部分,分别对左半部分和右半部分递归调用 `merge_sort()` 函数。最后,将排好序的左右两部分合并成一个有序数组,并将其作为结果返回。需要注意的是,此处的 `merge()` 函数是在 `merge_sort()` 函数中调用的,因为只有在递归到最底层时才会对单个元素进行排序,而在其他情况下需要将数组分成两部分进行递归调用。! W\" J8 j, c( `+ L4 U
-
复制代码 merge() 函数- def merge(left_half, right_half):
( S' G! @8 C- Q) y# ?& a& { - i = j = 0
5 S( m/ ~! ^3 Q4 Y - merged = []
1 Q* Q! [' U7 w- G3 h7 n* b) D+ E -
3 u. `( j G\" A: W% y - # 比较左右两部分的元素,将较小的元素添加到 merged 中
2 i, K& b% `& U! `' k. ? - while i < len(left_half) and j < len(right_half):% E# O+ y$ j; f6 L* f
- if left_half[i] < right_half[j]:5 f: s: p5 ~# ?0 s, V+ [! V
- merged.append(left_half[i])1 H: U1 V5 l% e$ l1 w: }+ y
- i += 1
b! p n' W7 @7 d0 J - else:
% J& c5 U$ M1 e5 I+ D8 |0 u$ `2 c9 ? - merged.append(right_half[j])
) U9 v4 n2 ]) g8 O - j += 1
/ |% ]6 n8 w/ O3 u -
2 i- [. A8 Y0 ], H - # 将左右两部分中剩余的元素添加到 merged 中
- A( E% [6 m; b- s! ?9 Z - merged += left_half[i:]% _( J ]2 J: F+ T, L3 [
- merged += right_half[j:]
! j- m' j& |3 Y: A2 Q -
; D- B2 H1 T6 J$ F7 |0 K: M% P - return merged
. J7 \7 I( E$ \! i - ```
]+ ?, F, w' A7 l4 y! r0 F - , Y# ?9 r8 G8 F! X/ q! O5 f; N7 [
- 这个函数用于合并两个有序数组。在函数内部,使用两个指针 i 和 j 分别指向左右两部分的起始位置,以及一个新的数组 merged 来存储合并后的结果。合并的过程中,不断比较左右两部分的元素大小,并将较小的元素加入 merged 中。最后,将左右两部分中剩余的元素添加到 merged 中,最终返回 merged。
复制代码 在实现归并排序时,需要注意以下几点:
& R. c1 X& j# ]3 ~, n7 { Z
( W$ ?* [# K8 f2 r: Q判断数组长度是否小于等于 1:这一步是递归调用的终止条件,防止出现无限递归的情况。
d# V; T9 D, A# X( ?
) F$ N9 V5 k) x( y将数组分成两部分:需要使用 Python 的切片操作来实现,将数组分成左右两部分。
" b+ P( |. q7 z# v; \- k( D
( B& {: N1 T2 P对左右两部分进行递归调用:将左右两部分作为参数传入 merge_sort() 函数并进行递归调用,直到数组长度小于等于 1。2 b2 r: X, V! |# ^0 E4 k' A% ?
' M. d" }+ S4 E* H& }" u合并两个有序数组:使用 merge() 函数将排好序的左右两部分合并成一个有序数组。& h. V8 x9 j8 o
. H! |2 E, t' D5 d2 ]! L: s7 q测试
2 [& W1 h4 m. ~/ \2 O6 N! ]7 Q9 e j在使用上述代码实现归并排序时,可以通过以下代码测试:- arr = [3, 5, 1, 9, 7, 2, 8, 4, 6]) M/ q$ A t! I- M6 }
- print(merge_sort(arr)) # 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]
复制代码 这个例子中,将一个无序的数组作为输入,调用 merge_sort() 函数进行排序,并输出排好序的结果。
6 h/ w* l! N- `7 `3 r; N* \1 Z8 _' l) j( e( A$ ~/ s+ f$ z @
总的来说,这个实现是一种简单而清晰的归并排序实现方式,适合初学者学习和理解。虽然这个实现的时间复杂度为 O(nlogn),但其空间复杂度为 O(n),因为在合并过程中需要额外的空间来存储排好序的元素,因此在处理大规模数据时可能会占用较多的内存。/ W5 C- Q8 |& Y3 X. ?/ H* E. Z1 [
2.2Java实现以下是使用 Java 实现归并排序的代码:
- public class MergeSort {
7 P3 W! X$ K0 N# j - public static void main(String[] args) {
% e4 y. K7 i# W! K; }9 ? - int[] arr = {3, 5, 1, 9, 7, 2, 8, 4, 6};
# Q I1 J! q( j7 C; Y2 ]0 d\" ` - mergeSort(arr, 0, arr.length - 1);
7 Z/ T\" x. N, s5 p - System.out.println(Arrays.toString(arr)); // 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]
$ ?0 i% L: v1 e* z! Z0 L - }3 J\" Y8 T3 Q\" x X/ k
-
3 @; Z- Z; U% |: h3 o - public static void mergeSort(int[] arr, int left, int right) {
: i# v6 I( `: X( { - if (left >= right) {
/ H5 W) i3 }, @- F - return;\" x: f+ X! X/ T7 ~# F5 I
- }
1 f3 q% H1 m! Z# R+ F - 5 A& q: c' z$ t- v6 }
- int mid = (left + right) / 2;
( _ ]' y3 Y2 Y0 M1 j - mergeSort(arr, left, mid);( g2 C2 h- P5 K' |. H' X. e
- mergeSort(arr, mid + 1, right);
Y+ @- m# U. W- L& f - merge(arr, left, mid, right);( s2 Y& A9 p: W9 Y, ]6 ^8 a
- }$ t7 ~: W/ M# d) y! G) j) y
- % Y! w7 X( d' T V {+ e
- public static void merge(int[] arr, int left, int mid, int right) {# Y7 P3 W- O9 l# l
- int[] temp = new int[right - left + 1];
7 J* Q: [7 M7 a0 m6 ]8 r8 g& ]! y+ u - int i = left, j = mid + 1, k = 0;
1 _5 \3 A$ g* J -
) O9 o5 Q$ M+ o* m' S - while (i <= mid && j <= right) {& _/ w/ z5 L+ Y$ j
- if (arr[i] < arr[j]) {* A\" I: Z) `$ M8 N8 |$ P5 q
- temp[k++] = arr[i++];9 \% h- Q3 O5 j O. h) z/ Y& |. ?
- } else {& e5 I; m. J: N. t2 i
- temp[k++] = arr[j++];
\" r3 y$ n( I3 W7 m& w2 x# I$ |% p* j - }
4 R- q- q) N\" w- j2 d+ _ - }& W+ J/ T& o! ]; q2 n; J\" P- j
- / O% `9 g& C2 J. B) x$ s) @/ x4 C
- while (i <= mid) {
- e: R4 w# M& Z$ c9 j- ~5 l - temp[k++] = arr[i++];+ ?3 |) f0 S0 f' `$ S; d
- }7 U, T# h- h ]4 e
-
- W0 D+ c% M' l9 D\" Q0 g- F0 I - while (j <= right) {
1 D' f# \7 s% W: ? - temp[k++] = arr[j++];% g4 q2 k% {: K s' G6 u; T2 D
- }
# ?2 G8 Y+ Y! z- e - + `; r$ o8 t* V2 r7 d0 x* o
- for (int m = 0; m < temp.length; m++) {
\" c( c, K* a+ ` - arr[left + m] = temp[m];/ C* s$ A. T9 Q
- }
9 Y' z0 W0 u9 s& T - }; y, Q) y6 [3 |/ n5 i, J
- }
复制代码这个实现也使用了两个函数,一个是 mergeSort() 函数,用于进行递归调用,另一个是 merge() 函数,用于合并两个有序数组。 下面对这两个函数进行详细讲解:
& J% P3 ~- |9 y' w/ }mergeSort() 函数- public static void mergeSort(int[] arr, int left, int right) {' ]0 u# F- a( A/ }' J
- if (left >= right) {
: S$ z0 Q7 l3 ]' D* z\" A) ^ - return; l; O$ W0 @# u% G- I) u\" U6 {
- }* C' v2 C# m; F6 O& N
-
, T {% G9 |0 t |% | - int mid = (left + right) / 2;
. k! r' }% a! z1 y/ V; ]3 G6 c - mergeSort(arr, left, mid);
+ s\" z4 D: ^3 L4 e - mergeSort(arr, mid + 1, right);- o5 v, p. |4 J, S
- merge(arr, left, mid, right);
: H2 {. R& Q& Y4 p\" n$ f - }
, l+ a; w2 z/ y! e6 |8 \9 } - 3 a5 F |: k# k
-
复制代码 这个函数使用递归的方式对数组进行排序。
) U4 z( ]5 ~: L" b
+ ?4 ]6 K* ?8 N* K$ Q" `* `对于输入的数组和左右下标,首先判断左下标是否大于等于右下标,如果是,则直接返回。否则,将数组分成两个部分,分别对左半部分和右半部分递归调用 `mergeSort()` 函数。
5 z( q- J; n# D/ [! ~% n3 T5 P. |7 s* c Z
最后,将排好序的左右两部分合并成一个有序数组,并将其作为结果返回。需要注意的是,此处的 `merge()` 函数是在 `mergeSort()` 函数中调用的,因为只有在递归到最底层时才会对单个元素进行排序,而在其他情况下需要将数组分成两部分进行递归调用。; ?* \! I6 t" O* N& ?5 A
merge() 函数- public static void merge(int[] arr, int left, int mid, int right) {% a. w, t. t& Q
- int[] temp = new int[right - left + 1];
0 `0 V- N4 B& D x - int i = left, j = mid + 1, k = 0;
3 V, i7 @/ N3 ?0 q- o. a -
4 [+ A6 d9 o! J' R' e! x3 x: F - while (i <= mid && j <= right) {
\" B6 a# V* J, ]/ I+ s - if (arr[i] < arr[j]) { O4 ]( P D3 {1 W\" A
- temp[k++] = arr[i++];2 |9 w$ T- I. k5 I' S' s
- } else {
) _/ F. E7 o* M i$ u\" v Y - temp[k++] = arr[j++];
; b8 X/ E9 d6 w - }3 M# ?) Y6 H: r0 E5 Y
- }
* v% P: A+ A; Z - % n( G. U% G: T3 [7 Q# k8 v0 q
- while (i <= mid) {9 v5 ?1 w8 h; [. |
- temp[k++] = arr[i++];8 }. g\" a1 N3 W
- }
, a/ E* w Q\" H( { -
/ C6 C: u% k1 s$ R - while (j <= right) {2 `5 U' M) A3 q( u4 v# Y\" A0 l
- temp[k++] = arr[j++];
& |: D c2 c& k\" u) p - }
3 P/ S0 E) D( c, z' u' @, z& z1 l - ^9 K, Q: P' k; _: K, U
- for (int m = 0; m < temp.length; m++) {! r R! u. S% n- ^4 q5 A
- arr[left + m] = temp[m];
( l8 L% q, j6 ~. P) \6 H/ U1 g- ] - }8 ?7 X: ^9 P5 Y4 J, {& o
- }4 q/ ]$ t1 I, G' V1 s\" q: y& o
-
复制代码 这个函数用于合并两个有序数组。在函数内部,使用两个指针 i 和 j 分别指向左右两部分的起始位置,以及一个新的数组 temp 来存储合并后的结果。
- v0 n0 }5 }6 b- b# V
4 H+ `7 E0 T4 o+ M5 T0 V合并的过程中,不断比较左右两部分的元素大小,并将较小的元素加入 temp 中。
. j. r" H" [( ]! ~3 m, }( v
5 L! A3 H; l8 G最后,将左右两部分中剩余的元素添加到 temp 中,最终将 temp 中的元素复制回原数组中。
8 B, C1 |0 _, X, U, _
9 Y( S$ I9 q0 N; i9 B1 y需要注意的是,在复制回原数组时,需要计算出每个元素在原数组中的位置。' u$ I! R+ q) ^5 m! v Q
0 d4 u$ u; q$ m- P' `) j
这个归并排序的实现是比较基础的,但是足以演示归并排序的算法思想和实现过程。当然,实际应用中可能需要对代码进行一些优化,比如可以对小数组使用插入排序来提高效率,或者使用迭代的方式来避免递归调用带来的额外开销。
! E1 [/ ~+ r; J7 Q; M3 z, l4 K- ]6 Y& H' \
& \6 H% ^' _8 Q/ ^( a8 ^( C) m7 p
, @; |) }1 q* S) v* n8 r; L4 N/ }( s6 R$ b6 _/ t9 H1 m9 ^# j4 A
7 t. ]' x/ V. P( n
3 a# h' _! W* X' ]1 x* h6 w B- X h( `7 G& s
|
zan
|