归并排序(也挺快的,0v0)

本文详细介绍了归并排序的递归及迭代实现方式,通过代码示例解析了排序过程中的关键步骤,包括数组划分、合并等操作。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
//对数组a,下标范围在[ns,ne)的元素进行归并排序 
void mergesort(int * array,int ns,int ne)
{
	if(ne-ns==1) //1.递归终止条件,半开区间中只有一个元素,一定有序 
		return;
	//2.二分法,去中间位置
	//对2个子数组进行分开排序
	int m=ns+(ne-ns)/2;//避免溢出,取中间位置
	mergesort(array,ns,m);//左半区间归并排序 
	mergesort(array,m,ne);//右半区间归并排序,包括中值
    if(a[m-1]<a[m]) return;//如果左边最后一个元素小于右边第一个元素,说明已经是顺序的了
	//3.依次取出子数组的元素,合并 
	int *ta=new int[ne-ns];//定义一个临时数组 
	int nl=ns,nr=m;//左右的子数组的下标 
	int nt=0;//临时数组的下标
	while(nl<m&&nr<ne)
	{
		if(array[nl]<array[nr]) {ta[nt]=array[nl];nl++;nt++;}
		else {ta[nt]=array[nr];nr++;nt++;}
	} 
	//若有剩余,必定一个全部取完,另一个有剩余 
	while(nl<m) {ta[nt++]=array[nl++];}
	while(nr<ne) {ta[nt++]=array[nr++];}
	//把临时数组赋值给数组a
	for(int i=0;i<ne-ns;i++)
		array[i+ns]=ta[i];
	//释放临时空间
	delete[] ta; 
}
void print(int array[],int n)
{
	for(int i=0;i<n;i++)
	printf("%d ",array[i]);
}
int main()
{
	int array[]={4,1,10,15,37,79,24,11,91,2,18,94,45,21,52,83,98,90};
	int n=sizeof(array)/sizeof(*array);
	mergesort(array,0,n); 
	print(array,n);
}

迭代版本:

上节的归并排序使用递归的方式实现,递归频繁的调用函数会消耗一定时间,并且对栈的操作也很多,大多数递归算法都可以转化成迭代的方式实现。递归是将数组从上到下的层层分组,减小长度,那么迭代实现的话则是从下到上,设置一个间距,初始为1,则以1为单位进行元素的合并,接下来间距乘以2,以2个元素一组进行合并,重复上述步骤,直至间距大于数组长度。

上图以2个元素一组为例,设置4个指针,为

int leftMin, leftMax, rightMin, rightMax
分别指向两组元素的对应位置,当然也可以让leftMax和rightMax分别指向每组的最后一个元素,而不是最后一个元素的下一个位置,合并时需要temp数组,合并过程会出现两个数组中一边先遍历结束的情况:当左边的先遍历结束时,因为右边数组的剩余元素本来就应该待在当前的位置,因此无需处理;当右边的元素先遍历结束时,如图中对勾代表元素已经放到正确的位置,X代表还没有遍历的元素,那么将左边数组未遍历的元素放到右边数组中对应的位置处即可,省去了复制到temp数组再复制回原数组的操作。
--------------------- 
作者:Rap_God 
来源:优快云 
原文:https://blog.youkuaiyun.com/u012936940/article/details/80150017 
版权声明:本文为博主原创文章,转载请附上博文链接!

#include <iostream>
#include <algorithm>
#include <vector>
#define rep1(i,s,e,c) for(int i=s;i<e;i=i+c)
#define rep2(i,s,e,c) for(int i=s;i<=e;i=i+c)
#define rep3(i,e,s,c) for(int i=e;i>=s;i=i-c)
using namespace std;
typedef long long ll;
const int MAX=1e5+1;
const int INF=0x3f3f3f3f;
const int MOD=332748118;
void mergesort(int a[],int n){
	int *t = new int[n];//临时数组t 
	int p=0;//t数组的下标
	//和归并排序递归版本一样,同样是分为两部分
	int leftMin,leftMax,rightMin,rightMax;
	for(int i=1;i<n;i*=2){//i为每部分的长度,每一次翻倍,翻倍后的长度为i的数组已经在翻倍前排完序 
		for(leftMin=0;leftMin<n-i;leftMin=rightMax){//将数组a根据i分成n/i个部分,两两排序 
			//根据leftMin和i确认边界,左闭右开 
			leftMax=leftMin+i;
			rightMin=leftMax;
			rightMax=rightMin+i;
			if(rightMax>n){
				rightMax=n;
			}
			p=0;
			//根据对应下标元素的大小将元素顺序存储到t中 
			while(leftMin<leftMax && rightMin<rightMax){
				a[leftMin]<a[rightMin]?t[p++]=a[leftMin++]:t[p++]=a[rightMin++];
			}
			//如果左边遍历完,右边剩余的部分因为已经最大,不用动 
			//如果右边遍历完,将左边剩余的部分(这部分最大)搬到最右边 
			while(leftMin<leftMax){//右边已经全部遍历完,rightMin在rightMax的位置 
				a[--rightMin]=a[--leftMax];
			}
			while(p>0){
				a[--rightMin]=t[--p];
			}
		}		
	}
	delete[] t; 
}
void print(int a[],int n){
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	}
}
int main()
{
	int n,a[MAX];
	cin>>n;
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	mergesort(a,n);
	print(a,n);
    return 0;
}
/*
8
5 2 7 4 8 1 6 3
*/

 

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值