题目描述
给定一个数列,用归并排序算法把它排成升序。
输入
第一行是一个整数n(n不大于10000),表示要排序的数的个数;
下面一行是用空格隔开的n个整数。
输出
输出排序后的数列,每个数字占一行。
样例输入
5 3 2 1 4 5
样例输出
1
2
3
4
5
代码实现
#include <iostream>
using namespace std;
/*
* 归并排序的基本原理:
* 1.首先给定一个数组,先进行划分,划分时用到一个临时数组。
* 2.递归的进行划分,先划分左半,再划分右半。
* 3.不能划分时,对他们进行合并。
* 4.当有剩余部分时,剩余部分追加到合并数组的后面。
* 5.用临时数组覆盖原数组,释放临时数组。
*/
void printArr(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
cout << arr[i] << " ";
}
cout << arr[n - 1] << endl;
}
void m_merge(int arr[], int arrTmp[], int left, int right, int mid) {
int l_pos = left;
int r_pos = mid +1;
int pos = left;
while (l_pos <= mid && r_pos <= right) {
// 比较两个数组的第一个元素,谁的小就放在前面
if (arr[l_pos] < arr[r_pos]) {
arrTmp[pos++] = arr[l_pos++];
}
else
{
arrTmp[pos++] = arr[r_pos++];
}
}
// 剩余部分追加到合并数组的后面
while (l_pos <= mid)
{
arrTmp[pos++] = arr[l_pos++];
}
// 剩余部分追加到合并数组的后面
while (r_pos <= right)
{
arrTmp[pos++] = arr[r_pos++];
}
// 合并的数组(部分)覆盖原数组
while (left <= right)
{
arr[left] = arrTmp[left];
left++;
}
}
void m_sort(int arr[], int arrTmp[], int left, int right) {
if (left < right)
{
int mid = (left + right) / 2;
// 递归分割左半部分
m_sort(arr, arrTmp, left, mid);
// 递归分割右半部分
m_sort(arr, arrTmp, mid+1, right);
// 将分割玩的数组进行排序合并
m_merge(arr, arrTmp, left, right, mid);
}
}
// 归并排序的入口
void merge_sort(int arr[], int n) {
// 判断输入的原数组是否存在
if (arr == NULL || n <= 0) {
return;
}
// 创建一个临时数组
int* arrTmp = new int[n];
if (arrTmp) {
// 临时数组创建成功,开始分割数组
m_sort(arr,arrTmp,0,n-1);
delete[] arrTmp;
}
else
{
cout << "临时数组分配错误" << endl;
}
}
int main2()
{
int arr[9] = { 9, 5, 1, 4, 8, 6, 2, 3, 7 };
// 打印原始数组
printArr(arr, 9);
// 归并排序
merge_sort(arr,9);
// 打印排序后的数组
printArr(arr, 9);
return 0;
}
int main()
{
int n = 0;
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
merge_sort(arr, n);
for (int i = 0; i < n; i++) {
cout << arr[i] << endl;
}
return 0;
}