題目連結: https://zerojudge.tw/ShowProblem?problemid=a233
# 內容
排序,就對了
# 思路
難得有機會,來用一下 merge sort 吧
如圖所示:
- 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列;
- 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置;
- 比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置;
- 重複步驟 3 直到某一指標達到序列尾;
- 將另一序列剩下的所有元素直接複製到合併序列尾。
# 程式碼
#include<iostream> | |
using namespace std; | |
int arr[1000005]; | |
// 合併時需要兩個子陣列 | |
// 第一個是紀錄 arr [l..m] | |
// 第二個是紀錄 arr [m+1..r] | |
void merge(int arr[], int l, int m, int r) | |
{ | |
int i, j, k; | |
int n1 = m - l + 1; | |
int n2 = r - m; | |
int L[n1], R[n2]; | |
/* 將數值複製過去 L [] and R [] */ | |
for (i = 0; i < n1; i++) | |
L[i] = arr[l + i]; | |
for (j = 0; j < n2; j++) | |
R[j] = arr[m + 1 + j]; | |
/* 合併這兩者到 arr [l..r] 中 */ | |
i = 0; // 定義第一個的 index | |
j = 0; // 定義第二個的 index | |
k = l; // 定義被合併的 index | |
while (i < n1 && j < n2) { | |
if (L[i] <= R[j]) { | |
arr[k] = L[i]; | |
i++; | |
} | |
else { | |
arr[k] = R[j]; | |
j++; | |
} | |
k++; | |
} | |
/* 將剩餘的 L [] 複製過去 */ | |
while (i < n1) { | |
arr[k] = L[i]; | |
i++; | |
k++; | |
} | |
/* 將剩餘的 R [] 複製過去 */ | |
while (j < n2) { | |
arr[k] = R[j]; | |
j++; | |
k++; | |
} | |
} | |
void mergeSort(int arr[], int l, int r) | |
{ | |
if (l < r) { | |
int m = l + (r - l) / 2; | |
// 將排序分成二部分 | |
mergeSort(arr, l, m); | |
mergeSort(arr, m + 1, r); | |
// 整合 | |
merge(arr, l, m, r); | |
} | |
} | |
int main() | |
{ | |
int n; cin>>n; | |
for(int i = 0;i<n;i++) | |
cin>>arr[i]; | |
mergeSort(arr, 0, n-1); | |
for(int i = 0;i<n;i++) | |
cout<<arr[i]<<" "; | |
return 0; | |
} |