跟着《算法导论》学习——插入排序与归并排序

读前声明:本人所写帖子主要为了记录本人学习的一个过程,无他想法,由于内容比较肤浅,如有雷同,非常正常!!!

本文内容:

本文主要是参考《算法导论》这本书,完成部分算法编写,可能编程习惯或者风格比较差,还请多多批评。

1、插入排序(Insertion Sort)

插入排序是对少量元素进行排序的有效算法,其机理与很多人打牌时,整理手中牌时的做法差不多。开始摸牌时,我们的左手是空的,牌面朝下放在桌上,接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将它与手中已有的每一张牌从右到左的比较。

其代码如下:

void InsertionSort(int a[],int n)
{
	for(int j=1;j<n;j++)
	{
		int key = a[j];
		int i = j-1;
		while (i>=0&&a[i]>key)
		{
			a[i+1] = a[i];
			i--;
		}
		a[i+1] = key;
}
2、归并排序(Merge sort)

归并排序是分治法(Divide-and-Conquer)的一个应用。分治法的的策略如下:将原问题划分为n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。分治模式在每一层递归都有三个步骤:

分解(Divide):将原问题分解成一系列子问题;

解决(Conquer):递归地求解各子问题,若子问题足够小,则直接求解;

合并(Combine):将子问题的结果合并成原问题的解

归并排序完全按照上述模式,直观的操作如下:

分解:将n个元素分成各含n/2个元素的子序列;

解决:用合并排序法对两个子序列递归地排序;

合并:合并两个已排序的子序列以得到排序结果。

在对子序列排序时,其长度为1时递归结束,单个元素被视为已排序的。

合并排序的关键步骤在于合并步骤中的合并两个已排序子序列。为做排序,引入一个辅助过程Merge,其过程是将两个子序列经过比较,合并成一个大的排好序的数组。

Merge子函数如下:

void Merge(int a[],int b[],int left,int middle,int right)
{
	for (int i=left;i<=right;i++)
	{
		b[i] = a[i];
	}
	int s1 = left;
	int s2 = middle+1;
	int t = left;
	while (s1<=middle&&s2<=right)
	{
		if (b[s1]<=b[s2])
		{
			a[t++] = b[s1++];
		} 
		else
		{
			a[t++] = b[s2++];
		}
	}
	if (s1==middle+1)
	{
		while (s2<=right)
		{
			a[t++] = b[s2++];
		}
	}
	if (s2==right+1)
	{
		while (s1<=middle)
		{
			a[t++] = b[s1++];
		}
	}
}

归并排序算法过程:

void MergeSort(int a[],int b[],int left,int right)
{
	if(left>=right) return;
	int middle = (left+right)/2;
	MergeSort(a,b,left,middle);
	MergeSort(a,b,middle+1,right);
	Merge(a,b,left,middle,right);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值