- 在线时间
- 481 小时
- 最后登录
- 2026-8-25
- 注册时间
- 2023-7-11
- 听众数
- 4
- 收听数
- 0
- 能力
- 0 分
- 体力
- 7859 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 2946
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1177
- 主题
- 1192
- 精华
- 0
- 分享
- 0
- 好友
- 1
该用户从未签到
 |
1 基础介绍
0 L+ e) B* w+ a: d排序算法是很常见的一类问题,主要是将一组数据按照某种规则进行排序。
& p& h' ]! O! i, }5 ]1 J: _# [4 z9 K# ]) ~3 C G \
以下是一些常见的排序算法:3 V# ?+ T- p2 e" g* \$ G
1 ^& v7 r4 Y- K, Q7 J0 M, k
冒泡排序(Bubble Sort)
+ B8 S! I4 {* @$ j. O( D& R% k$ _
插入排序(Insertion Sort)
+ [) c" ]: i; b" h+ _5 s, [ Q6 \6 U" i& |$ X% ~& g
选择排序(Selection Sort)0 T" Z' J+ S1 R8 Q' I! E
0 x7 o, m" R2 I0 s* j0 }& J
归并排序(Merge Sort)& [/ }3 ^1 f1 u- X
0 `4 h9 ]( m" W1 m2 f4 \
快速排序(Quick Sort)5 U5 |! ^9 ^; T( G1 o8 U2 X. @! {1 w
6 y8 M% g2 Z8 g/ R3 ~$ j% {堆排序(Heap Sort), d4 P/ j6 s/ `
4 F! }) o% C6 Q% ~一、基本介绍介绍
- N* X9 a/ x+ p& B1 B. R1.1 原理介绍
( G3 _, w/ T, w/ z8 @7 A m" d" `" ~$ [归并排序(Merge Sort)是一种基于分治思想的排序算法,它将待排序的数组分成两部分,分别对这两部分递归地进行排序,最后将两个有序子数组合并成一个有序数组。它的时间复杂度为 O(nlogn)。8 K( c! A9 _. o( v. M# F
4 m( A7 L: h1 R. f+ t% ]归并排序的基本思路是将待排序的数组分成两个部分,分别对这两部分进行排序,然后将排好序的两部分合并成一个有序数组。这个过程可以用递归来实现。具体的实现步骤如下:
, P2 {0 P' q7 R6 f9 B( G/ q6 p [8 j7 T" p( F4 ]+ K( v# Q! F
分解:将待排序的数组不断分成两个子数组,直到每个子数组只有一个元素为止。6 X2 F9 a" T+ n0 @
) f' m$ X5 ]' ?" P! Z合并:将相邻的两个子数组合并成一个有序数组,直到最后只剩下一个有序数组为止。
& z& y( c, c) j5 b- @" Y; [2 n* `' {" ~: N
合并的过程中,需要用到一个辅助数组来暂存合并后的有序数组。具体来说,假设待合并的两个有序数组分别为 A 和 B,它们的长度分别为 n 和 m,合并后的有序数组为 C,那么合并的过程可以按如下步骤进行:5 j7 q0 @0 ~+ V" Q3 X2 v
0 R9 C0 f* X8 Q! S+ Y定义三个指针 i、j 和 k,分别指向数组 A、B 和 C 的起始位置。* P* V7 |% i! y8 ?7 c
- i% H$ V) |' \% Y$ I- w- l比较 A 和 B[j] 的大小,将小的元素放入 C[k] 中,并将对应指针向后移动一位。
7 F: {3 q# l% h( q
) x% K" W: z R) i& O! G V% b重复步骤 2,直到其中一个数组的元素全部放入 C 中。+ i/ x ]/ o# I2 U) W/ F
8 X$ {/ B( J2 e% g6 Z将另一个数组中剩余的元素放入 C 中。
8 g8 [. Z& e9 j' g" r) K' K, E, K2 ^2 V& y) }
归并排序的优点是稳定性好,即对于相等的元素,在排序前后它们的相对位置不会改变。缺点是需要额外的空间来存储辅助数组。, ?( Z) g5 }/ |0 e
$ j* S D$ {0 f% X, l' P2 ?原理简单示例 3 S# K3 L3 Y# G8 D% k7 W; ?
以下是一个示例,演示了如何使用归并排序对一个数组进行排序:2 \6 }- g9 q+ o( N
/ o J) V( }) ^( v% \( S& D& U3 a
假设要对数组 [5, 2, 4, 6, 1, 3] 进行排序。
3 @& u( G& E0 h8 g" q5 t0 P, c
* e- y" d; w5 K$ f首先将数组分成两部分:[5, 2, 4] 和 [6, 1, 3]。- k5 {+ M. @$ D8 i
1 n. y+ H, R; q; U; W- V
对左右两部分分别递归调用归并排序。对于左半部分,继续进行分解,将其分成两部分:[5] 和 [2, 4]。对于右半部分,也进行相同的操作,将其分成两部分:[6] 和 [1, 3]。& o: D/ W' u7 l4 w
! G3 I) d x; ^对于 [5] 和 [2, 4],由于它们的长度都小于等于 1,因此直接返回它们本身。对于 [6] 和 [1, 3],同样返回它们本身。
8 j9 I+ c6 V5 ]5 b3 ?2 \% O$ L2 g. A" t8 i, d8 t+ K$ @( g2 k
接下来将排好序的左右两部分合并成一个有序数组。对于左半部分,由于它只有一个元素,因此可以直接将其作为有序数组。对于右半部分,需要将 [1, 3] 进行排序,排序后得到 [1, 3, 6]。: I ~! r- G+ Z+ @6 R9 K
2 k% M1 y* H# Z6 l, s将排好序的左右两部分合并成一个有序数组。对于左半部分,指针 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]。% S' h, n8 C0 p1 C
. M: Y. m$ E; E4 }) w) l: z因此,对于输入的数组 [5, 2, 4, 6, 1, 3],使用归并排序后得到的排好序的数组为 [1, 2, 3, 4, 5, 6]。
) [' u) Q# z& W* c7 E5 j+ s
, R/ J# Y7 X- m Z! P7 u1.2 复杂度 8 \: s$ R/ G$ E9 J+ V
归并排序的时间复杂度为 O(nlogn),其中 n 是待排序数组的长度。
/ u) g. W4 ^7 z' H$ G
2 s% z# u! U2 K* y8 Y. {这个复杂度可以通过分治的思想来解释。
& m8 [- r, p* g! E2 @( I3 j" V! Z* Y9 Y9 W& C2 k
首先将待排序的数组分成两部分,对每一部分递归调用归并排序,然后将两部分合并成一个有序数组。
' ^. u, w$ B; o3 o- W: c3 x
0 }, E0 Q; Y" f r# t( g/ w( h每次递归调用都将数组的长度减半,因此需要进行 logn 次递归调用。在每个递归层次中,需要将两个有序数组合并成一个有序数组,这一过程需要线性时间 O(n)。因此,归并排序的总时间复杂度为 O(nlogn)。
* @; I& L/ R( s% k2 ^5 D5 s- L
) V8 o$ x- R3 E! z7 ?归并排序的空间复杂度为 O(n),其中 n 是待排序数组的长度。在排序过程中,需要使用一个辅助数组来存储合并后的有序数组。) W! Q N. r9 K0 D7 v$ U! Y
( F' e2 f. p$ E, G j) Y这个辅助数组的长度等于待排序数组的长度,因此归并排序的空间复杂度为 O(n)。如果实现中使用链表来存储数据,空间复杂度可以降低为 O(1)。
' \4 u8 n( P3 H7 x% S
r4 o& b _' T1 I5 W1.3使用场景# L3 y5 x5 d8 U7 B, G9 a' K
归并排序的应用场景比较广泛,主要适用于以下几种情况:, \$ _8 A# q$ q. q! q
I# R1 q4 o" l p; L' b* B对于大规模的数据排序:归并排序的时间复杂度为 O(nlogn),相比于其他排序算法如冒泡排序、插入排序等,它在处理大规模数据时更加高效。6 i2 C8 u; p; O" K# i
# A, i6 f* L% |: p( t& Y6 [4 Q2 ?
对于稳定排序的需求:归并排序是一种稳定排序算法,即对于相等的元素,在排序前后它们的相对位置不会改变。# `4 G+ j4 c3 A* [) f: ?
6 M# J+ B! c4 w3 b9 v) D8 H对于需要保证排序稳定性的需求:归并排序是一种基于比较的排序算法,不依赖于数据的初始状态,具有较好的稳定性。
# q# @8 ^3 X1 m9 O5 u. G8 [
' l7 ~ N4 s' z, N+ ?$ q对于需要多路排序的需求:归并排序可以轻松地扩展到多路排序,即将待排序的数组分成多个子数组,对每个子数组分别进行归并排序,然后将它们合并成一个有序数组。
* Y0 C7 ~: [1 i H2 p) x
: a% ?* u) c4 U. w1 j( J+ h7 p对于需要外部排序的需求:归并排序可以应用于外部排序,即在排序过程中将数据存储在外部存储器中,而不是在内存中。在外部排序中,需要使用多路归并排序来合并不同的子文件。
% W. t9 z' O; H( J
/ F [3 C6 _- d' ]( c! }' ?总的来说,归并排序是一种高效、稳定的排序算法,适用于大规模数据的排序、需要保证排序稳定性的需求以及外部排序等场景。
2 s5 Y5 b! a# n" d3 z, b$ L/ \2 D3 k/ u7 g W# W
二、代码实现
. T% g# W9 a. @* m7 |2.1 Python 实现) f0 i, _; \, s/ m f$ O
以下是使用 Python 实现归并排序的完整代码:- def merge_sort(arr):
* c2 ]. J( ^- E0 y5 D9 C0 q/ X - if len(arr) <= 1:9 H- j! w, N$ }2 f; b0 `3 `
- return arr
# D w1 a2 [ N: n/ M' _ -
% i8 ~ {* u: r% H6 t2 S0 d+ u2 W# h - # 将数组分成两个部分2 w3 P\" [( M) L/ v. r
- mid = len(arr) // 2
7 `9 j4 i4 D8 b g e - left_half = arr[:mid]
4 ]* _6 K4 L Z# R3 H - right_half = arr[mid:]- p, t/ G( y1 D- X# W& F% e6 E/ H
- , J- g6 B9 x6 ]) e
- # 对左右两部分分别递归调用归并排序$ I% f# |6 \ t+ O4 d5 J
- left_half = merge_sort(left_half)
7 o& c/ V! Z) [ - right_half = merge_sort(right_half), J# @1 F4 h C, G7 A+ \
-
+ c\" k s5 [/ K- y% G+ e) G - # 合并左右两部分
) u( }8 B6 I1 O - return merge(left_half, right_half)\" X* s' O4 W. h% y C
- . O5 l* R% {! q\" x7 F9 D
- def merge(left_half, right_half):0 F! Z9 a* r- ^$ a
- i = j = 06 }0 ?/ V\" N+ T1 T4 i\" m9 O0 n3 ]
- merged = []1 z( B3 L: V r0 m* o
- # y% M I- P' [& W
- # 比较左右两部分的元素,将较小的元素添加到 merged 中$ e' O$ q\" O1 {8 n$ t\" E t% Q/ {
- while i < len(left_half) and j < len(right_half):* c4 G4 k! | f( t2 y3 K! h
- if left_half[i] < right_half[j]:# E. z/ Q+ c4 R% T4 N
- merged.append(left_half[i])1 [% U; x( Y- C, [
- i += 1
1 a: Y/ m3 ]# H3 j - else:0 B n3 e. J: Q% q% Q- m
- merged.append(right_half[j])
3 g' Q! A) e: h9 `$ H - j += 1
$ P0 _+ [! K' a: Q - # L6 b' ^) b' V+ N! {
- # 将左右两部分中剩余的元素添加到 merged 中4 {3 X. m9 @8 Y7 S) V8 P
- merged += left_half[i:]
; w$ g. G- H) a- u+ A; O( o - merged += right_half[j:]9 h' G# W' x) _8 f# S2 S
-
, S; v, Z, \1 o! N - return merged
复制代码 代码讲解 这个实现使用了两个函数,一个是 merge_sort() 函数,用于进行递归调用,另一个是 merge() 函数,用于合并两个有序数组。下面对这两个函数进行详细讲解: merge_sort() 函数- def merge_sort(arr):
! @, K2 a5 k% z# Z& r6 G - if len(arr) <= 1:) K1 F6 i) B) n\" x- p/ r
- return arr
/ i4 L* U' a7 M5 ?9 J; H! u3 h8 ] - ) c; L7 J$ y7 {0 O
- # 将数组分成两个部分& J+ y, ~) i! P! v- k: {4 ?
- mid = len(arr) // 2
1 R( w+ V7 ]( h. l - left_half = arr[:mid]# ^! z! B: @ E
- right_half = arr[mid:]- h$ v& Z. V; L& y% `6 q
-
7 y L+ e1 d) E+ J& v - # 对左右两部分分别递归调用归并排序. n8 ?1 u8 C5 {! C5 w0 O
- left_half = merge_sort(left_half)
. \0 _8 @3 k8 c& P - right_half = merge_sort(right_half)' ~/ u1 r5 z2 U) Z( m9 `$ k
-
( m. v, c' Y1 o/ L$ J - # 合并左右两部分 s; E1 Y6 A8 Z! L
- return merge(left_half, right_half)# U: x$ y5 ~7 v. ~! v( E+ G
- ```6 c/ ]/ Q: }3 x' i* r
- ; |# V g7 k) b
- 这个函数使用递归的方式对数组进行排序。对于输入的数组,首先判断其长度是否小于等于 1,如果是,则直接返回该数组。否则,将数组分成两个部分,分别对左半部分和右半部分递归调用 `merge_sort()` 函数。最后,将排好序的左右两部分合并成一个有序数组,并将其作为结果返回。需要注意的是,此处的 `merge()` 函数是在 `merge_sort()` 函数中调用的,因为只有在递归到最底层时才会对单个元素进行排序,而在其他情况下需要将数组分成两部分进行递归调用。 o, k& X+ K0 l) V' u( z\" M
-
复制代码 merge() 函数- def merge(left_half, right_half):
% O y2 }# d% U' V4 T3 y1 D* c& r; { - i = j = 0( X$ \' x. E5 H5 `
- merged = []
, f: K4 H) H& W* G - : P7 @6 I3 c6 C% g4 R
- # 比较左右两部分的元素,将较小的元素添加到 merged 中9 [3 n+ Y$ t4 u6 w4 o7 T4 i
- while i < len(left_half) and j < len(right_half):
6 S* ]* b# p1 b# K: k - if left_half[i] < right_half[j]:( @' s, }. V& o$ d5 Z9 z\" u' n
- merged.append(left_half[i])' ]3 ^ r I, \3 j0 R- n
- i += 1
0 G) x/ u/ O0 {! b8 r! ]* Z7 c2 ~ - else:
' }' u. \9 n3 w7 v: |5 e+ S, z\" }* M - merged.append(right_half[j])
4 g/ {( \. `6 _! { - j += 19 t) M& o9 H+ L3 f. O: r9 _6 \; k
- 0 r9 ^( f9 i7 Q ~* n( j. X1 T
- # 将左右两部分中剩余的元素添加到 merged 中; k\" d u+ J! e, x4 r9 Q7 @
- merged += left_half[i:]9 L% B: A7 ?6 m% J\" Y, s
- merged += right_half[j:]
) v0 P r: S+ T4 O& c5 }4 a2 _ -
\" l4 v3 F5 ~: ^ - return merged9 N$ f! N @; y\" _8 a e
- ```
7 g2 u\" N' Q! Y1 z - $ f0 L% e7 t- i x
- 这个函数用于合并两个有序数组。在函数内部,使用两个指针 i 和 j 分别指向左右两部分的起始位置,以及一个新的数组 merged 来存储合并后的结果。合并的过程中,不断比较左右两部分的元素大小,并将较小的元素加入 merged 中。最后,将左右两部分中剩余的元素添加到 merged 中,最终返回 merged。
复制代码 在实现归并排序时,需要注意以下几点:
0 } ?; C. C6 i5 W6 A+ C
* U. w! B' S$ K( H; ?$ i判断数组长度是否小于等于 1:这一步是递归调用的终止条件,防止出现无限递归的情况。
5 A7 t! ]7 B1 q8 M$ X
- i9 h- c: h2 P9 [ S4 W/ y& W将数组分成两部分:需要使用 Python 的切片操作来实现,将数组分成左右两部分。& y* o# g& S* [+ E3 {( ?
2 |! R( y. f$ C7 T: D7 Z' Q$ @/ s8 U2 i
对左右两部分进行递归调用:将左右两部分作为参数传入 merge_sort() 函数并进行递归调用,直到数组长度小于等于 1。
8 Z6 v7 x/ U: k9 K2 I6 m2 f$ Q( ?# a; ~8 P& e
合并两个有序数组:使用 merge() 函数将排好序的左右两部分合并成一个有序数组。
( q( @' G. ?3 ?# D& {+ E
5 L* j! a1 r ~. v. Y测试
+ V3 d9 b% ^( H0 U! G$ u在使用上述代码实现归并排序时,可以通过以下代码测试:- arr = [3, 5, 1, 9, 7, 2, 8, 4, 6]# P' [+ X. j! ~\" \( d
- print(merge_sort(arr)) # 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]
复制代码 这个例子中,将一个无序的数组作为输入,调用 merge_sort() 函数进行排序,并输出排好序的结果。/ @! m( m& M0 j; y
. W1 ^8 I; i* W9 T
总的来说,这个实现是一种简单而清晰的归并排序实现方式,适合初学者学习和理解。虽然这个实现的时间复杂度为 O(nlogn),但其空间复杂度为 O(n),因为在合并过程中需要额外的空间来存储排好序的元素,因此在处理大规模数据时可能会占用较多的内存。. c4 \" o5 ]+ d8 t* v
2.2Java实现以下是使用 Java 实现归并排序的代码:
- public class MergeSort {
5 Q: W; D- j% S4 S2 E6 _7 w( @ - public static void main(String[] args) {
4 d+ U4 Q% S% D% C; h - int[] arr = {3, 5, 1, 9, 7, 2, 8, 4, 6};
5 K$ z; l7 V\" Q+ G; ] - mergeSort(arr, 0, arr.length - 1);
) O0 c3 t* {6 ~/ ^9 q) z - System.out.println(Arrays.toString(arr)); // 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]
* v5 s3 i: X1 X9 c - }
; X$ | Z* j6 \9 @4 m -
8 A( r. X' h: H- C; x\" { - public static void mergeSort(int[] arr, int left, int right) {% x6 i' f3 C# N5 Y' m3 S
- if (left >= right) {
/ I6 N5 P8 V! V4 A( P - return;
) S9 P! U+ o7 W m - }
: n; a! y- q, X+ G6 X/ I - 2 f1 n. b. ], Z3 l) {9 h+ n/ o3 G
- int mid = (left + right) / 2;8 m6 Z. u& a9 J! ~
- mergeSort(arr, left, mid);
' A% I4 D4 S, q6 a - mergeSort(arr, mid + 1, right);
4 x7 V9 x5 H\" f: G1 g - merge(arr, left, mid, right);
1 d& v4 B! p' Q9 |. w - }
y- B5 |2 @3 p -
1 U4 q3 e- o) p/ I0 {( } v - public static void merge(int[] arr, int left, int mid, int right) {
, H( L1 j0 J* x3 s H+ p# a8 V2 M - int[] temp = new int[right - left + 1];
$ L8 \$ P& r! T+ y/ H1 e3 J - int i = left, j = mid + 1, k = 0;) @* u4 k- R+ ?8 n8 i: s5 n) H4 A
-
p\" ?* e: W1 m; {; {) T - while (i <= mid && j <= right) {8 Q. \8 u7 b5 t
- if (arr[i] < arr[j]) {
7 Z- i r% m) O& \ - temp[k++] = arr[i++];- }# x: J' o3 x g- u
- } else {9 Y6 k: a+ |( D
- temp[k++] = arr[j++];
/ z/ t$ {, m7 y- P7 r4 g$ j - }
7 T) ^4 w7 ^. J/ u/ Q - }0 V; ^ g& ?5 }1 H\" r0 `
- & ^+ F% T2 `0 T2 j6 C
- while (i <= mid) {
- C2 n3 u- x$ l5 F- @. w - temp[k++] = arr[i++];& `' r! t' z5 O3 P v
- }. G @9 R8 f; K) i+ T6 [- n
-
3 b) b2 Y, a# n V1 n. V - while (j <= right) {
8 I5 |! D0 l4 F: a - temp[k++] = arr[j++];' `\" s( |3 \2 B& J$ F& K
- }
$ E: z9 Q( B+ l2 s3 N -
2 g% F1 @6 O7 U; ~7 P2 _ - for (int m = 0; m < temp.length; m++) {2 v9 V# v' P4 c+ u8 Q& R. J
- arr[left + m] = temp[m];
. X& D+ ]. d. k5 d- n; q - }
\" \$ Q& |1 d* C - }. @! C- d( u4 g# h- t
- }
复制代码这个实现也使用了两个函数,一个是 mergeSort() 函数,用于进行递归调用,另一个是 merge() 函数,用于合并两个有序数组。 下面对这两个函数进行详细讲解:
7 Q- v# G! \- c* R9 q: lmergeSort() 函数- public static void mergeSort(int[] arr, int left, int right) {- e3 F8 a; v8 j9 Q8 q$ T8 z
- if (left >= right) {\" D0 U5 O* E6 r! r5 Z# } j e
- return;. Q1 Q\" ~- c\" O1 V
- }
* ^; W# ?, j3 o8 [8 a; ^% p -
2 b$ n3 K6 ^4 B) t) }; }1 r, s - int mid = (left + right) / 2;; K0 L( Q ]0 |) l
- mergeSort(arr, left, mid);' }0 a1 \( R' g T2 v- s0 F
- mergeSort(arr, mid + 1, right);
/ o' W) e- \8 _ - merge(arr, left, mid, right);
! b\" u, w7 I7 M: B\" p w - }
% _- K$ x0 e6 X - % i9 E+ l2 A8 }9 a\" M0 E, R
-
复制代码 这个函数使用递归的方式对数组进行排序。
/ w& {. p4 L* ?8 V' Z& f) Q/ p
5 w3 |6 `4 A. G [$ t" U- c对于输入的数组和左右下标,首先判断左下标是否大于等于右下标,如果是,则直接返回。否则,将数组分成两个部分,分别对左半部分和右半部分递归调用 `mergeSort()` 函数。
2 {. }* y5 o/ ]/ I# p( G% H) E
. \1 \' q$ a9 F8 Q" ` s3 k! A最后,将排好序的左右两部分合并成一个有序数组,并将其作为结果返回。需要注意的是,此处的 `merge()` 函数是在 `mergeSort()` 函数中调用的,因为只有在递归到最底层时才会对单个元素进行排序,而在其他情况下需要将数组分成两部分进行递归调用。0 |& b# c6 f6 r+ h; g
merge() 函数- public static void merge(int[] arr, int left, int mid, int right) {
% e8 M* J/ n4 a/ F, H4 {9 i9 n\" w. g - int[] temp = new int[right - left + 1];+ h8 K1 b4 O\" c, ^- i; W
- int i = left, j = mid + 1, k = 0;
7 P$ K: R3 H& r1 \$ G0 B* n - 4 N: p& s+ J7 l! b
- while (i <= mid && j <= right) {
1 T* H\" m9 X, l - if (arr[i] < arr[j]) {
9 v* ~& j+ h! F' A - temp[k++] = arr[i++];
* t/ v1 \% k- X; u - } else {: e N: G3 f9 [6 Y1 h
- temp[k++] = arr[j++];
& M+ J/ P! K, y* \# h - }# b6 h/ b l, g4 h8 q
- }* V) p* x/ C9 ~& W* K& e: J\" Z
-
2 V& \3 q6 V7 M O+ B, f - while (i <= mid) {% K3 Y9 {3 z& S) g
- temp[k++] = arr[i++];4 W7 M4 X2 d# \\" E; N2 D
- }
# t% l, x$ t, K# h; B -
% D$ ]3 k3 [4 [1 C - while (j <= right) {
. S4 r. j- [2 c* { - temp[k++] = arr[j++];
\" a3 P0 } t% f8 ^8 x/ X - }
- H A2 N# E3 g' _\" e0 z -
5 ]; F$ I% P* N) P4 n) v - for (int m = 0; m < temp.length; m++) {5 U$ p% Q+ \2 B& E2 E% `\" b
- arr[left + m] = temp[m];0 l& Z4 H/ ^' l( S
- }) ]& Q* {1 Y% V+ {$ } C
- }
+ d) f+ s. P$ |9 E: Y2 q, r6 {1 | -
复制代码 这个函数用于合并两个有序数组。在函数内部,使用两个指针 i 和 j 分别指向左右两部分的起始位置,以及一个新的数组 temp 来存储合并后的结果。
4 g% N' l- N6 @0 A0 _, C5 [2 P& W' v ?
合并的过程中,不断比较左右两部分的元素大小,并将较小的元素加入 temp 中。5 h* ~- I. d1 f9 U" i
( a& j9 _$ _# W- j最后,将左右两部分中剩余的元素添加到 temp 中,最终将 temp 中的元素复制回原数组中。) U. W; u" o: m* f% y s
% z! V5 h- L7 }7 f1 g: K9 s需要注意的是,在复制回原数组时,需要计算出每个元素在原数组中的位置。+ ?( ]2 l4 X" B. g& S: n
, N4 z% x2 j! g1 d; r5 r7 x
这个归并排序的实现是比较基础的,但是足以演示归并排序的算法思想和实现过程。当然,实际应用中可能需要对代码进行一些优化,比如可以对小数组使用插入排序来提高效率,或者使用迭代的方式来避免递归调用带来的额外开销。
: }$ K% b {+ K1 I9 W5 \* |
6 _$ u; O3 v. X" Z2 ?& X3 K0 H* ]9 e2 e
5 {, s* y& b/ ^. ^. F
) w4 {5 d0 Z& F; [# O
* p# n* a1 X/ V8 V1 W! G0 g( {; |
0 ]- z9 ~. k5 h/ Y( _( h% I$ `+ g$ Z9 m! a9 Y
|
zan
|