首先来个插入排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include stdio.h > void { int *x *y } void { int for length ; for j
i ; swap(&x[j-1], } int { int insert_sort(a, for printf("%4d", return } |
在第二个for循环中,总是给t赋予相同值x[i],可以将其移出第二个for循环
1
2
3
4
5
6
7
8
9
10
11
|
void { int for length ; { int t
x [i]; for j
i ; x[j] x[j] } } |
一种简单的快速排序
排序数组时,将数组不停分成两个小部分,进行递归排序,分别用l和u表示数组排序部分的下界和上界,递归结束条件是待排序部分的元素个数小于2.
然后围绕某一值t对数组进行划分,重新组织x[a….b],并计算中间元素的下标m,使得所有<t在m左,所有>t在m右
|a <t |m >= t |i ?未处理部分 b|
1
2
3
4
|
m for if swap(++m, |
1
2
3
4
|
void { if return |
1
|
m |
1
|
for |
1
|
if |
1
|
swap(++m, |
1
2
3
4
|
swap(m, qsort(l, qsort(p } |
从右侧划分,完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
void { if return; m do { while swap(i, } while qsort2(l, qsort2(m } |
当元素相同时,为最坏情况o(n*n),使用双向划分可解决问题,变为o(nlog(n))
1
|
主循环中有两个循环,第一个内循环将i向右移过小元素,遇到大元素停止;第二个内循环向左移过大元素,遇到小元素停止。 |
1
|
主循环测试这两个下标若交叉,则交换它们的值。 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
void { if return int while { while while t ; if break; swap(i, } swap(l, qsort3(l, qsort3(j } |
1
|
|
以上都是按照第一个元素进行划分,随机选择划分元素可得到更好的性能 swap(l, randint(l, u));.
1
2
3
4
5
6
7
8
9
|
int { return } int { return } |
对于任意n元输入数组,快速排序时间都正比于nlogn。
快速排序会花费大量时间来排序很小数组,如果用插入排序累排序小数组,程序速会更快。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
void { if cutoff ) return; swap(l. int t
x [l], i
l , j
u
for { while while if break; swap(i, } swap(j, qsort4(l, qsrt4(j } void { qsort4(0, insert_sort(x, } |