微信
手机版
网站地图

我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤

2019-04-14 14:48:14 投稿人 : admin 围观 : 314 次 0 评论

快速排序

快速排序(Quicksort) 是一种排序算法,平均时间复杂度为:玩很6奖励O(n log n),最坏需要 O(n),但很少见,快速排序之所以叫快速排序,就是因为它比一般的排序算法要快。快速排序使用了分而治之的思想,步骤如下:

  1. 选择基准值(pivot)

  2. 将数组分成两个子数组:小于基准值的元素和大于基准值的元素

  3. 对这两个子数组进行快速排序

不同的选取基数值策略对排序性能都有很大的影响。

递归实现:

  1. public static void quickSort(int[] arr) {

  2. qsort(arr, 0, arr.length - 1);

  3. }

  4. private static void qsort(int[] arr, int low, int high) {

  5. System.out.println(String.format("qsort() -> low:%s, high:%s", low, high));

  6. if (low < high) {

  7. //将数组分为两部分

  8. int pivot = partition(arr, low, high);

  9. //递归排序左子数组

  10. qsort(arr, low, pivot - 1);

  11. //递归排序右子数组

  12. qsort(arr, pivo金熙美t + 1, high);

  13. }

  14. }

  15. private static int partition(int[] arr, int low, int high) {

  16. //枢轴记录

  17. int pivot = arr[low];

  18. while (low < high) {

  19. while (low < high && arr[high] >= 我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤pivot) --high;

  20. //交换比枢轴小的记录到左端

  21. arr[low] = arr[high];

  22. while (low < high && arr[low] <北外星光;= pivot) ++low;

  23. //交换比枢轴小的记录到右端

  24. arr[high] = arr[low];

  25. }

  26. //扫描完成,枢轴到位

  27. arr[low] = pivot;

  28. //返回的是枢轴的位置

  29. 何朋娟return low;

  30. }

非递归实现版:

  1. public static void quickSort(int[] array){

  2. if (array == null || array.length我的骄傲无可救药 == 1) return;

  3. //存放开始与结束索引

  4. Stack<Integer> s = new Stack<Integer>();

  5. //压栈

  6. s.push(0);

  7. s.push(array.length - 1);

  8. //谁告汪治怀利用循环里实现

  9. while (!s.empty()) {

  10. int right = s.pop();

  11. int left = s.pop();

  12. //如果最大索引小于等于左边索引,说明结束了

  13. 我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤 if (right <= left) continue;撸奶奶

  14. 岳守国 int i = partition(array, left, right);

  15. if (left < i - 1) {

  16. s.push(left);

  17. s.push(i Amireux- 1);

  18. }

  19. if (i + 1 < right) {

  20. s.push(i+1);

  21. s.push(right);

  22. }

  23. }

  24. }

归并排序

归并排序(mergesort)时间复杂度:O(n&唐依雪nbsp;log n),同样采用分治法实现。

步骤:

  1. 分割:递归地把当前序列平均分割成两半

  2. 归并:在保持元素顺序的同时将上一步得到的子序列集成到一起

递归实现:

  1. public static void sort(int[] data) {

  2. doSort(data, 0, data.length - 1);

  3. }

  4. public static void doSort(int[] data, int我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤 left, int right) {

  5. if (left >= right)

  6. return;

  7. System.out.println();

  8. // 找出中间索引

  9. int center = (left + right) / 2;

  10. // 对左边数组进行递归

  11. doSort(data, left, center);

  12. // 对右我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤边数组进行递归

  13. doSort(data, center + 1, right);

  14. // 合并

  15. merge(data, left, center, right);

  16. }

  17. /**

  18. * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序

  19. *

  20. * @param data

  21. * 数组对象

  22. * @param left

  23. * 梢青奈 左数组的第一个元素的索引

  24. * @par张建宗被骂am center

  25. * 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引

  26. * @param right

  27. * 右数组最后一个元素的索引

  28. */

  29. private static void merge(int[] data, int left, int center, int right) {

  30. S我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤ystem.out.println(String.format("->\nleft:%s,center:%s,right:%s\nbefore:", left, center, right));

  31. Util.printArray(data);

  32. // 临时数组

  33. int[] tmpArr = new 张补胜int[data.length];

  34. // 右数组第一个元素索引

  35. int mid = center + 1;

  36. // third 记录临时数组的索引

  37. int third = left;

  38. // 缓存左数组第一个元素的索引

  39. int tmp = left;

  40. while (left <= center &&揭秘深圳现代镖局 mid <= right) {

  41. // 从两个数组中取出最小的放入临时数组

  42. if (data[left] <= data[mid]) {

  43. tmpArr[third++] = data[left++];

  44. } else {

  45. tmpArr[third++] = data[mid++];

  46. }

  47. }

  48. // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)

  49. 施索恩工作室 while (mid <= right) {

  50. tmpArr[third++] = data[mid++];

  51. }

  52. while (left <= center) {

  53. tmpArr[third++] = data[left++];

  54. }

  55. // 将临时数组中的内容拷贝回原数组中

  56. // (原left-right范围的内容被复制回原数组)

  57. while (tmp <孙立石= right) {

  58. data[tmp] = tmpArr[tmp坝坝舞wagcw++];

  59. }

  60. System.out.println("\nafter:");

  61. Util.printArray(data);

  62. System.out.println("\n<-\n\n");

  63. }

非递归实现:

  1. public static void sort(int[] arr) {

  2. int[] orderedArr = new int[arr.length];

  3. for (int i = 2; i < arr.length * 2; i *= 2) {

  4. for (int 我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤j = 0; j < (arr.length + i - 1) / i; j++) {

  5. int left = i * j;

  6. int mid = left + i / 2 >= arr.length ? (arr.length - 1) : (left + i / 2);

  7. int right = i * (j + 1) - 1 >= arr.length ? (arr.length - 1) : (i * (j + 1) - 1);

  8. int start = left, l = left, m = mid;

  9. while (l < mid && m <= right) {

  10. if (arr[l] < arr[m]) {

  11. orderedArr[start++] = arr[l++];

  12. } else {

  13. orderedArr[start++] = arr[m++];

  14. 互插 }

  15. }

  16. while (l < mid)

  17. 我叫mt4,【算法篇】快速排序与归并排序-Java,烧烤 orderedArr[start++] = arr[l++];

  18. while (m <= right)

  19. orderedArr[start++] = arr[m++];

  20. System.arraycopy(orderedArr, left, arr, left, right - left + 1);

  21. }

  22. }

  23. }

关于它们具体的工作原理网上多的是,但真的把代码整整齐齐的写出来的还真不多,白看不如一敲,我还是直接放代码比较好。具体的详细原理介绍可以随便搜一下有助于理解,我这里就不 copy 啦。

最近在学算法,后面我还会继续把常见的几种排序法放出来。

最近真的超级忙,卿本红妆之冷情太子忙的没空写博客,不过过了这段时间会保证一定频率的输出,不管多忙都得抽出时间。


相关文章

标签列表