王道-置换选择排序b站教学视频
置换选择排序的流程
图片比文字更好理解,故不加文字解释
当当前工作区已经满了并且找不到合适的放入当前归并段的元素的时候,开始生成下一个归并段。
此后重复上述过程。
计算机考研可能考察置换选择排序的知识点
- 归并段个数 = 总的记录个数 / 每个归并段的长度 【上取整】
- 利用败者树选择minimax
- 外部排序
PAT 甲级 1171 Replacement Selection 题解
题目
给你一个长度为n的序列,和一个大小为m的内存空间,每次排序的大小不能超过m这个内存空间,使用置换选择算法,输出一个或者多个有序的序列
题解
- 知识点
置换选择排序
用于内部排序的内存工作区WA可容纳L个记录,则每个初始归并段也只能包含L个记录,若文件共有n个记录,则初始归并段的数量r=n/L
- 解题思路
- 利用priority_queue实现最小堆
- 将小于minimax的数放到下一行去进行处理
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, m; cin >> n >> m;
vector<int> arr(n);
for(int i = 0; i < n; i++){
cin >> arr[i];
}
priority_queue<int, vector<int>, greater<int>> wa;
vector<int> v, line; // v存放下轮的数,line存放本轮的数
//int wasize = 0; //工作区当前空闲大小
int minimax = INT_MIN;
int index = 0;
//将数先压入工作区
for(; index < m; index++){
wa.push(arr[index]);
}
int count = 0;
//用于统计是否处理完序列中的所有数字
while(count < n){
//因为当前工作区是第一组进入工作区的序列,所以直接处理就可以了
minimax = wa.top();
line.push_back(minimax);
wa.pop();
count++;
if (index < n){
if (arr[index] > minimax) {
wa.push(arr[index++]);
}
else {
v.push_back(arr[index++]);
}
}
if (wa.empty()){
//工作区为空的情况下
//说明第一行已经处理完毕了
for(int i = 0; i < line.size(); i++){
if (i == 0) cout << line[i];
else cout << " " << line[i];
}
cout << '\n';
line.clear();
for(int i = 0; i < v.size(); i++){
wa.push(v[i]);
}
v.clear();
}
}
}