0 R" M& E+ |5 u【史上最全内部排序算法】(直接插入、折半插入、希尔) +(冒泡、快速)+(简单选择、堆{含元素的增删})+(归并)+ (基数)排序 + 对比总结. Z. E9 k( M" j% o0 M8 }
文章目录2 I$ ?, t- l" g, v0 D- V
排序# A* l: P; ?5 B( g% M
1. 插⼊排序 ) n" f% N$ `$ _' z1 ^' [/ T( j8 K(稳定)1.1 直接插入排序【适用于顺序存储和链式存储的线性表】: T- _, ^' A7 }' X# t6 k- `; [
时间、空间复杂度2 l! J& t1 o+ {$ O, A$ @
(稳定)1.2 折半插入排序【先⽤折半查找找到应该插⼊的位置,再移动元素】 4 z% O# K, i" P' W* {/ Q- j- U- P! T时间、空间复杂度& y# b* B+ {. }2 `3 E' _
(不稳定)1.3 希尔排序【多次直接插入排序】 ; _' p# h C r+ v/ b: ]时间、空间复杂度 . ]. Z/ ], J& [5 V _, w" x! m2. 交换排序 " B% L0 j# c! i+ I% }: s2.1 (稳定)冒泡排序 - T1 Q$ p5 V- Z7 c" ^- G/ j时间、空间复杂度& W% B1 G% z7 ^( ~' ~6 h$ B1 S
2.2 (不稳定)快速排序【所有内部排序算法中,平均性能最优的排序算法】 2 G/ {5 C' ]7 R; T" r6 ?" ~时间、空间复杂度 * a, y9 l2 P+ ]; k& w3 K3.选择排序5 x. X& n; i) m8 {: |" w" e
3.1 (不稳定)简单选择排序 ) u4 q3 E% J& H时间、空间复杂度0 G$ H9 M% r0 h: X. `' O
3.2 (不稳定)堆排序 $ C$ [( b/ z# y① 什么是堆、⼤根堆(⼤顶堆)、⼩根堆(⼩顶堆)?1 S: G& m. P$ K+ A" Q# Y9 W
② 建⽴⼤根堆:BuildMaxHeap(int A[], int len)、HeadAdjust(int A[], int k, int len) , n2 b, K+ g# p4 ]5 g, @③基于⼤根堆进⾏排序:HeapSort(int A[], int len); \3 q: s2 i2 ^! {
时间、空间复杂度 , w1 g3 W+ x% C1 r5 n! p④ 补充:在堆中插⼊新元素 ! v/ s c$ \1 M* p( _3 R⑤ 补充:在堆中删除元素 ; u4 C$ \3 W' U* r6 N6 B0 b4. (稳定)归并排序 # R: Z" L$ g9 s4 X① 明白什么是“2路”归并?——就是“⼆合⼀”+ ~, b' Z2 G; C+ j
② 一次“2路”归并的代码【Merge(int A[], int low, int mid, int high)】 3 d. p8 a3 d9 b2 p J9 ^③递归进行分治思想【MergeSort(int A[], int low, int high)】 W* E2 n6 U: P: L( o④ 总实现代码 ) ^2 W$ a" P4 w, ^* e时间、空间复杂度2 B+ q M6 b+ t W
5. 基数排序 ' C) g) C" J. g内部排序算法总结 / a/ x, X* s' f0 D& d/ T/ X/ L排序3 \% B( k. m5 ?- m
排序:重新排列表中的元素,使表中元素满足按关键字有序的过程。$ N% ?9 z% a: _, U( N4 j
% z4 z% t- w7 m& k8 T# F
排序算法的评价指标:时间复杂度、空间复杂度、稳定性。 $ Q' ^: W% y, S3 w; e: f% n# s. _# h: S8 @; f
算法的稳定性:关键字相同的元素在使用某一排序算法之后相对位置不变,则称这个排序算法是稳定的,否则称其为不稳定的。 8 W$ J$ t- A' C6 O4 K稳定的排序算法不一定比不稳定的排序算法要好。 ( G) G$ j r4 m) j7 a' F* n: a" j/ M! a: O2 p8 K! F: s8 I
3 X v1 l5 M/ V" ~5 S; p8 ^
排序算法的分类: # @3 u5 z- p* u/ i* B* p内部排序 : 排序期间元素都在内存中——关注如何使时间、空间复杂度更低。! b o/ J/ f4 v2 `7 X
外部排序 :排序期间元素无法全部同时存在内存中,必须在排序的过程中根据要求,不断地在内、外存之间移动——关注如何使时间、空间复杂度更低,如何使读/写磁盘次数更少。 1 l% }8 X4 l J' A7 K" R . F3 E1 K. `& O; f3 ~. j' ^5 `各自排序算法演示过程参考:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html' j& X5 t" D" O: Q2 Q8 Y; W" e
7 u3 o, J: q& d1 a. L" O # m% F% a" K( K: X0 F 5 ^' F; ?7 a2 O# \8 \/ B- P" D1. 插⼊排序 5 v3 B) i7 u+ j1 a8 h(稳定)1.1 直接插入排序【适用于顺序存储和链式存储的线性表】 & r) y$ s/ T+ F基本操作就是:将有序数据后的第一个元素 插入到 已经排好序的有序数据中 从而得到一个新的、个数加一的有序数据 - h- c) m. X& @. n, X; H) [ + x" t( _: [! T; [7 \4 J# J$ ~算法解释:(从小到大) 5 h- b9 W3 w2 p g8 Q$ u; @ y' I
$ q0 i7 l' N5 z$ X4 ^算法三个步骤: " h# ?# s2 N, z) I* `! ~) N$ F0 _/ f7 d
先保留要插入的数字 2 Q' K5 C3 }) |4 t% b往后移4 v @: G- V( C! u$ m5 h4 n
插入元素) w# l6 o5 y9 I) o% i+ ?& i' m
1 a3 T; N0 t* W$ _// 对A[]数组中共n个元素进行插入排序 + M) {+ n5 n% l* ?" T. \! ]void InsertSort(int A[],int n){ , A) Q0 W1 _4 d. R1 Y3 \5 S int i,j,temp; 1 I J: R! I, ~0 S1 A for(i=1; i<n; i++)6 C( |/ _ s% F, ^- d' A) Z
{ 7 ] H) A+ `, p) A) C& x" z //如果是A[i-1] <= A,直接就是有序了,就不用下面的步骤【也是算法稳定的原因】9 D2 H7 U# a% L/ \& y% B1 T
if(A<A[i-1])/ I) `5 p7 B I
{ ' n* H1 ~% a& b' I
temp=A; //保留要插入的数字 ) U/ D' k' b9 m O5 u, n0 j# M3 Q$ z$ v5 I# m
for(j=i-1; j>=0 && A[j]>temp; --j)# C8 ^) e4 ~" H: j
A[j+1]=A[j]; //所有大于temp的元素都向后挪& i v9 ?+ n7 v
4 D% ~" j+ S" x8 H) G* c; X# C
A[j+1]=temp;//插入元素 7 z4 G/ w. J1 x. p/ Y } 5 O K/ `) ~6 C }5 g3 P$ b; U& S9 U, X% x) H1 e5 X% U
}. j: v8 q; K' B" i
& G+ G0 T: z4 h4 ~; o7 D1* x3 H% B i5 t+ g/ S: J; y
2% C8 V8 S% W) m. S
3 9 J2 H& k( V6 b$ V* S5 Y$ z7 N4 g. C% x a) F% Q55 J$ T; b d% h4 z& w, C/ P) k
6 7 k+ x' O3 o0 t7 p3 \+ p6 P" H% @& L7$ \& g ~/ @; Z/ U/ D
8 ; ?3 l! x8 A( C1 `* k& M9 % V# f( X+ ~2 {10" ]* S( E- M: G O
11 ! ]9 I( D! i/ B1 _3 m) F6 k9 x! Q12, r/ @& o p' P' D! s
134 R( u' ?0 P, I U- @! j. m7 w
14 + t; h$ Q x3 J! X15 2 C+ }8 D2 {0 r16 : J( n; }. W$ F0 I$ E17 * H L/ r$ F- M+ p4 l" z用算法再带入这个例子,进行加深理解 * M/ _2 y! t8 W3 ] ! T: L; i: c8 q" {( Y( x: R1 }- [: i- W+ M
带哨兵:4 h- p. n% F4 U' m
* Y# ^: G- |/ A
4 w3 s1 P& W& n6 c% J- D补充:对链表L进行插入排序 3 d. a( `' l: K( W/ ~+ ]+ H& B3 q
void InsertSort(LinkList &L){ : b2 K( L, ]1 u& c& o0 Z0 ` LNode *p=L->next, *pre;0 N1 Q$ h2 r) I- l' }
LNode *r=p->next; : Z2 p4 V d" W4 \9 M( L3 Q p->next=NULL;; e+ s8 j4 k) z4 p. i0 d. u& t
p=r; : L. \) {2 k8 v/ @+ ~8 x4 L while(p!=NULL){% ^! `- W/ b" e! a: N8 J
r=p->next; , E5 _+ U* v) Z0 U p pre=L; ! n& a: k0 H6 }. J2 @ while(pre->next!=NULL && pre->next->data<p->data) 2 s n& c/ `) y8 c @ pre=pre->next; Q0 R- \! F3 G% U# T1 ^
p->next=pre->next; 9 m' N( e. H. p; Z: g* c2 V9 f pre->next=p; 5 b! c8 j1 s: Y- V p=r; * _8 N6 X: p$ H1 @5 @9 d5 ` } ; a, p' Y$ I |9 n* B/ G}+ e, }' ^9 L* L# Y, }" H
1 ' ?" U- q G$ e6 b6 B2 H2+ b5 D: M" P+ g
3 % T* s- V! F+ Y& ~+ |4 : v$ ]0 @# K; i55 M- l3 k; c. _0 F1 @) M4 g
6 v/ _2 f" z: R' H3 D7, q# T2 a4 ?- I% M* ?2 V
83 _) D6 a0 [; d; s% {( M8 j( ?( t! s
9 . X. T. r5 S! p( r104 P& J/ m0 v {
11 5 m2 T8 M% y' D- O7 \, Q12 : c& o; T: x9 G; Q2 R/ P13# _! Z! M4 _. j2 h
14 $ k! {( r, B( P: \15 3 f5 Q4 E4 w. ~0 r, r3 c) D E时间、空间复杂度 5 k0 A) N# ]( A9 k3 r: T0 Z& n8 h0 A
& s4 j4 C0 a" L; p . P* h5 m8 ]/ \! p2 q 5 A, t d' {- @4 u0 v- u' H g+ i" k: m
// 用第一个元素将数组A[]划分为两个部分 ! S' s! \4 @9 fint Partition(int A[], int low, int high){ 1 Z! Q7 D+ o$ K4 T( Y" d //取首元素为pivot, Z7 i q9 `7 ~: U& S7 e
int pivot = A[low];* S" h3 {4 U2 K& b8 T9 D8 F. z/ U$ y
! w ?8 @: \! l$ u+ j while(low<high) 0 u# B: l/ @3 b9 F { ) p5 e* C0 O8 s, i5 i1 E& }3 _ //先是high开始向左移动( [! O3 S E- H
while(low<high && A[high]>=pivot)% V# p6 e$ l$ Z( X c
--high; " |$ h2 L" H2 u6 F& ?& ? A[low] = A[high];1 e+ [. s/ _' I+ Z; G6 _5 n7 C
0 h9 h, k! m* U //随后low向右移动 & ^4 r- \, q. \7 n& ^9 ]# F while(low<high && A[low]<=pivot) + q5 f( h; h9 w& Q# K, d4 O/ m& G ++low; 6 H; S, i% L0 B _. m8 P0 w6 R A[high] = A[low]; ; Y5 z7 J; W! s. X7 Z }* c: u" s% u6 G2 y
! w# c! \9 j/ G* T- s
//low=high的位置,即pivot放在的位置 6 U( J0 C' J: w6 x- C5 R- \ A[low] = pivot; " j% E5 F' E8 \* B) e' G" b/ y2 T, B" v S
return low;: Y ?+ I3 e: Q+ n v
} . T4 J6 M& y8 g% X/ d' J
9 f: ]) ~% @: Z7 o0 i2 n2 O
// 对A[]数组的low到high进行快速排序" _! |2 ]" ~ `$ G
void QuickSort(int A[], int low, int high){ . g3 c. E9 u8 r: Y if(low<high){4 R* X v/ [2 F
int pivotpos = Partition(A, low, high); //划分 5 N& D9 S' h5 J! r t QuickSort(A, low, pivotpos - 1); ) [2 G: x. X% a+ Q+ i) Z QuickSort(A, pivotpos + 1, high); + h, R2 h0 r" r4 V( H" S }$ I/ {3 {- Z) N
}# R3 ?7 H& f$ h) @7 `. n5 p3 B& F. N& l