您的位置:首页 > 其它

排序算法:归并排序

2015-09-02 15:42 337 查看
归并排序:稳定排序

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

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));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: