码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2018-07-19 22:30:48      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:return   tle   tmp   logs   src   分治算法   idt   .so   ==   

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

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

 


归并排序动态图:

技术分享图片

 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 }

 

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

标签:return   tle   tmp   logs   src   分治算法   idt   .so   ==   

原文地址:https://www.cnblogs.com/peiwei/p/9292078.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!