C++归并排序

将两个有序数组合并成一个有序数组

  1. 将数组进行分解,直到分解为单个元素时,因为最开始无法得到有序数组,而是把只有一个元素的单个数组,看成有序数组

  2. 依次将两两有序数组进行有序合并,直至排序完成

  3. 合并的步骤:先申请两数组合并后所需要的空间大小,然后将两个排序好的数组逐一进行比较,往申请的空间里

    void merge(int a[], int l, int mid, int r) {
    	int *help = new int[r - l + 1];//申请两个数组合并后所需的空间
    //i代表第一个有序数组的开头,j代表第二个有序数组的开头,index代表新申请的数组的下标
    	int i = l, j = mid + 1,index = 0;
    	while (i<=mid&&j<=r)//判断i,j不要越界
    	{
    		if (a[i] <= a[j]) {
    			help[index++] = a[i++];
    		}
    		else
    		{
    			help[index++] = a[j++];
    		}
    	}
    	while (i <= mid) {//此种情况,说明第二个有序数组的元素已经全部放入help中了,所以把第一个有序数组中没放入help中的元素全部放入help中
    		help[index++] = a[i++];
    	}
    	while (j <= r) {
    		help[index++] = a[j++];
    	}
    //将help中的元素,再全部放入原数组中
    	index = l;
    	for (int i = 0; i <= r - l; i++) {
    		a[index++] = help[i];
    	}
    	delete[] help;//释放空间
    }
    void mergeSort(int a[], int l, int r) {
    	if (l >= r) {
    		return;
    	}
    	int mid = (l + r) / 2;
    	mergeSort(a, l, mid);//递归
    	mergeSort(a, mid + 1, r);
    	merge(a, l, mid, r);
    }
    int main() {
    	int a[]= {1,5,3,2,4};
    //sizeof(a)代表a数组字节,sizeof(a[0])代表a中一个元素的字节,所以二者相除就是数组a的元素个数
    	mergeSort(a, 0, sizeof(a) / sizeof(a[0]) - 1);
    	for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
    		cout << a[i] << " ";
    	}
    	cout << endl;//此种方法实现数组的空格输出,并是释放了资源
    }
    

    归并排序

    分到最后剩一个元素为止,分log2n层

    n为每一层比较的次数

    时间复杂度nlog2n空间复杂度:O(n)因为栈区局部变量,空间用完就被释放

    稳定

    归并排序是一种基于分治思想的排序。

    先将序列分为长度相等的两个子序列,对子序列排好序以后,再合并。

    对子序列的排序,则调用递归实现。是稳定的

    时间复杂度:

    最优:O(nlogn)

    最差:O(nlogn)

    平均:O(nlogn)

    归并排序的时间复杂度是稳定的,不管数据类型如何,对于n个数据,需要分成logn层,而合并每一层的数据,都需要O(n)的时间,所以时间复杂度稳定为O(nlogn)。

    空间复杂度:

    归并排序需要额外的空间占用,也算是他的缺点吧,空间占用为O(n)。

    稳定性:

    归并排序的出口只有1个元素,或者2个元素的时候,我们都可以在这里保证他们的稳定性,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值