归并排序
一、归并的思想
考试结束后要将全省的学生成绩进行排名,可以依次将每个班级,每个学校,每个市,每个省的排名合并后再排名就可以得到最终的全省排名,这就用到了归并的思想。
看看下面这张图,就能很清晰的说明归并的思想了。红色框中就是无序的序列,通过两两合并后再合并,最终获得了一个有序的数组。
注意观察它的形状,很像一颗倒置的完全二叉树。通常涉及到完全二叉树结构的排序,效率一般都不会低。
二、算法实现
归并排序就是利用归并的思想实现的排序方法。它的原理是:
假设初始序列有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2的有序子序列(n为奇数时,存在一个长度为1的子序列),再两两归并,如此反复,直至得到一个长度为n的有序序列为止。这种排序方法称为多个2路归并排序排序
/** * 归并排序 * * 归并排序的思想: * 1.两个已排序的数组,可以进行归并将其合并到第三个数组中。 * 2.借用1中的思想,如果将一个数组分成左右两部分, * * @author lp * */ public class MergeSort { public static void mergeSort(int[] data, int left, int right) { if (left < right) { // 找出中间索引 int center = (left + right) / 2; // 对左边数组进行递归 mergeSort(data, left, center); // 对右边数组进行递归 mergeSort(data, center + 1, right); // 合并 merge(data, left, center, right); } } private static void merge(int[] data, int left, int center, int right) { int[] tmpArr = new int[data.length]; int mid = center + 1; // third记录中间数组的索引 int third = left; int tmp = left; while (left <= center && mid <= right) { // 从两个数组中取出最小的放入中间数组 if (data[left] <= data[mid]) { tmpArr[third++] = data[left++]; } else { tmpArr[third++] = data[mid++]; } } // 剩余部分依次放入中间数组 while (mid <= right) { tmpArr[third++] = data[mid++]; } while (left <= center) { tmpArr[third++] = data[left++]; } // 将中间数组中的内容复制回原数组 while (tmp <= right) { data[tmp] = tmpArr[tmp++]; } // System.out.println(Arrays.toString(data)); } public static void main(String[] args) { int array[] = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15,35, 25, 53, 51 }; mergeSort(array, 0, array.length - 1); for (int element : array) { System.out.print(element + " "); } } }
不积跬步,无以至千里。不积小流,无以成江海!