【数据结构】归并排序

一、算法基本思想

把两个有序序列合并到一起

初始时两个指针i,j分别指向两个序列的首部,比较所指元素的大小,把较小的元素放到下面空序列中,对应指针向后移动。

当一个序列的指针超出范围时把另一个序列的剩余元素直接放到下面的新序列。

二、实现过程

初始序列

设置三个指针low,mid,high,分别指向首部,尾部和中间,mid=(low+high)/2

根据mid把整个序列分为两个

继续分解

分解到最后可以看作是一组组的有序序列,然后进行排序,形成新的有序序列

继续两两合并

最终得到有序序列

三、代码实现

1.对有序序列进行合并

//创建一个指针指向长度为8的数组的首地址
int* temp = (int*)malloc(8 * sizeof(int));

void Merge(int num[], int low, int high, int mid) {
	int i, j, k;
	//把要排序的数组复制到临时数组
	for (k = low; k <= high; k++) {
		temp[k] = num[k];
	}
	//对两个序列进行排序
    //如果有一个序列的指针超出范围就跳出循环
	for (i = low, j = mid + 1, k = low; i <= mid && j <= high; k++) {
		if (temp[i] <= temp[j]) {
			num[k] = temp[i];
			i++;
		}
		else {
			num[k] = temp[j];
			j++;
		}
	}
	//如果一个序列的指针超出范围,把另一个序列的剩余元素直接放到原数组对应位置
	while (i <= mid)num[k++] = temp[i++];
	while (j <= high)num[k++] = temp[j++];
}

2.对初始序列进行分解和排序

void MergeSort(int num[], int low, int high) {
	if (low < high) {
        //递归实现序列的分解
		int mid = (low + high) / 2;
		MergeSort(num, low, mid);
		MergeSort(num, mid+1, high);
		Merge(num, low, high, mid);
	}
}

四、完整代码和运行结果


int* temp = (int*)malloc(8 * sizeof(int));

void Merge(int num[], int low, int high, int mid) {
	int i, j, k;

	for (k = low; k <= high; k++) {
		temp[k] = num[k];
	}
	for (i = low, j = mid + 1, k = low; i <= mid && j <= high; k++) {
		if (temp[i] <= temp[j]) {
			num[k] = temp[i];
			i++;
		}
		else {
			num[k] = temp[j];
			j++;
		}
	}
	while (i <= mid)num[k++] = temp[i++];
	while (j <= high)num[k++] = temp[j++];
}

void MergeSort(int num[], int low, int high) {
	if (low < high) {
		int mid = (low + high) / 2;
		MergeSort(num, low, mid);
		MergeSort(num, mid+1, high);
		Merge(num, low, high, mid);
	}
	
}

int main() {
	int num[8] = { 49,38,65,97,76,13,27,49 };
	MergeSort(num, 0, 7);
	for (int i = 0; i < 8; i++) {
		printf("%d\n", num[i]);
	}
}

五、算法效率分析

1.空间复杂度

①临时数组的创建,长度为n,空间复杂度为O(n)

②递归栈:所占空间的大小与归并的次数有关

可以把有序序列分别看作是一个完全二叉树的结点,最上层的结点数=序列元素个数=n

二叉树第h层最多有2^(h-1)个结点,若树高为h,则应满足n<=2^(h-1),即h-1>=log₂n

完全二叉树最大高度满足h-1=log₂n,所以归并的趟数是log₂n

所以递归的深度为log₂n,空间复杂度为O(log₂n)

所以空间复杂度=O(log₂n)+O(n)=O(log₂n)(只保留高阶)

2.时间复杂度

每趟归并的时间复杂度为O(n)

共进行了log₂n次归并,所以时间复杂度为O(nlog₂n)

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值