qsort--random_shuffle

系统 1417 0

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 }

qsort--random_shuffle


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论