插入排序和归并排序

插入排序

描述:

假设有一把扑克牌:7,2,10,4,6,9,K,4,J,Q,3,现在要对其进行排序。

从左往右开始,7是第一个,不动,从第二个(2)开始,2<7于是放到7前面:2,7,10,4,6,9,K,4,J,Q,3

接着10大于7,大于2,放回原位置不做调整。

2<4<7放到2的后面。

。。。

这样一直到最后一张3插入到2的后面。整个排序结束。


归并排序

描述:

如果要对序列7,2,10,4,3,9,K,4,J,Q,3排序可以将其分成两半7,2,10,4,6和9,K,4,J,Q,3对这两部分分别排序。

同样对7,2,10,4,6排序可将其分成两部分7,2和10,4,6

对7,2排序可以再分为两部分:7和2

然后将这两部分按照次序合并放入数组中:2,7。

同样数组2,7和6,4,10合并成2,3,4,7,10.

依次类推,2,4,6,7,10和3,4,9,J,Q,K合并成2,3,4,6,7,9,10,J,Q,K

代码实现:

#include "common.h"

extern void Sort();

static void InsertionSort(int* a,int n);

static void MergeSort(int* a,int p,int r);
static void Merge(int* a,int p,int q,int r);


void Sort()
{
	int a[]= {19,3,12,4,7,6,12,9,23,14,29,13,34,8};
	Debug(a,sizeof(a)/sizeof(int),0);
	//InsertionSort(a,sizeof(a)/sizeof(int));
	MergeSort(a,0,sizeof(a)/sizeof(int)-1);
	Debug(a,sizeof(a)/sizeof(int),0);
}

static void InsertionSort(int* a,int n)
{
	int j;
	for(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;
	}
}

static void MergeSort(int* a,int p,int r)
{
	int q=0;
	if(p<r)
	{
		q = (r+p)/2;
		MergeSort(a,p,q);
		MergeSort(a,q+1,r);
		Merge(a,p,q,r);
		Debug(a,r-p+1,p);
	}
}


static void Merge(int* a,int p,int q,int r)
{
	int i=0,j=0;
	int len = r-p+1;
	int first1 = p,
		last1 = q;
	int first2 = q+1,
		last2 = r;
	int *t = (int*)malloc(len*sizeof(int));
	if( t== NULL || len == 0)
	{
		return;
	}
	while(first1<=last1 && first2 <= last2)
	{
		if(a[first1] < a[first2])
		{
			t[i] = a[first1];
			first1++;
			i++;
		}
		else
		{
			t[i] = a[first2];
			first2 ++;
			i++;
		}
	}
	while(first1 <= last1)
	{
		t[i] = a[first1];
		first1++;
		i++;
	}
	while(first2 <= last2)
	{
		t[i] = a[first2];
		first2++;
		i++;
	}
	for(i=p,j=0; i<=r; j++,i++)
	{
		a[i] = t[j];
	}
	free(t);
}




尽管合并排序的最坏情况运行时间为Θ(n*lgn),插入排序的最坏情况运行时间为Θ(n平方),但插入排序中的常数因子使得它在n较小时,运行的要更快一些。因此在合并排序算法中,当子问题足够小时,采用插入排序就比较合适了。最坏情况运行时间为Θ(nk+nlg(n/k))

static void MergeSort(int* a,int p,int r)
{
	int q=0;
	if(r-p>=7)
	{
		q = (r+p)/2;
		MergeSort(a,p,q);
		MergeSort(a,q+1,r);
		Merge(a,p,q,r);
	}
	else
	{
		InsertionSort(a+q,r-q+1);
	}
	Debug(a,r-p+1,p);

}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ZenZenZ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值