算法第二章实践作业

归并排序算法

分治思想:把大问题拆解成若干个有规律的小问题

[!NOTE] 理解归并的含义
归:递归,作用是切分成最小为1个的数组
并:合并,两个数组合成时的选择策略

快速排序算法

关键词: #基准值 #指针覆盖 #递归

1、快速排序基本题型:

给定n个整数,请按照从小到大的顺序排序。

输入格式:
第一行数字n,1<=n<=100000
第二行n个整数,以一个空格分隔

输出格式:
从小到大排序后的数字,以一个空格分隔

输入样例:

5
4 2 1 3 5

输出样例:

1 2 3 4 5
#include <iostream>
using namespace std;

int a[1000000];

void quickSort(int left, int right) {
	if (left >= right) return;
	int i = left;
	int j = right;
	int p = a[left];
	while (i < j) {
		while (i < j && a[j] > p) {
			j--;
		}
		if (i < j) {
			a[i] = a[j];
		}
		while (i < j && a[i] < p) {
			i++;
		}
		if (i < j) {
			a[j] = a[i];
		}
	}
	a[i] = p;
	quickSort(left, i - 1);
	quickSort(i + 1, right);
}

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

注意:选择左基准,要从 j 从右往左开始找!
区分好下标、i j 指针、 left right 起始点
自己画图模拟这个过程

index 0 1 2 3 4
nums 4 2 1 3 5

微信图片_20251102230800_1357_745

自然语言描述:
1、全局定义数组,main 函数中要调用 quickSort 函数
2、quickSort 函数中要写递归的返回条件,然后下面开始定义指针,指针和始末点不要混为一体,不一样的,选择基准值,选左基准的话就要先移动 j 指针
3、外循环是 while(i < j) 里面两个 while 循环注意是先 j 后 i
4、按照以基准值为分割点,左小右大的格式来排
5、最后要复原 i = j 的值等于基准值
6、递归选好传入的始末点

如果要用快速排序思想来找第 k 小的数的话,就要在上面的基础多写一个 find 递归函数,取消 quickSort 的递归

时间复杂度的分析:
-最好时间复杂度:(O(n \log n))(每次划分均匀,子问题规模接近)。
-最坏时间复杂度:(O(n^2))(每次划分极端不平衡,子问题规模相差极大)。

总结

分治法的核心是 “拆解复杂问题,利用子问题的解构建原问题的解”,其价值不仅在于高效解决特定问题(如排序、查找、分形计算等),更在于提供了一种 “化繁为简” 的思维框架。但使用时需注意拆分的均匀性和合并的效率,避免陷入 “为分治而分治” 的误区。理解分治法,本质上是理解 “如何通过合理的结构拆分,将问题的复杂度控制在可接受的范围内”—— 这既是算法设计的关键,也是解决现实问题的重要思路。

posted @ 2025-11-02 23:43  欧伟健  阅读(4)  评论(0)    收藏  举报