左程云新手班第八节

1 位运算求最大值

#include<iostream>
using namespace std;
//用位运算求出两者中的较小值:方法1:先用位运算求出该数的符号,非负数时记为1,负数计为0之后两数相减
//求出差的符号,之后组合出最小值,但在相减时有溢出导致符号不确定风险
//方法2:多讨论了一步a,b符号是否相同的问题
int flip(int n)
{
	return 1 ^ n;//把0变成1,1变成0
}
int sign(int n)//将符号位移动到第一位做运算
{
	return flip((n >> 31)&1);
}
int getmax1(int a, int b)
{
	int c = a - b;
	int sca = sign(c);
	int scb = flip(sca);
	return a* sca + b * scb;
}
int getmax2(int a, int b)
{
	long long c = (long long)a - b;
	int sa = sign(a);
	int sb = sign(b);
	int sc = sign(c);
	int difsab = sa ^ sb;
	int samsab = flip(difsab);
	int returna = difsab * sa + samsab * sc;
	int returnb = flip(returna);
	return a * returna + b * returnb;
}

2 归并排序的递归实现和非递归实现

#include<iostream>
#include<vector>
using namespace std;
//归并排序:先按两对两对地进行找,然后扩大到四个一对,逐个扩大最后将数组对半分
//然后将左右数组合并排序
void mergesort(vector<int>& arr)
{
	if (arr.size() < 2)
		return;
	process(arr, 0, arr.size() - 1);
}
void process(vector<int>& arr, int l, int r)
{
	if (l == r)
		return;
	int mid = l + (r -l) / 2;
	process(arr, l, mid);
	process(arr, mid + 1, r);
	merge(arr, l, mid, r);
}
void merge(vector<int>& arr, int l, int mid, int r)
{
	vector<int> help(r - l + 1);
	int i = 0;
	int p1 = l;
	int p2 = mid + 1;
	while (p1 <= mid && p2 <= r)
	{
		help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
	}
	while (p1 <= mid)
	{
		help[i++] = arr[p1++];
	}
	while (p2 <= r)
	{
		help[i++] = arr[p2++];
	}
	for (i = 0; i < help.size(); i++)
	{
		arr[l + i] = help[i];
	}
}
#include<iostream>
#include<vector>
using namespace std;
//归并排序:先按两对两对地进行找,然后扩大到四个一对,逐个扩大最后将数组对半分
//然后将左右数组合并排序
void mergesort2(vector<int>& arr)
{
	if (arr.size() < 2)
		return;
	int step = 1;
	int n = arr.size();
	while (step < n)
	{
		int l = 0;
		while (l < n)
		{
			int m = 0;
			if (n - l >= step)
				m = l + step - 1;
			else
				m = n - 1;
			if (m == n - 1)
				break;
			int r = 0;
			if (n - 1 - m >= step)
				r = m + step;
			else
				r = n - 1;
			merge(arr, l, m, r);
			if (r == n - 1)
				break;
			else
				l = r + 1;
		}
		if (step > n / 2)
			break;
		step *= 2;
	}
}

void merge(vector<int>& arr, int l, int mid, int r)
{
	vector<int> help(r - l + 1);
	int i = 0;
	int p1 = l;
	int p2 = mid + 1;
	while (p1 <= mid && p2 <= r)
	{
		help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
	}
	while (p1 <= mid)
	{
		help[i++] = arr[p1++];
	}
	while (p2 <= r)
	{
		help[i++] = arr[p2++];
	}
	for (i = 0; i < help.size(); i++)
	{
		arr[l + i] = help[i];
	}
}

 3快速排序的递归实现和非递归实现

#include<iostream>
#include<vector>
using namespace std;
void swap(vector<int>& a, int i, int j)
{
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}
//快速排序的递归实现方法:以最右边的数作为分界,小于的放左边,大于的放右边等于的放中间
//对大数组做完上述操作后,再对小于区域和大于区域均做相同的操作,即可完成排序
vector<int> partition(vector<int>& arr, int l, int r)
{
	int lessr = l - 1;
	int morel = r;
	int index = l;
	while (index < morel)
	{
		if (arr[index] < arr[r])
			swap(arr, ++lessr, index++);
		else if (arr[index] > arr[r])
			swap(arr, --morel, index);
		else
			index++;
	}
	swap(arr, morel, r);
	return { lessr + 1,morel };
}
void process(vector<int>& arr, int l, int r)
{
	if (l >= r)
	{
		return;
	}
	vector<int> a = partition(arr, l, r);
	process(arr, l, a[0] - 1);
	process(arr, a[1] + 1, r);

}
void quickSort(vector<int>& arr) {
	if (arr.empty() || arr.size() < 2) {
		return;
	}
	process(arr, 0, arr.size() - 1);
}
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
void swap(vector<int>& a, int i, int j)
{
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}
//快速排序的递归实现方法:以最右边的数作为分界,小于的放左边,大于的放右边等于的放中间
//对大数组做完上述操作后,再对小于区域和大于区域均做相同的操作,即可完成排序
vector<int> partition(vector<int>& arr, int l, int r)
{
	int lessr = l - 1;
	int morel = r;
	int index = l;
	while (index < morel)
	{
		if (arr[index] < arr[r])
			swap(arr, ++lessr, index++);
		else if (arr[index] > arr[r])
			swap(arr, --morel, index);
		else
			index++;
	}
	swap(arr, morel, r);
	return { lessr + 1,morel };
}
//非递归版本的快排主要是将一个大数组逐个用l r拆分成小数组,相当于将任务分解
void quickSort(vector<int>& arr) {
	if (arr.empty() || arr.size() < 2) {
		return;
	}
	stack<pair<int, int>> stk;
	stk.push({ 0,arr.size() - 1 });
	while (!stk.empty()) {
		pair<int, int> cur = stk.top();
		stk.pop();
		vector<int> e = partition(arr, cur.first, cur.second);
		if (e[0] > cur.first)//有小于区域
		{
			stk.push({cur.first,e[0]-1});
		}
		if (e[1] < cur.second)//有大于区域
		{
			stk.push({ e[1] + 1,cur.second });
		}

	}
}

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值