算法学习-归并排序和二分查找

本文详细介绍了归并排序和二分查找两种经典算法。归并排序是一种高效的排序算法,利用分治法原理实现。文章给出了归并排序的具体步骤,并提供了一个具体的排序实例和递归实现代码。二分查找则是在有序数组中查找特定值的有效方法,文章同样提供了其实现步骤和代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法学习-归并排序和二分查找


一:归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

算法步骤:

1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4. 重复步骤3直到某一指针达到序列尾

5. 将另一序列剩下的所有元素直接复制到合并序列尾

设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;
第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;
第三次归并后:{1,6,8,38,100,202,301},比较次数:4;
总的比较次数为:3+4+4=11,;

根据对数据结构书上此算法的理解,编写了以下归并算法的递归实现:

#include "iostream.h"

void merge(int a[],int b[],int i,int m,int n)
{
	for(int j=m+1,k=i;i<=m&&j<=n;++k)
	{
		if(a[i]<=a[j])b[k]=a[i++];  //a中按顺序归并
		else	b[k]=a[j++];
	}
	if(i<=m)
	{for(;i<=m;++k)       //前半区多余的部分直接赋值
		{
			b[k]=a[i++];    
		}
	}
	if(j<=n)
	{for(;j<=n;++k)			//后半区多余的部分直接赋值
		{
			b[k]=a[j++];
		}
	}
}

void msort(int a[],int b[],int s,int t)
{
	int tr[8];  //中间变量,存储有序序列
	if(s==t)b[s]=a[s];
	else
	{
		int m=(s+t)/2;		//均分
		msort(a,tr,s,m);	//前半区归并为有序存储到tr中
		msort(a,tr,m+1,t);	//后半区归并为有序存储到tr中	
		merge(tr,b,s,m,t);	//两个有序序列归并到b中
							//注意此处的tr位置,以及数据是如何传递和修改的
							//调试此处花费了大量时间,还需仔细理解
	}
}

void main()
{
	int a[]={49,38,65,97,76,13,27};
	int b[8];
	msort(a,b,0,7);
	for(int q=0;q<7;q++)
	{
	cout<<b[q]<<endl;
	}
} 


二:二分查找

二分查找是在一个有序的数组中查找的算法,通过二分查找可以快速的缩小范围;

算法步骤:

1. 申明三个变量,指示待查找区域的起点,中点,末点

2. 将数组的中间项与T进行比较,如果T比数组的中间项要小,则到数组的前半部分继续查找,反之,则到数组的后半部分继续查找。

3.如果找到则返回,否则重复2的操作,最终就会在数组中找到T,或者确定原以为T所在的范围实际为空。

以下是自己实现的二分查找算法:

#include "iostream.h"

int binarysearch(int a[],int n,int value)
{
	int left=0;
	int right=n-1;
	while(left<=right)     //注意等号,当查询为最后一个元素时需要用到等号
	{
		int middle=left+((right-left)>>1);   //位移运算防溢出(借鉴)
											 //理解是(left+right)/2,会超过int型范围
		if(value<a[middle])
			right=middle-1;			//在前半区
		else if(value>a[middle])
			left=middle+1;			//在后半区
		else
			return middle;
	}
	return -1;		//没有找到
}

void main()
{
	int a[10]={3,12,24,37,45,53,61,78,90,100};
	int m=binarysearch(a,10,100);
	cout<<m<<endl;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值