分治算法-归并排序快速排序

Posted peiwei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治算法-归并排序快速排序相关的知识,希望对你有一定的参考价值。

分治算法:把一个任务,分成形式和原任务相同,但规模更小的几个部分任务(通常是两个部分),分别完成,或只需要选一部完成。然后再处理完成后的这一个或几个部分的结果,实现整个任务的完成。

分治的典型应用:归并排序、快速排序

 


归并排序动态图:

技术分享图片

 1 package com.inbreak.cnblogs.sort;
 2 
 3 import com.inbreak.cnblogs.Helper;
 4 
 5 /**
 6  * 归并排序:
 7  * 分别前一半、后一半排序
 8  * 将前半部分、后半部分归并到一个有序数组,再拷贝到原数组中。
 9  *
10  * @author inbreak
11  * @create 2018-07-19
12  */
13 public class MergeSort {
14 
15     public static void main(int[] a, int size) {
16         Helper.printArray(a);
17         int[] tmp = new int[size];
18         mergeSort(a, 0, size - 1, tmp);
19         Helper.printArray(a);
20     }
21 
22     public static void mergeSort(int[] a, int s, int e, int[] tmp) {
23         if (s < e) {
24             int m = (s + e) / 2;
25             mergeSort(a, s, m, tmp);
26             mergeSort(a, m + 1, e, tmp);
27             merge(a, s, m, e, tmp);
28         }
29     }
30 
31     public static void merge(int[] a, int s, int m, int e, int[] tmp) {
32         //将s~m和m+1~e合并到tmp数组
33         int pt = 0;
34         int pi = s;
35         int pj = m + 1;
36         //先把左半边或者右半边的拷贝完
37         while (pi <= m && pj <= e) {
38             if (a[pi] < a[pj]) {
39                 tmp[pt++] = a[pi++];
40             } else {
41                 tmp[pt++] = a[pj++];
42             }
43         }
44         //上面的while循环结束,其中的一半全部复制完成,下面的2个while循环只有一个会走
45         //这趟归并的左半部分
46         while (pi <= m) {
47             tmp[pt++] = a[pi++];
48         }
49         //这趟归并的右半部分
50         while (pj <= e) {
51             tmp[pt++] = a[pj++];
52         }
53         //将tmp复制到原数组
54         for (int i = 0; i < e - s + 1; i++) {
55             a[s + i] = tmp[i];
56         }
57     }
58 
59 }

 

 


 快速排序:

技术分享图片

 

 1 package com.inbreak.cnblogs.sort;
 2 
 3 import com.inbreak.cnblogs.Helper;
 4 
 5 /**
 6  * 快速排序:
 7  * 1)设k=a[0], 将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k右边,和k相等的,不关心在k左右出现均可 (O(n)时间完成)
 8  * 2) 把k左边的部分快速排序
 9  * 3) 把k右边的部分快速排序
10  *
11  * @author inbreak
12  * @create 2018-07-19
13  */
14 public class QuickSort {
15 
16     public static void main(int[] a, int size) {
17         Helper.printArray(a);
18         quickSort(a, 0, size - 1);
19         Helper.printArray(a);
20     }
21 
22     public static void quickSort(int[] a, int s, int e) {
23         if (s >= e) {
24             return;
25         }
26         int k = a[s];
27         int pi = s;
28         int pj = e;
29         //while循环结束 pi == pj 后的这个就是a[pi] == k,确定这个左边数都比k小,右边都比k大
30         while (pi != pj) {
31             //先从右指针pj往左遍历
32             while (pj > pi && a[pj] >= k) {
33                 pj--;
34             }
35             //pj循环结束后 pj中的值a[pj] < k,此时交换内容,因为默认第一个就是k也就是a[pi]
36             Helper.swap(a, pi, pj);
37             //从左指针pi往右遍历
38             while (pj > pi && a[pi] <= k) {
39                 pi++;
40             }
41             //交换
42             Helper.swap(a, pi, pj);
43         }
44         //针对左、右半部分的递归
45         quickSort(a, s, pi - 1);
46         quickSort(a, pi + 1, e);
47 
48     }
49 }

 

以上是关于分治算法-归并排序快速排序的主要内容,如果未能解决你的问题,请参考以下文章

算法排序02——归并排序介绍及其在分治算法思想上与快排的区别(含归并代码)

分治算法的完美使用----归并排序

python代码实现归并排序(Merge Sort )

归并排序和快速排序(算法系列)

《数据结构与算法之美》09——排序归并排序与快速排序

算法 | 分治 | 归并排序