归并排序算法思想:
分而治之(divide – conquer);每个递归过程涉及三个步骤
第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作
第三, 合并: 合并两个排好序的子序列,生成排序结果.
- import java.util.Arrays;
- /**
- * java归并算法实现<br>
- *
- * @author JAVA世纪网(java2000.net, laozizhu.com)
- */
- public class Test {
- final static int MAXVALUE = 10000;
- static int[] L;
- static int[] R;
- public static void Merge(int[] A, int p, int q, int r) {
- int n1 = q – p;
- int n2 = r – q + 1;
- L = new int[n1 + 1];
- R = new int[n2 + 1];
- for (int i = 0; i < n1; i++) {
- L[i] = A[p + i];
- }
- for (int j = 0; j < n2; j++) {
- R[j] = A[q + j];
- }
- L[n1] = MAXVALUE;
- R[n2] = MAXVALUE;
- int i = 0, j = 0;
- for (int k = p; k <= r; k++) {
- if (L[i] <= R[j]) {
- A[k] = L[i];
- i++;
- } else {
- A[k] = R[j];
- j++;
- }
- }
- }
- public static void MergeSort(int[] A, int p, int r) {
- int q;
- if (p < r) {
- q = (p + r) / 2;
- MergeSort(A, p, q);
- MergeSort(A, q + 1, r);
- Merge(A, p, q + 1, r);
- }
- }
- public static void main(String[] args) {
- int[] inputArray = { 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4, 7, 1,
- 3 };
- // 方法1
- MergeSort(inputArray, 0, inputArray.length – 1);
- System.out.println(Arrays.toString(inputArray));
- Integer[] inputArray2 = { 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4,
- 7, 1, 3 };
- // 方法2
- new MergeSort().sort(inputArray2);
- System.out.println(Arrays.toString(inputArray2));
- }
- }
- class MergeSort {
- private Comparable[] bridge;
- /**
- * *利用归并排序算法对数组obj进行排序
- */
- public void sort(Comparable[] obj) {
- if (obj == null) {
- throw new NullPointerException(“The param can not be null!”);
- }
- bridge = new Comparable[obj.length];// 初始化中间数组
- mergeSort(obj, 0, obj.length – 1); // 归并排序
- bridge = null;
- }
- /**
- * 将下标从left到right的数组进行归并排序
- *
- * @param obj 要排序的数组的句柄
- * @param left 要排序的数组的第一个元素下标
- * @param right 要排序的数组的最后一个元素的下标
- */
- private void mergeSort(Comparable[] obj, int left, int right) {
- if (left < right) {
- int center = (left + right) / 2;
- mergeSort(obj, left, center);
- mergeSort(obj, center + 1, right);
- merge(obj, left, center, right);
- }
- }
- /**
- * *将两个对象数组进行归并,并使归并后为升序。归并前两个数组分别有序
- *
- * @param obj 对象数组的句柄
- * @param left 左数组的第一个元素的下标
- * @param center 左数组的最后一个元素的下标
- * @param right 右数组的最后一个元素的下标
- */
- private void merge(Comparable[] obj, int left, int center, int right) {
- int mid = center + 1;
- int third = left;
- int tmp = left;
- while (left <= center && mid <= right) { // 从两个数组中取出小的放入中间数组
- if (obj[left].compareTo(obj[mid]) <= 0) {
- bridge[third++] = obj[left++];
- } else
- bridge[third++] = obj[mid++];
- }
- // 剩余部分依次置入中间数组
- while (mid <= right) {
- bridge[third++] = obj[mid++];
- }
- while (left <= center) {
- bridge[third++] = obj[left++];
- }
- // 将中间数组的内容拷贝回原数组
- copy(obj, tmp, right);
- }
- /**
- * *将中间数组bridge中的内容拷贝到原数组中
- *
- * @param obj 原数组的句柄
- * @param left 要拷贝的第一个元素的下标
- * @param right 要拷贝的最后一个元素的下标
- */
- private void copy(Comparable[] obj, int left, int right) {
- while (left <= right) {
- obj[left] = bridge[left];
- left++;
- }
- }
- }
import java.util.Arrays; /** * java归并算法实现<br> * * @author JAVA世纪网(java2000.net, laozizhu.com) */ public class Test { final static int MAXVALUE = 10000; static int[] L; static int[] R; public static void Merge(int[] A, int p, int q, int r) { int n1 = q - p; int n2 = r - q + 1; L = new int[n1 + 1]; R = new int[n2 + 1]; for (int i = 0; i < n1; i++) { L[i] = A[p + i]; } for (int j = 0; j < n2; j++) { R[j] = A[q + j]; } L[n1] = MAXVALUE; R[n2] = MAXVALUE; int i = 0, j = 0; for (int k = p; k <= r; k++) { if (L[i] <= R[j]) { A[k] = L[i]; i++; } else { A[k] = R[j]; j++; } } } public static void MergeSort(int[] A, int p, int r) { int q; if (p < r) { q = (p + r) / 2; MergeSort(A, p, q); MergeSort(A, q + 1, r); Merge(A, p, q + 1, r); } } public static void main(String[] args) { int[] inputArray = { 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4, 7, 1, 3 }; // 方法1 MergeSort(inputArray, 0, inputArray.length - 1); System.out.println(Arrays.toString(inputArray)); Integer[] inputArray2 = { 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4, 7, 1, 3, 2, 6, 5, 2, 4, 7, 1, 3 }; // 方法2 new MergeSort().sort(inputArray2); System.out.println(Arrays.toString(inputArray2)); } } class MergeSort { private Comparable[] bridge; /** * *利用归并排序算法对数组obj进行排序 */ public void sort(Comparable[] obj) { if (obj == null) { throw new NullPointerException("The param can not be null!"); } bridge = new Comparable[obj.length];// 初始化中间数组 mergeSort(obj, 0, obj.length - 1); // 归并排序 bridge = null; } /** * 将下标从left到right的数组进行归并排序 * * @param obj 要排序的数组的句柄 * @param left 要排序的数组的第一个元素下标 * @param right 要排序的数组的最后一个元素的下标 */ private void mergeSort(Comparable[] obj, int left, int right) { if (left < right) { int center = (left + right) / 2; mergeSort(obj, left, center); mergeSort(obj, center + 1, right); merge(obj, left, center, right); } } /** * *将两个对象数组进行归并,并使归并后为升序。归并前两个数组分别有序 * * @param obj 对象数组的句柄 * @param left 左数组的第一个元素的下标 * @param center 左数组的最后一个元素的下标 * @param right 右数组的最后一个元素的下标 */ private void merge(Comparable[] obj, int left, int center, int right) { int mid = center + 1; int third = left; int tmp = left; while (left <= center && mid <= right) { // 从两个数组中取出小的放入中间数组 if (obj[left].compareTo(obj[mid]) <= 0) { bridge[third++] = obj[left++]; } else bridge[third++] = obj[mid++]; } // 剩余部分依次置入中间数组 while (mid <= right) { bridge[third++] = obj[mid++]; } while (left <= center) { bridge[third++] = obj[left++]; } // 将中间数组的内容拷贝回原数组 copy(obj, tmp, right); } /** * *将中间数组bridge中的内容拷贝到原数组中 * * @param obj 原数组的句柄 * @param left 要拷贝的第一个元素的下标 * @param right 要拷贝的最后一个元素的下标 */ private void copy(Comparable[] obj, int left, int right) { while (left <= right) { obj[left] = bridge[left]; left++; } } }
运行结果
[1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7]
[1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7]