归并排序

【3】归并排序

原理:分为三部分:
1.新建辅助数组
2.先递归分解原数组,不断分成两部分循环递归排序
3.合并数组,同时把合并排序后的元素放到辅助数组中
 
时间复杂度:O(nlogn)
稳定
缺点:需要额外的N空间来进行排序
 
和快排一样的复杂度,但是稳定排序,排序关键字相等的两个元素在整个序列排序的前后,相对位置不会发生变化。因此是稳定性排序中效率最高的一个,c++\python等稳定性排序的内部实现中,都是使用的归并排序。

 

Java实现

package com.hello.kitty.sort;

/**
 * @name: S_04_MergeSort.class
 * @Author :   
 * @create :   2020-01-11
 * @Desc: 归并排序
 * 思路:1,分:分别归并排序左右两块
 *      2.合并左右两块
 *      如果右指针>右边界,说明剩下的数都在左边,直接加,因为已排序
 *      左指针>mid,说明剩下的数都在右边,直接加,因为已排序
 *      之后就是判断大小,谁小加谁
 * 优缺点:效率高、稳定、O(nlogn),但是需要额外的辅助空间
 */
public class S_04_MergeSort {
    public static int[] mergeSort(int[]arr, int[] tmpArr,int left, int right){

        if(left < right){
            int mid = (left + right)/2;
            //归并排序左半部分
            mergeSort(arr,tmpArr, left,mid);
            //归并排序右半部分
            mergeSort(arr,tmpArr,mid+1, right);

            //合并左右两块
            merge(arr, tmpArr,left, mid+1, right);
        }
        return null;
    }

    /**
     * 合并两个有序数组
     * @param arr
     * @param tmpArr
     * @param left
     * @param mid
     * @param right
     * @return
     */
    public static int[] merge(int[]arr, int[] tmpArr,int left, int mid,int right){
        int i = left;
        int j = mid+1;

        //先把元素放进辅助数组
        for(int k = left;k<right;k++){
            tmpArr[k] = arr[k];
        }

        for(int k = left;k<right;k++){
            //两块比较,i是第一块的指针,j是第二快的指针

            //左边排完了,说明剩下的大数都在右半部分
            if(i>mid){
                arr[k] = tmpArr[j++];
            }else if(j > right){
                //右边排完了,说明大数在左半部分
                arr[k] = tmpArr[i++];
            }else if(tmpArr[i] < tmpArr[j]){
                //否则,左边小,取左边
                arr[k] = tmpArr[i++];
            }else{
                //右边小,取右边
                arr[k] = tmpArr[j++];
            }
        }
        return null;
    }

    public static void main(String[] args) {
        int[] arr = {3,1,4,2,8,6,5,4};
        int[] tmpArr = new int[8];
        mergeSort(arr, tmpArr, 0, 7);
    }
}
/**********************************************************
名称:归并排序
原理:分为三部分:
	1.新建辅助数组
	2.先递归分解原数组,不断分成两部分
	3.合并数组,同时把合并排序后的元素放到辅助数组中

***********************************************************/



#include "stdafx.h"
#include<iostream>
using namespace std;
void Merge(int a[],int first,int mid,int last,int atmp[])
{
	int i = first,j = mid + 1;
	//把元素拷贝到辅助数组中
	for(int k = first; k <= last; k++)
	{
		atmp[k] = a[k];
	}
	//之后按照排序从辅助数组中拷贝回原数组
	for(int k = first; k <= last; k++)
	{
		if(i > mid)//一块的头大于中点,说明左边镁元素了
		{
			a[k] = atmp[j++];
		}
		else if(j > last)//一块的尾超过终点,说明右边没元素
		{
			a[k] = atmp[i++];
		}
		else if(atmp[i]<atmp[j])//两块的头尾都在序列中,左边元素小,则入队,然后从下一个开始继续比
		{
			a[k] = atmp[i++];
		}
		else
		{
			a[k] = atmp[j++];
		}
	}
}




void mergesort(int a[],int first,int last,int atmp[])//把数组递归划分排序,再合并
{
	if(first < last) 
	{
		int mid = (first + last)/2;//平分数组,找到中间值
		mergesort(a,first,mid,atmp);//循环对左边排序
		mergesort(a,mid+1,last,atmp);//循环对右边排序
		Merge(a,first,mid,last,atmp);//将两个有序序列合并
	}
}

void MergeSort(int a[],int length)//归并排序函数
{
	int *atmp = new int[length];//新建辅助数组
	mergesort(a,0,length-1,atmp);
	delete [] atmp;

	for(int i = 0;i!=length;i++)  
    {  
        cout << a[i]<<" ";  
    }  
}

int main()  
{  
    int length = 0;  
    int i = 0;  
    cout << "请输入排序数组长度:" << endl;  
    cin >> length;  
    int a[100] = {0};  
  
    cout << "请输入排序数组:" << endl;  
    for(;i!=length;i++)  
        cin>>a[i];  
    cout << "归并排序:" << endl;  
    MergeSort(a,length);  
    cout << endl;  
  
    system("pause");  
    return 0;  
  
}  

 

 

 

参考资料:http://www.cnblogs.com/yangecnu/p/Introduce-Merge-Sort.html

浅谈算法和数据结构: 三 合并排序

 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值