【排序】歸併排序(遞迴和非遞迴版本)
阿新 • • 發佈:2019-02-19
#include<iostream> using namespace std; void merge(int* a, int* temp, int begin, int middle, int end){ int i = begin; int j = middle + 1; int k = 0; while (i <= middle&&j <= end){//比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置 if (a[i] < a[j]) temp[k++] = a[i++]; else temp[k++] = a[j++]; } while (i <= middle)//若第一個序列有剩餘,直接拷貝出來粘到合併序列尾 temp[k++] = a[i++]; while (j <= end)//若第二個序列有剩餘,直接拷貝出來粘到合併序列尾 temp[k++] = a[j++]; for (i = 0; i < k; i++)//將排序好的序列拷貝回陣列中 a[begin + i] = temp[i]; } //遞迴版本 void merge_sort_recurse(int* a, int* temp, int begin, int end){ int middle = (begin + end) >> 1; if (begin < end){ merge_sort_recurse(a, temp, begin, middle);//左邊有序 merge_sort_recurse(a, temp, middle + 1, end);//右邊有序 merge(a, temp, begin, middle, end);//再將兩個有序數列合併 } } //非遞迴版本,將a中相鄰長度為s的子序列兩兩歸併 void merge_pass(int* a, int* temp, int s, int len){ int i = 0; int j; while (i < len - 2 * s + 1){ merge(a, temp, i, i + s - 1, i + 2 * s - 1); i += 2 * s; } if (i < len - s + 1)//歸併最後兩個序列 merge(a, temp, i, i + s - 1, len); } void merge_sort_no_recurse(int* a, int len){ int temp[1001]; int k = 1; while (k <= len){ merge_pass(a, temp, k, len); k *= 2; //子序列長度加倍 } } int main(){ int num1[1001] = { 50, 10, 90, 30, 70, 40, 80, 60, 20 }; int temp1[1001]; int num2[1001] = { 50, 10, 90, 30, 70, 40, 80, 60, 20 }; int n = 9; merge_sort_recurse(num1, temp1, 0, n-1); for (int i = 0; i < n; i++) cout << num1[i] << " "; cout << endl; merge_sort_no_recurse(num2, n - 1); for (int i = 0; i < n; i++) cout << num2[i] << " "; cout << endl; return 0; }