1,实现random_shuffle:random_shuffle是STL中的一个模板算法,作用是随机重排列一对random access iterator之间的元素。基本思想是:假设序列有n个元素,先从所有元素中选一个放到位置1(即与位置1的元素交换),然后再从剩下的n-1个元素中选择一个放到位置2,以此类推。
2,qsort:partition之后双向递归。
qsort的实现:
View Code
1
#include
<
string
.h
>
/*
memcpy
*/
2
3
#define
SWAP_ELEM(pl, pr, size) do {\
4
char
temp[size];
/*
C99
*/
\
5
memcpy(temp, pl, size); \
6
memcpy(pl, pr, size); \
7
memcpy(pr, temp, size); \
8
}
while
(
0
)
9
10
char
*
partition(
char
*
pl,
char
*
pr, size_t size,
int
pivot_index,
11
int
(
*
compare_func)(
const
void
*
,
const
void
*
))
12
{
13
char
*
pivot;
14
char
*
next_less;
//
pointer to the next slot for elements
15
//
with value less than the pivot.
16
17
//
1, swap the pivot element to the last slot.
18
pivot
=
pl
+
size
*
pivot_index;
19
SWAP_ELEM(pr, pivot, size);
20
pivot
=
pr;
21
//
2, move elements with value less than pivot to the front of the sequence.
22
next_less
=
pl;
23
while
(pl
<
pr) {
24
if
(compare_func(pl, pivot)
<
0
) {
25
SWAP_ELEM(pl, next_less, size);
26
next_less
+=
size;
27
}
28
pl
+=
size;
29
}
30
//
3, swap the pivot to its place
31
SWAP_ELEM(next_less, pivot, size);
32
return
next_less;
33
}
34
35
void
do_my_qsort(
char
*
pl,
char
*
pr, size_t size,
36
int
(
*
compare_func)(
const
void
*
,
const
void
*
))
37
{
38
if
(pr
<=
pl) {
//
0 or 1 element
39
return
;
40
}
41
42
if
(pr
-
pl
==
size) {
//
2 elements
43
if
(compare_func(pl, pr)
>
0
)
44
SWAP_ELEM(pl, pr, size);
45
return
;
46
}
47
48
//
more than 2 elements, divide & conquer.
49
//
1, partition the sequence, pivot is chosen to be the leftmost element.
50
char
*
new_pivot
=
partition(pl, pr, size,
0
, compare_func);
51
//
2, recursively enter two subsequences.
52
do_my_qsort(pl, new_pivot
-
size, size, compare_func);
53
do_my_qsort(new_pivot
+
size, pr, size, compare_func);
54
}
55
56
/*
Implementation of libc-qsort.
*/
57
void
my_qsort(
void
*
base
, size_t nmemb, size_t size,
58
int
(
*
compare_func)(
const
void
*
,
const
void
*
))
59
{
60
char
*
pbase
=
base
;
61
char
*
plast
=
base
+
nmemb
*
size
-
size;
//
start addr of the last element.
62
63
do_my_qsort(pbase, plast, size, compare_func);
64
}
65
66
#undef
SWAP_ELEM
qsort的测试:
View Code
1
#include
<
stdio.h
>
2
#include
<
stdlib.h
>
3
#include
<
string
.h
>
4
#include
<
time.h
>
5
#include
<
assert.h
>
6
7
void
my_qsort(
void
*
base
, size_t nmemb, size_t size,
8
int
(
*
compare_func)(
const
void
*
,
const
void
*
));
9
10
#define
MAX_N 27
11
int
arr[MAX_N];
12
13
void
print_arr(
void
)
14
{
15
int
i;
16
17
for
(i
=
0
; i
<
MAX_N; i
++
)
18
printf(
"
%d
"
, arr[i]);
19
printf(
"
\n
"
);
20
}
21
22
/*
A simplified version of the STL algorithm random_shuffle
*/
23
void
my_random_shuffle(
int
*
arr,
int
n)
24
{
25
int
i;
26
27
srand(time(
0
));
28
for
(i
=
1
; i
<
n; i
++
) {
29
int
selected_index
=
rand()
%
(i
+
1
);
//
OK, forgive my using rand(),
30
//
which is of limited random digits.
31
int
temp
=
arr[selected_index];
//
swap to current position.
32
arr[selected_index]
=
arr[i];
33
arr[i]
=
temp;
34
}
35
/*
equivalent to:
36
for (i = n - 1; i > 0; i--) {
37
int selected_index = rand() % (i + 1); // select a random element.
38
int temp = arr[selected_index]; // swap to current position.
39
arr[selected_index] = arr[i];
40
arr[i] = temp;
41
}
42
*/
43
}
44
45
int
comp(
const
void
*
lhs,
const
void
*
rhs)
46
{
47
return
*
(
int
*
)lhs
-
*
(
int
*
)rhs;
48
}
49
50
int
main(
int
argc,
char
*
argv[])
51
{
52
int
i;
53
54
for
(i
=
0
; i
<
MAX_N; i
++
)
55
arr[i]
=
MAX_N
-
1
-
i;
56
//
case #1, sequence of 1 element
57
printf(
"
case #1: \n
"
);
58
my_qsort(arr,
1
,
sizeof
(arr[
0
]), comp);
59
print_arr();
60
//
case #2, sequence of 2 elements
61
printf(
"
case #2: \n
"
);
62
my_qsort(arr,
2
,
sizeof
(arr[
0
]), comp);
63
print_arr();
64
//
case #3, sequence of 3 elements
65
printf(
"
case #3: \n
"
);
66
my_qsort(arr,
3
,
sizeof
(arr[
0
]), comp);
67
print_arr();
68
69
//
case #4, all 0's
70
printf(
"
case #4: \n
"
);
71
for
(i
=
0
; i
<
MAX_N; i
++
)
72
arr[i]
=
0
;
73
my_qsort(arr, MAX_N,
sizeof
(arr[
0
]), comp);
74
print_arr();
75
76
//
case #5, ascent sequence.
77
printf(
"
case #5: \n
"
);
78
for
(i
=
0
; i
<
MAX_N; i
++
)
79
arr[i]
=
i;
80
my_qsort(arr, MAX_N,
sizeof
(arr[
0
]), comp);
81
print_arr();
82
83
//
case #6, descent sequence.
84
printf(
"
case #6: \n
"
);
85
for
(i
=
0
; i
<
MAX_N; i
++
)
86
arr[i]
=
MAX_N
-
1
-
i;
87
my_qsort(arr, MAX_N,
sizeof
(arr[
0
]), comp);
88
print_arr();
89
90
//
case #7, random permutated sequence.
91
printf(
"
case #7: \n
"
);
92
for
(i
=
0
; i
<
MAX_N; i
++
)
93
arr[i]
=
i;
94
my_random_shuffle(arr, MAX_N);
95
print_arr();
96
//
qsort(arr, MAX_N, sizeof(arr[0]), comp);
97
//
print_arr();
98
my_qsort(arr, MAX_N,
sizeof
(arr[
0
]), comp);
99
print_arr();
100
101
return
0
;
102
}

