8645 归并排序(非递归算法)
时间限制:1000MS 代码长度限制:10KB
提交次数:2398 通过次数:1192
题型: 编程题 语言: G++;GCC
Description
用函数实现归并排序(非递归算法),并输出每趟排序的结果
输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据
输出格式
每行输出每趟排序的结果,数据之间用一个空格分隔
输入样例
10
5 4 8 0 9 3 2 6 7 1
输出样例
4 5 0 8 3 9 2 6 1 7
0 4 5 8 2 3 6 9 1 7
0 2 3 4 5 6 8 9 1 7
0 1 2 3 4 5 6 7 8 9
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
//归并两个部分 bg为第一部分的起点 mid为第二部分的起点 end为第二部分边界的下一位
void Merge(int num[], int bg, int mid, int end)
{
//建立临时数组存两个部分的合并后的数组
int* tmp = new int[end - bg];
int i = bg, j = mid;
int k = 0;
//比较两部分 当i=mid 或j=end 退出
while (i < mid && j < end)
{
//由大小依次排序放到临时数组里 直到一个部分排完退出
if (num[i] > num[j])
{
tmp[k++] = num[j++];
}
else {
tmp[k++] = num[i++];
}
}
//如果前半部分没存完 依次存进去
while (i < mid) {
tmp[k++] = num[i++];
}
//如果后半部分没存完 依次存进去
while (j < end) {
tmp[k++] = num[j++];
}
//把排好的临时数组存到num数组对应下标里
for (int i = 0; i < k; i++) {
num[bg++] = tmp[i];
}
}
int main(void) {
ios::sync_with_stdio(0), cin.tie(0);
int n;
cin >> n;
int* num = new int[n + 1];
for (int i = 1; i <= n; i++) cin >> num[i];
//width为一部分的长度 依次为1 2 4 8 外层判断条件不能写width<=n 取等可能会重复输出一次
for (int width = 1; width < n; width *= 2) {
// 第一部分起点bg为1 下一次为 bg+两个长度
for (int bg = 1; bg <= n; bg += width * 2) {
//mid为第二部分的起点
int mid = bg + width;
//为了防止访问错误 如果mid边界大于 n则最大为 n+1
if (mid > n)mid = n + 1;
//end为第二部分边界的下一位
int end = bg + width * 2;
//同理 最大只能为 n+1
if (end > n)end = n + 1;
//合并两部分
Merge(num, bg, mid, end);
}
//检查
for (int i = 1; i <= n; i++) cout << num[i] << ' ';
cout << endl;
}
return 0;
}