排序算法:归并排序

归并排序:稳定排序

归并(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));
	}
}


猜你喜欢

转载自blog.csdn.net/linyk3/article/details/48179297