归并排序,递归与非递归,c/c++描述

本文介绍了归并排序的原理和两种实现方式:递归和非递归。归并排序通过将大问题分解为小问题解决,最终合并成有序序列。递归方法遵循分治策略,非递归方法则通过逐步合并子表完成排序。代码示例展示了这两种方法的详细步骤,适合初学者理解。
摘要由CSDN通过智能技术生成

  归并排序,又是一种新的排序。其时间复杂度 < O(n ^ 2)。
  以前在链表里,我们已经学过,如何把两个有序表合并成一个总的有序表。
  在归并排序里,要给一个大表排序,我们就采用了这样的思路:先把表分成两部分分别排好序,再把这两个有序的子表合并在一块。当然这个定义是递归的。当表里只有一个元素时,才不必进行拆分。
  归并排序,也可以不用递归的方法。我们直接把表划分成一堆只有一个元素的子表,再对子表进行两两合并,使所有子表都含有两个元素,再对子表进行两两合并,使子表具有4个元素,依次类推,直到合并完后只剩下一个表,至此,排序完毕。
  在非递归合并中,若子表数量是奇数,则剩余最后一个子表不参与合并,若子表数量是偶数,但最后一个子表的元素数目不够,依然要对最后两个子表合并。目的是要保证新的一趟合并开始前,所有子表都依然是有序的。
  当表的元素数目不是 2 的幂数,则表最终被合并到只剩下两个子表时,俩子表长度是不相等的,这时候需要单独对这俩子表进行一次合并。
  b站的归并排序讲解很好。比课本好懂。
下面是全部代码,包括递归和非递归:

#include<iostream>
#include<stdlib.h>
using namespace std;

void dispaly(int array[],int length) {
	for (int i = 0; i < length; i++)
		cout << array[i] << ' ';
	cout << endl;
}

void merge(int array[],int arrayTemp[],int start,int mid,int end) {
	int i = start, j = mid + 1, indexTemp = start;
	while (i <= mid && j <= end)
		if (array[i] <= array[j])
			arrayTemp[indexTemp++] = array[i++];
		else
			arrayTemp[indexTemp++] = array[j++];

	if (i <= mid)
		while (indexTemp <= end)
			arrayTemp[indexTemp++] = array[i++];

	if (j <= end)
		while (indexTemp <= end)
			arrayTemp[indexTemp++] = array[j++];

	for (i = start; i <= end; i++)
		array[i] = arrayTemp[i];
}

void sort(int array[],int arrayTemp[],int start,int end) {
	if (start == end)
		return;

	int mid = (start + end) / 2;
	sort(array,arrayTemp,start,mid);
	sort(array,arrayTemp,mid + 1,end);
	merge(array,arrayTemp,start,mid,end);
}

void mergeSort(int array[],int length) {
	int* arrayTemp = (int*)malloc(length * sizeof(int));
	if (arrayTemp != NULL) {
		sort(array, arrayTemp, 0, length - 1);
		free(arrayTemp);
	}
	else
		cout << "fail to allocate memory !" << endl;
}

void mergeSortNoRecursion(int array[],int length) {
	int* arrayTemp = (int*)malloc(length * sizeof(int));
	
	if (arrayTemp == NULL) {
		cout << "fail to allocate memory !" << endl;
		return;
	}

	int arrayLength;
	int start, mid, end;
	for (arrayLength = 1; arrayLength <= length / 2; arrayLength *= 2) {
		for (start = 0; start + arrayLength * 2 <= length; start = end + 1) {
			mid = start + arrayLength - 1;
			end = start + 2 * arrayLength - 1;
			merge(array, arrayTemp, start,mid ,end);
		}

		if (start + arrayLength < length)
			merge(array,arrayTemp,start,start + arrayLength - 1,length - 1);
	}

	if (arrayLength != length)
		merge(array,arrayTemp,0,arrayLength - 1,length - 1);

	free(arrayTemp);
}

int main() {
	int array[] = {2,9,0,6,3,4,8,7,1,5};
	int const length = 10;

	mergeSort(array,length);
//	mergeSortNoRecursion(array,length);

	dispaly(array,length);
	return 0;
}


测试结果当然是正确的。
在这里插入图片描述

谢谢阅读

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值