zoukankan      html  css  js  c++  java
  • qsortrandom_shuffle

    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 }
  • 相关阅读:
    一、模板的渲染
    十六、ajax上传图片 mvc
    十五、API请求接口-远程服务器返回错误: (400) 错误的请求错误
    九、操作(在结果中搜索+查询该表,单独几个字段查询,通过子查询方式查询)
    一、Vue分页实现
    【2019-10-29】除非你变成你自己
    【2019-10-28】美好在于细节心态
    【2019-10-27】理智是罗盘,感情是大风
    【2019-10-26】日积月累的小惠生者
    【2019-10-25】从错误和失败中获得经验
  • 原文地址:https://www.cnblogs.com/qsort/p/2155923.html
Copyright © 2011-2022 走看看