数据结构与算法学习(2)

本文深入探讨了递归在排序算法中的应用,重点介绍了归并排序和快速排序。归并排序通过递归地拆分数组并合并已排序部分实现高效排序,而快速排序则利用分治策略,选取基准值并重新排列数组元素。文章还讨论了两种排序算法的优化方法,如随机选取基准值以避免最坏情况,以及处理相同数值的策略。
摘要由CSDN通过智能技术生成

数据结构与算法学习(2)

一.递归

请添加图片描述

二.归并排序

void Merge(vector<int>& arr, int left, int mid, int right) {
	vector<int> tmp(right - left + 1, 0);
	int p1 = left;
	int p2 = mid + 1;
	int i = 0;
	while (p1 <= mid && p2 <= right)
	{
		tmp[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
	}
	while (p1 <= mid)
	{
		tmp[i++] = arr[p1++];
	}
	while (p2 <= right)
	{
		tmp[i++] = arr[p2++];
	}
	for (int i = 0; i < tmp.size(); i++)
	{
		arr[left + i] = tmp[i];
	}
}
void Sort04(vector<int>& arr, int left, int right) {
	if (left >= right)return;
	int mid = left + ((right - left) >> 1);
	Sort04(arr, left, mid);
	Sort04(arr, mid + 1, right);
	Merge(arr, left, mid, right);
}

1.小和问题

int Merge01(vector<int>& arr, int left, int mid, int right) {
	vector<int> tmp(right - left + 1, 0);
	int p1 = left;
	int p2 = mid + 1;
	int i = 0;
	int num = 0;
	while (p1 <= mid && p2 <= right)
	{
		num += arr[p1] <= arr[p2] ? (right - p2 + 1) * arr[p1] : 0;
		tmp[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
	}
	while (p1 <= mid)
	{
		tmp[i++] = arr[p1++];
	}
	while (p2 <= right)
	{
		tmp[i++] = arr[p2++];
	}
	for (int i = 0; i < tmp.size(); i++)
	{
		arr[left + i] = tmp[i];
	}
	return num;
}
int Test05(vector<int>& arr, int left, int right) {
	if (left >= right)return 0;
	int mid = left + ((right - left) >> 1);
	return Test05(arr, left, mid) + Test05(arr, mid + 1, right) + Merge01(arr, left, mid, right);
}

2.逆序对问题

int Merge01(vector<int>& arr, int left, int mid, int right) {
	vector<int> tmp(right - left + 1, 0);
	int p1 = left;
	int p2 = mid + 1;
	int i = 0;
	int num = 0;
	while (p1 <= mid && p2 <= right)
	{
		num += arr[p1] > arr[p2] ? (mid - p1 + 1) : 0;
		tmp[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
	}
	while (p1 <= mid)
	{
		tmp[i++] = arr[p1++];
	}
	while (p2 <= right)
	{
		tmp[i++] = arr[p2++];
	}
	for (int i = 0; i < tmp.size(); i++)
	{
		arr[left + i] = tmp[i];
	}
	return num;
}
int Test05(vector<int>& arr, int left, int right) {
	if (left >= right)return 0;
	int mid = left + ((right - left) >> 1);
	return Test05(arr, left, mid) + Test05(arr, mid + 1, right) + Merge01(arr, left, mid, right);
}

三.快速排序

一般的快排

void Sort05(vector<int>& arr, int left, int right) {
	if (left >= right)return;
	int less = 0;
	int high = right;
	int base = arr[right];
	while (less < high)
	{
		while (arr[less] <= base && less < high)
			less++;
		while (arr[high] >= base && less < high)
			high--;
		if (less < high)
			Swap(arr, less, high);
	}
	arr[right] = arr[high];
	arr[high] = base;
	Sort05(arr, left, high - 1);
	Sort05(arr, high + 1, right);
}

优化1.不取最后一个数,防止复杂度下降到n^2,而是随机抽取一个数放到结尾
优化2.每次排序将相同的数直接排完放到中间

vector<int> Test06(vector<int>& arr, int left, int right) {
	int less = left - 1;
	int high = right;
	while (left < high)
	{
		if (arr[left] < arr[right])
			Swap(arr, left++, ++less);
		else if (arr[left] > arr[right])
			Swap(arr, --high, left);
		else
			left++;
	}
	Swap(arr, right, high);
	return{ less,high };
}
void Sort06(vector<int>& arr, int left, int right) {
	if (left >= right)return;
	vector<int> tmp = Test06(arr, left, right);
	Sort06(arr, left, tmp[0]);
	Sort06(arr, tmp[1], right);
}

1.小于等于指定数在左边大于指定数在右边

void Test08(vector<int>& arr, int num) {
	int left = -1;
	for (int i = 0; i < arr.size(); i++)
	{
		if (arr[i] <= num) {
			Swap(arr, ++left, i);
		}
	}
}

2.荷兰国旗问题

void Test07(vector<int>& arr, int num) {
	int less = -1;
	int high = arr.size();
	int left = 0;
	while (left < high)
	{
		if (arr[left] < num)
			Swap(arr, left++, ++less);
		else if (arr[left] > num)
			Swap(arr, --high, left);
		else
			left++;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值