算法学习(1)快速排序/归并排序/二分

排序:快排,归并排序
二分:整数,浮点数

1,快速排序大排列

785.快速排序测试

https://www.acwing.com/problem/content/787
在这里插入图片描述

常规递归查找(不可以)

#include<iostream>
using namespace std;

const int N = 100001;
int Partion(int[], int, int);
void Qsort(int a[], int low, int high) {
	if (low < high) {
		int p = Partion(a, low, high);
		Qsort(a, low, p - 1);
		Qsort(a, p + 1, high);
	}
}
int Partion(int a[], int low, int high) {
	int p = a[low];
	while (low < high) {
		while (low < high && a[high] >= p) high--;
		a[low] = a[high];
		while (low < high && a[low] <= p) low++;
		a[high] = a[low];
	}
	a[low] = p;
	return low;
}
int main() {
	int a[N];
	int size = 0;
	cin >> size;
	for (int i = 0; i < size; i++) {
		 cin >> a[i];
	}
	Qsort(a, 0, size - 1);
	for (int i = 0; i < size; i++) {
		cout << a[i] << " ";
	}
}

递归法改进(可以)

在这里插入图片描述

#include<iostream>
using namespace std;

const int N = 100001;
int a[N] = { 0 };


void Qsort(int a[], int low, int high) {
	if (low >= high)
		return;

	int   p = a[(low + high) >> 1], i = low - 1, j = high + 1;	//	j >= l,i<=r-1

	while (i < j) {
		//a[0..i-1] <= p, a[i] >= p
		do
			i++;
		while (a[i] < p);

		// a[j+1..r] >= p, a[j] <= p
		do
			j--;
		while (a[j] > p);

		if (i < j)
			swap(a[i], a[j]);
	}
	Qsort(a, low, j);
	Qsort(a, j + 1, high);
}

int main() {
	int size;
	cin >> size;
	for (int i = 0; i < size; i++) {
		cin >> a[i];
	}
	Qsort(a, 0, size - 1);
	for (int i = 0; i < size; i++) {
		cout << a[i] << " ";
	}
}

#include<iostream>
using namespace std;

const int N = 100001;
int a[N] = { 0 };

void Qsort(int a[], int low, int high) {
	if (low >= high)
		return;

	int  i = low - 1, j = high + 1, p = a[(low + high + 1) >> 1];//

	while (i < j) {
		do
			i++;
		while (a[i] < p);

		do
			j--;
		while (a[j] > p);


		if (i < j)
			swap(a[i], a[j]);
	}

	Qsort(a, low, i-1);
	Qsort(a, i, high);
}

int main() {
	int size = 0;
	cin >> size;
	for (int i = 0; i < size; i++) {
		cin >> a[i];
	}
	Qsort(a, 0, size - 1);
	for (int i = 0; i < size; i++) {
		cout << a[i] << " ";
	}
}


方法分析:https://www.acwing.com/solution/content/16777/

2、归并排序

787.归并排序测试

https://www.acwing.com/problem/content/description/789
在这里插入图片描述

常规递归查找(不可以)

#include<iostream>
using namespace std;

const int N = 100000;
int a[N],s[N];

// 比较放入
void Merge(int a[], int b[], int low, int high);
// 比较排序
void Msort(int a[], int b[], int low, int high);

void Msort(int a[], int b[], int low, int high) {
	int t[N] = { 0 };
	 //第一步:分成子问题
	if (low == high) {
		b[low] = a[high];
	}else {
		int mid = (low + high) >> 1;
		 //第二步:递归处理子问题
		Msort(a, t, low, mid);
		Msort(a, t, mid + 1, high);
		 //第三步:子问题合并
		Merge(t, b, low, high);
	}
}
void Merge(int a[], int b[], int low, int high) {
	int mid = (low + high) >> 1;
	int i = low, j = mid + 1,k=low;
	while (i <= mid && j <= high) {
		b[k++] = (a[i] <= a[j] ? a[i++] : a[j++]);
	}
	while (i <= mid) b[k++] = a[i++];
	while (j <= high) b[k++] = a[j++];
}
int main() {
	int size = 0;
	scanf_s("%d", &size);
	for (int i = 0; i < size; i++) {
		cin >> a[i];
	}
	Msort(a, s, 0,size-1);
	for (int i = 0; i < size; i++) {
		cout << s[i] << " ";
	}
}

在这里插入图片描述

递归法改进

#include<iostream>
using namespace std;

const int N = 100000;
// 输入
int a[N],i,j;

void MergeSort(int a[], int low, int high) {
	if (low >=  high)	return;
	int mid = (low + high) >> 1;
	MergeSort(a, low, mid);
	MergeSort(a, mid + 1, high);
	i = low, j = mid + 1;
	int k = 0;
	int* tmp = (int*)malloc(sizeof(int) * (high - low + 1));
	while (i <= mid && j <= high) {
		tmp[k++] = a[i] < a[j] ? a[i++] : a[j++];
	}
	while (i <= mid) 
		tmp[k++] = a[i++];
	while (j <= high)
		tmp[k++] = a[j++];
	for (i = 0; i < high - low + 1; i++) {
		a[low + i] = tmp[i];
	}
	free(tmp);
}
int main() {
	int size = 0; 
	cin >> size;
	for (i = 0; i < size; i++) {
		cin >> a[i];
	}
	MergeSort(a, 0, size - 1);
	for (i = 0; i < size; i++) {
		cout << a[i] << " ";
	}
}

3、二分法查找

789. 数的范围

https://www.acwing.com/problem/content/791/
在这里插入图片描述

整数二分的模板:

// 判断mid是否满足性质 
bool check(int);

int bsearch_1(int l, int r) {
	while (l < r) {
		int mid = l + r >> 1;
		if (check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	return l;
}

int bsearch_2(int l, int r) {
	while (l < r) {
		int mid = l + r + 1 >> 1;
		if (check(mid))
			l = mid;
		else
			r = mid - 1;
	}
	return l;
}
#include<iostream>
using namespace std;
const int N = 100010;
int q[N];

int main() {
	int n, m, i, x;
	cin >> n >> m;
	for (i = 0; i < n; i++) {
		cin >> q[i];
	}
	//	需要写两个二分,一个需要找到 >= x的第一个数,另一个需要找到 <= x的最后一个数
	while (m--) {
		cin >> x;
		int l = 0, r = n - 1;
		int mid;

		while (l < r) {
			mid = (l + r) >> 1;
			if (q[mid] >= x)
				r = mid;
			else
				l = mid + 1;
		}

		if (q[l] != x) {
			cout << "-1 -1" << endl;
			continue;
		}
		else {
			cout << l << " ";
			l = 0, r = n - 1;
			while (l < r) {
				mid = (l + r+1) >> 1;
				if (q[mid] <= x)
					l = mid;
				else
					r = mid - 1;
			}
			cout << l << endl;
		}
	}
	return 0;
}

浮点数二分的模板

例如 求浮点数开方:

#include<iostream>
using namespace std;
int main() {
	double x,mid;
	cin >> x;
	double l = 0, r = x;
	while (r - l > 1e-6) {	// 保留四位小数
		mid = (l + r) / 2;
		if (mid * mid >= x)
			r = mid;
		else
			l = mid;
	}
	cout << l << endl;
}

数的三次方:

https://www.acwing.com/problem/content/description/792/
在这里插入图片描述
二分法:

#include<iostream>
#include <iomanip> 
using namespace std;
// x^3 =n  ->  x=?
void test_half() {
	double n;
	cin >> n;
	//结果保留6位小数  −10000≤n≤10000
	double precision = 1e-8;
	double l = -10000, r = 10000, mid = 0;
	while (r - l > precision) {
		mid = (l + r) / 2;
		if (mid * mid * mid >= n)
			r = mid;
		else
			l = mid;
	}
	// 或 printf("%.6f", l); 
	cout<< setiosflags(ios::fixed) << setprecision(6)<< l << endl;
}

int main() {
	test_half();
}

牛顿法

#include<iostream>
#include <iomanip> 
#include<math.h>
using namespace std;
void test_newton() {
	double n;
	cin >> n;
	//结果保留6位小数  −10000≤n≤10000
	double precision = 1e-8;
	double x0 = 1 , x1;
	x1 = x0 - (x0 * x0 * x0 - n) / (3 * x0 * x0);
	while (fabs(x1 - x0) >= precision) {
		x0 = x1;
		x1 = x0 - (x0 * x0 * x0 - n)/ (3 * x0 * x0) ;
	}
	cout << setiosflags(ios::fixed) << setprecision(6) << x1 << endl;
}
int main() {
	test_newton() ;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

广大菜鸟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值