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