vault backup: 2026-06-10 11:19:43

This commit is contained in:
2026-06-10 11:19:43 +08:00
parent 788576ec4b
commit b9bc08ab2f
6 changed files with 391 additions and 209 deletions
+69 -39
View File
@@ -65,13 +65,21 @@ flowchart TD
归并排序是分治法最经典的应用之一,时间复杂度 **O(n logn)**。
```plaintext
function mergeSort(A, left, right):
if left < right:
mid = (left + right) / 2
mergeSort(A, left, mid) // 分解:排序左半部分
mergeSort(A, mid+1, right) // 分解:排序右半部分
merge(A, left, mid, right) // 合并:合并两个有序子数组
```cpp
#include <vector>
using namespace std;
// merge函数省略,此处仅展示归并排序的分治骨架
// void merge(vector<int>& A, int left, int mid, int right) { ... }
void mergeSort(vector<int>& A, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(A, left, mid); // 分解:排序左半部分
mergeSort(A, mid + 1, right); // 分解:排序右半部分
// merge(A, left, mid, right); // 合并:合并两个有序子数组
}
}
```
- **分解**:将数组从中间分为两半
@@ -95,28 +103,42 @@ function mergeSort(A, left, right):
- 每组2个元素:组内比较1次,再与当前最大、最小各比较1次
- 比较次数从 **2(n-1)** 降至约 **3n/2**
```plaintext
function findMaxMin(A, n):
// 初始化
if n is odd:
maxVal = minVal = A[1]
start = 2
else:
if A[1] < A[2]:
minVal = A[1], maxVal = A[2]
else:
minVal = A[2], maxVal = A[1]
start = 3
```cpp
#include <vector>
#include <utility>
using namespace std;
// 两两比较
for i = start to n step 2:
if A[i] < A[i+1]:
smaller, larger = A[i], A[i+1]
else:
smaller, larger = A[i+1], A[i]
if smaller < minVal: minVal = smaller
if larger > maxVal: maxVal = larger
return (maxVal, minVal)
// 同时求最大值和最小值,比较次数约 3n/2
pair<int, int> findMaxMin(vector<int>& A, int n) {
int maxVal, minVal;
int start;
// 初始化:根据元素个数的奇偶性决定初始值
if (n % 2 == 1) {
maxVal = minVal = A[0];
start = 1;
} else {
if (A[0] < A[1]) {
minVal = A[0]; maxVal = A[1];
} else {
minVal = A[1]; maxVal = A[0];
}
start = 2;
}
// 两两比较:每组内比较1次,再分别与全局最大最小比较
for (int i = start; i < n; i += 2) {
int smaller, larger;
if (A[i] < A[i + 1]) {
smaller = A[i]; larger = A[i + 1];
} else {
smaller = A[i + 1]; larger = A[i];
}
if (smaller < minVal) minVal = smaller;
if (larger > maxVal) maxVal = larger;
}
return {maxVal, minVal};
}
```
**解释**:每次循环处理两个元素,组内比较1次确定大小,再分别与全局最大最小比较最多2次,所以每组最多3次比较。总比较次数约为 3(n-1)/2。
@@ -129,17 +151,25 @@ function findMaxMin(A, n):
2. 只有当某个元素**大于当前最大值**时,才更新第二大值
3. 一次遍历即可完成
```plaintext
function findSecondMax(A, n):
maxVal = A[1]
secondMax = -infinity
for i = 2 to n:
if A[i] > maxVal:
secondMax = maxVal // 原来的最大变为第二
maxVal = A[i] // 更新最大
else if A[i] > secondMax:
secondMax = A[i] // 更新第二
return secondMax
```cpp
#include <vector>
#include <climits>
using namespace std;
// 一次遍历找第二大的数,时间O(n)
int findSecondMax(vector<int>& A, int n) {
int maxVal = A[0];
int secondMax = INT_MIN;
for (int i = 1; i < n; i++) {
if (A[i] > maxVal) {
secondMax = maxVal; // 原来的最大变为第二
maxVal = A[i]; // 更新最大
} else if (A[i] > secondMax) {
secondMax = A[i]; // 更新第二
}
}
return secondMax;
}
```
#### 4.5 伪币问题