113-对归并排序算法的非递归实现和分析

归并排序算法非递归思想

归并排序的非递归实现主要在于子序列的划分;
1、首先需要一个临时数组以及左右两个子序列的区间;
2、从区间长度为1开始(递增两倍)将原数组划分成多对左右两个子序列;
3、依次将多对左右子序列进行比较,并按顺序存入临时数组中
4、再将临时数组排序好的序列再复制到原数组中
5、最后区间长度两倍增长,重复以上操作,即归并

排序过程图示
在这里插入图片描述

二路归并排序算法

将相邻的两个段(本身已经是有序的)的数据合并到一块,合并完成后整个段依旧有序
初始时,认为单个数据就是有序的一个段

首先书写需要用到的辅助函数

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
/*辅助函数:
    1.打印数据
	2.判断整个数据序列是否已经有序
	3.交互两个数据swap方法
*/

void Show(int *arr,int len)//打印数据
{
	for(int i=0;i<len;++i)
	{
		printf("%d  ",arr[i]);
	}
	printf("\n");
}

bool IsSort(int *arr,int len)//判断整个数据序列是否已经有序
{
	for(int i=0;i<len-1;++i)
	{
		if(arr[i]>arr[i+1])
		{
			return false;
		}
	}
	return true;
}

void SwapValue(int *a,int *b)//交互两个数据swap方法
{
	int tmp=*a;
	*a=*b;
	*b=tmp; 
}

图解:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

l1:第一个段的第一个元素下标
h1:第一个段的最后一个元素下标
l2:第二个段的第一个元素下标
h2:第二个段的最后一个元素下标

实现二路归并算法

void Meger(int *arr,int len,int section_size,int *brr)
{
	int l1=0;
	int h1=l1+section_size-1;
	int l2=h1+1;
	int h2=l2+section_size<len?l2+section_size-1:len-1;
	
	int brr_index=0;
	
	//有两个归并段
	while(l2<len)
	{
		//两个归并段中都有数据时
		while(l1<=h1&&l2<=h2)
		{
			if(arr[l1]<arr[l2])
			{
				brr[brr_index++]=arr[l1++];
			}
			else
			{
				brr[brr_index++]=arr[l2++];
		    } 
		}
		//剩下一个归并段有数据
		while(l1<=h1)
		{
			brr[brr_index++]=arr[l1++];
		}
		while(l2<=h2)
		{
			brr[brr_index++]=arr[l2++];
		}
		l1=h2+1;
		h1=l1+section_size-1;
		l2=h1+1;
		h2=l2+section_size<len?l2+section_size-1:len-1;
	}
	//仅剩下一个归并段
	while(l1<len)
	{
		brr[brr_index++]=arr[l1++];
	}
	//将brr的数据全部导入到arr中
	for(int i=0;i<len;++i)
	{
		arr[i]=brr[i];
	} 
}
	  
void MegerSort(int *arr,int len)
{
	int *brr=(int *)malloc(sizeof(arr[0])*len);
	assert(brr!=NULL);
	for(int i=1;i<len;i*=2)
	{
		Meger(arr,len,i,brr);
	}
	free(brr);
}

最后完成主函数

int main()
{
	int arr[]={7,87,29,75,41,50,62,92,69,22,76,77,35};
	Show(arr,sizeof(arr)/sizeof(arr[0]));
	MegerSort(arr,sizeof(arr)/sizeof(arr[0]));
	Show(arr,sizeof(arr)/sizeof(arr[0])); 
	return 0;
	
}

运行结果
在这里插入图片描述
二路归并算法分析
时间复杂度 O(nlogn)
空间复杂度 O(n)
稳定性: 稳定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值