归并排序:稳定排序
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
归并
排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路
归并。
第一步:申请空间,使其大小为两个已经
排序序列之和,该空间用来存放合并后的序列
第二步:设定两个
指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
最差:
平均:
最好:
package test; import java.util.Arrays; /** * 归并排序 * 简介:将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列 * 时间复杂度为O(nlogn) * 稳定排序方式 * @param nums 待排序数组 * @return 输出有序数组 */ public class MergeSort { //归并排序 static void sort(int a[], int low, int high) { //满足归并的条件是 low < high if(low < high) { //使用递归将待排序数组分成两个分别排序再合并 int mid =(low + high) / 2; sort(a,low,mid); sort(a,mid+1,high); //将两个排好序的两个子数组归并 merge(a,low,mid,high); } } /* * 归并将两个排好序的子数组归并 * @param int a[] 待归并数组 * @param int low 数组的起始位置 * @param int mid 数组分成两个子数组后,第一个子数组的重点位置 * @param int high 数组的终点位置 */ static void merge(int a[],int low, int mid, int high) { //子数组1 起始位置 int i = low; //子数组2起始位置 int j = mid + 1; //已处理数组元素下表 int k = 0; //新建临时数组,用于存放已处理的数组元素。长度为待归并数组的长度 int[] temp = new int[high - low + 1]; //分别比较两个子数组的元素,将较小的元素存储在临时数组中,下标加1;继续比较知道其中一数组全部比较完毕 while(i <= mid && j <= high) { if(a[i] < a[j]) { temp[k++] = a[i++]; } else { temp[k++] = a[j++]; } } //将子数组1中剩下的元素全部保存到临时数组中 while(i <= mid) { temp[k++] = a[i++]; } //将子数组2中剩下的元素全部保存到临时数组中 while(j <= high) { temp[k++] = a[j++]; } //将临时数组的结果写进待排序的数组中 for(int n = 0; n < high-low+1; n++) { a[low + n] = temp[n]; } } public static void main(String args[]) { int a[] = new int[]{5,1,1,1,6,8,9,4,2,7}; sort(a,0,a.length-1); System.out.println(Arrays.toString(a)); } }