归并排序的两种算法

归并排序

1.具有哨兵的归并排序

在这里插入图片描述
时间复杂度近似于lgn,因为分治管理看上去就像一棵二叉树。

void MERGE1(vector<int> &val, int begindex, int midindex, int len)//有哨兵
{
	cout << "begindex: " << begindex << "\tendindex: " << midindex << "\tlen: " << len << endl;
	//begindex : 0     endindex : 0     len : 1//拿出下标为0,1的元素比较并放入val数组的0,1中
	//begindex : 0     endindex : 1     len : 2//比较0,1,2下标的元素合并
	//begindex : 3     endindex : 3     len : 4//比较3,4下标的元素合并
	//begindex : 0     endindex : 2     len : 4//比较0,1,2,3,4下标的元素合并
	//begindex : 5     endindex : 5     len : 6//比较5,6
	//begindex : 5     endindex : 6     len : 7//比较5,6,7
	//begindex : 8     endindex : 8     len : 9//比较8,9
	//begindex : 5     endindex : 7     len : 9//比较5,6,7,8,9
	//begindex : 0     endindex : 4     len : 9//比较0,1,2,3,4,5,6,7,8,9,合并
	vector<int> LVal, RVal;
	int Lindex = midindex - begindex + 1;//表示左边的元素个数
	int Rindex = len - midindex;//表示右边的元素个数
	int i, j, k;

	for (i = 0; i < Lindex; i++)
	{
		LVal.push_back(val[begindex + i]);//将从begindex下标开始存放元素
	}

	for ( j = 0; j < Rindex; j++)
	{
		RVal.push_back(val[midindex + j + 1]);//midindex + j + 1以这个下标为起始存放元素
	}

	LVal.push_back(1000);//定义哨兵//前提是要知道你的数据的最值,不然无法定义哨兵节点。
	RVal.push_back(1000);//比如我数据的最值是100以内的元素,所以哨兵定义为1000是正确的
	
	i = 0;
	j = 0;
	for (k = begindex; k <= len; k++)//k=begindex表示从第几个数组下标开始比较元素
	{
		if (LVal[i] <= RVal[j])
		{
			val[k] = LVal[i++];
		}
		else
		{
			val[k] = RVal[j++];
		}
	}
}

void MERGE_SORT(vector<int> &val, int begindex, int endindex)
{
	if (begindex < endindex)
	{
		int mid = (begindex + endindex) / 2;
		MERGE_SORT(val, begindex, mid);
		MERGE_SORT(val, mid + 1, endindex);
		MERGE1(val, begindex, mid, endindex);
	}
}

2.无哨兵归并排序

void MERGE2(vector<int> &val, int begindex, int midindex, int len)//无哨兵
{
	vector<int> Assist;
	int Lindex = midindex - begindex + 1;//左序列
	int Rindex = len - midindex;//右序列
	int i, j;
	i = begindex; j = midindex+1;//标记两个子序列应该从val数组中那个索引开始

	while (0<Lindex && 0< Rindex)//循环对比数据,直至某个序列被全部放入Assist数组中
	{
		if (val[i] <= val[j])
		{
			Assist.push_back(val[i++]);
			Lindex--;
		}
		else
		{
			Assist.push_back(val[j++]);
			Rindex--;
		}
	}

	while (Lindex > 0)//判断左子序列是否还存在元素
	{
		Assist.push_back(val[i++]);
		Lindex--;
	}

	while (Rindex > 0)//判断右子序列是否还存在元素
	{
		Assist.push_back(val[j++]);
		Rindex--;
	}

	i = 0;
	for (size_t k = begindex; k <= len; k++)//val是从begindex索引开始排序的,所以k要初始化成开始排序的索引
	{
		val[k] = Assist[i++];
	}
}

void MERGE_SORT(vector<int> &val, int begindex, int endindex)
{
	if (begindex < endindex)
	{
		int mid = (begindex + endindex) / 2;
		MERGE_SORT(val, begindex, mid);
		MERGE_SORT(val, mid + 1, endindex);
		MERGE2(val, begindex, mid, endindex);
	}
}

主函数随便写写就行了

int main()
{
	vector<int> val;

	for (size_t i = 0; i < 10; i++)
	{
		int value = rand() % 100;
		val.push_back(value);
	}

	for (size_t i = 0; i < 10; i++)
	{
		cout << val[i] << " ";
	}
	cout << endl;

	MERGE_SORT(val, 0, 9);

	for (size_t i = 0; i < 10; i++)
	{
		cout << val[i] << " ";
	}
	cout << endl;

	system("pause");
	return 0;

}

在这里插入图片描述
归并排序用来处理大量数据排序性能是非常好的因为天然是二叉树的性质。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值