当前位置:   article > 正文

快排QuickSort四种实现代码及简单优化_快速排序实现代码

快速排序实现代码

 一.优化

1.三数取中

        三数取中是一种优化快速排序算法的方法,可以提高排序的效率。传统的快速排序算法是以待排序数组的第一个元素为基准进行划分,但是如果待排序数组已经有序或接近有序,会导致快速排序的效率很低。三数取中的优化方法是选取待排序数组的头、尾和中间位置的三个元素,然后将这三个元素按照从小到大的顺序排列,取中间的元素作为基准。

  1. int GetMidIndex(int* a, int left, int right)
  2. {
  3. int mid = (left + (rand() % (right - left))) / 2;
  4. if (a[left] < a[mid])
  5. {
  6. if (a[mid] < a[right])
  7. {
  8. return mid;
  9. }
  10. else if (a[left] < a[right])
  11. {
  12. return right;
  13. }
  14. else
  15. {
  16. return left;
  17. }
  18. }
  19. else
  20. {
  21. if (a[left] < a[right])
  22. {
  23. return left;
  24. }
  25. else if (a[mid] > a[right])
  26. {
  27. return mid;
  28. }
  29. else
  30. {
  31. return right;
  32. }
  33. }
  34. return left;
  35. }

2.三路划分--指针法

        三路划分是对快速排序的一种优化方法,能够处理含有大量重复元素的数组。传统的快速排序将数组划分为两个部分,使得左半部分的元素都小于等于选定的主元素,右半部分的元素都大于等于主元素。

        而三路划分将数组划分为三个部分,分别是小于、等于和大于主元素的部分。具体实现方法如下:

        1. 随机选择一个元素作为主元素。
        2. 用两个指针分别指向数组的开头和结尾,并且用第三个指针记录当前位置。
        3. 从头开始遍历数组,若当前元素小于主元素,则将该元素与小于部分的下一个位置进行交换,并将小于部分的指针往后移动,当前位置也向后移动。
        4. 若当前元素等于主元素,则将当前位置向后移动。
        5. 若当前元素大于主元素,则将该元素与大于部分的前一个位置进行交换,并将大于部分的指针往前移动,但当前位置不变。
        6. 重复上述步骤,直到当前位置指针与大于部分的指针相遇。

        通过三路划分,能够将数组划分为小于、等于和大于主元素的三个部分,然后递归地对小于和大于部分进行排序。这样可以避免重复元素的多次比较,从而提高快速排序的效率。

  1. void QuickSort(int* a, int begin, int end)
  2. {
  3. if (begin >= end)
  4. {
  5. return;
  6. }
  7. //优化 三路划分 将等于key的收录到中间;
  8. int left = begin;
  9. int right = end;
  10. int cur = left + 1;
  11. srand(time(0));
  12. int midi = GetMidIndex(a, left, right);
  13. Swap(&a[left], &a[midi]);
  14. int key = a[left];
  15. while (cur <= right)
  16. {
  17. if (a[cur] < key )
  18. {
  19. Swap(&a[cur++], &a[left++]);
  20. }
  21. else if (a[cur] > key)
  22. {
  23. Swap(&a[cur], &a[right--]);
  24. }
  25. else if (a[cur] == key)
  26. {
  27. cur++;
  28. }
  29. }
  30. QuickSort(a, begin, left - 1);
  31. QuickSort(a, right + 1, end);
  32. }

 

 二.快排实现代码

1.hoare法

  1. int ParkSort(int* a, int left, int right)
  2. {
  3. int midi = GetMidIndex(a, left, right);//三数取中
  4. Swap(&a[left], &a[midi]);
  5. int keyi = left;
  6. while (left < right)
  7. {
  8. while (left < right && a[right] >= a[keyi])
  9. {
  10. --right;
  11. }
  12. while (left < right && a[left] <= a[keyi])
  13. {
  14. ++left;
  15. }
  16. Swap(&a[right], &a[left]);
  17. }
  18. Swap(&a[keyi], &a[left]);
  19. return left;
  20. }

2.挖坑法

  1. //快速排序--- 挖坑法
  2. int ParkSort2(int* a, int left, int right)
  3. {
  4. int midi = GetMidIndex(a, left, right);
  5. Swap(&a[left], &a[midi]);
  6. int key = a[left];
  7. int hole = left;
  8. while (left < right)
  9. {
  10. while (left < right && a[right] >= a[key])
  11. {
  12. --right;
  13. }
  14. a[hole] = a[right];
  15. hole = right;
  16. while (left < right && a[left] <= a[key])
  17. {
  18. ++left;
  19. }
  20. a[hole] = a[left];
  21. hole = left;
  22. }
  23. a[hole] = key;
  24. return hole;
  25. }

3.指针法

  1. int PartSort3(int* a, int left, int right)
  2. {
  3. int midi = GetMidIndex(a, left, right);
  4. Swap(&a[left], &a[midi]);
  5. int keyi = left;
  6. int prev = left;
  7. int cur = left+1;
  8. while (cur <= right)
  9. {
  10. if (a[cur] < a[keyi] && ++prev != cur)
  11. {
  12. Swap(&a[cur], &a[prev]);
  13. }
  14. cur++;
  15. }
  16. Swap(&a[prev], &a[keyi]);
  17. keyi = prev;
  18. return keyi;
  19. }

4.非递归法

  1. void QuickSortNonR(int* a, int begin, int end)
  2. {
  3. Stack st;
  4. StackInit(&st);
  5. StackPush(&st, end);
  6. StackPush(&st, begin);
  7. while (!StackEmpty(&st))
  8. {
  9. int left = StackTop(&st);
  10. StackPop(&st);
  11. int right = StackTop(&st);
  12. StackPop(&st);
  13. int keyi = PartSort3(a, left, right);
  14. if (keyi + 1 < right)
  15. {
  16. StackPush(&st, right);
  17. StackPush(&st, keyi+1);
  18. }
  19. if (keyi - 1 > left)
  20. {
  21. StackPush(&st, keyi - 1);
  22. StackPush(&st, left);
  23. }
  24. }
  25. StackDestroy(&st);
  26. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/1002818
推荐阅读
相关标签
  

闽ICP备14008679号