归并排序(MergeSort)
1、思想:
多次将两个或两个以上的有序表合并成一个新的有序表。
2、算法时间复杂度
最好的情况下:一趟归并需要n次,总共需要logN次,因此为O(N*logN)
最坏的情况下,接近于平均情况下,为O(N*logN)
说明:对长度为n的文件,需进行logN 趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
3、稳定性
归并排序最大的特色就是它是一种稳定的排序算法。归并过程中是不会改变元素的相对位置的。
4、缺点是,它需要O(n)的额外空间。但是很适合于多链表排序。
/**
* @author Administrator
* 并归排序法
*/
public class MergeSort {
/**
* @param args
*/
public static void main(String[] args) {
int[] data = { 1, 7, 16, 21, 41, 42,46, 52 ,53,63,86,97,3,53};
mergeSort(data, 0, data.length - 1); //
printData(data);
}
private static void mergeSort(int[] data, int low, int high) {
if(low>=high){
return ;
}
int mid = (low+high)/2;
mergeSort(data,low,mid);
mergeSort(data, mid+1, high);
merge(data,low,mid,high);
}
private static void merge(int data[],int low,int mid,int high){
int [] temp = new int[high-low+1];
int key = 0 ;
int i = low;
int j = mid+1;
/**把data从low到high可以看成从mid分开的两个数组
* 分别遍历两个数组,把最小值放入临时数组
* */
for(;i<=mid && j<=high;key++){
if(data[i]>data[j]){
temp[key] = data[j];
j++;
}else{
temp[key] = data[i];
i++;
}
}
/** 若从data[low] 到 data[mid]遍历完,则可能data[min+1]到data[high]的值还未遍历完
* 并且这些值肯定比data[mid]大,且是有序的.直接追加到temp后即可 */
if(i>mid){
while(j<=high){
temp[key]=data[j];
key++;
j++;
}
}
/**同理上 */
if(j>high){
while(i<=mid){
temp[key]=data[i];
key++;
i++;
}
}
/**把temp数组的值并归回data数组 */
setData(data,temp,low);
}
private static void setData(int []data,int []temp,int low){
if(data.length<temp.length){
return ;
}else{
for(int i = 0;i<temp.length;i++){
data[low+i] = temp[i];
}
}
}
public static void printData(int[] data) {
for (int i : data) {
System.out.print(i + " ");
}
System.out.println();
}
}