C++ 歸併排序與快速排序
阿新 • • 發佈:2018-11-13
歸併排序:
【演算法邏輯】
歸併的思路(分治)是把一個大問題a拆解成兩個小問題b和c,解決了兩個子問題再整合一下,就解決了原問題。用遞迴的方法,先分解再合併(分治是一種解決問題的處理思想,遞迴是一種程式設計技巧,這兩者並不衝突):
【程式碼實現】
#include<iostream> using namespace std; void Merge(int arr[], int l, int q, int r){ int n=r-l+1;//臨時陣列存合併後的有序序列 int* tmp=new int[n]; int i=0; int left=l; int right=q+1; while(left<=q && right<=r) tmp[i++] = arr[left]<= arr[right]?arr[left++]:arr[right++]; while(left<=q) tmp[i++]=arr[left++]; while(right<=r) tmp[i++]=arr[right++]; for(int j=0;j<n;++j) arr[l+j]=tmp[j]; } void MergeSort(int arr[], int l, int r){ if(l==r) return; int q = (l + r)/2; MergeSort(arr, l, q); MergeSort(arr, q + 1, r); Merge(arr, l, q, r); } int main(){ int a[8] = {3,1,2,4,5,8,7,6}; MergeSort(a,0,8); for(int i=0;i<8;++i) cout<<a[i]<<" "; }
快速排序:
【演算法邏輯】
從數列中挑出一個元素,稱為 “基準”(pivot);
重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割槽退出之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作;
遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
根據分治、遞迴的處理思想,我們可以用遞迴排序下標從 p 到 q-1 之間的資料和下標從 q+1 到 r 之間的資料,直到區間縮小為 1,就說明所有的資料都有序了。這裡涉及到基準的選擇問題,因此必須有函式Partition()來實現“基準”。
【程式碼實現】
#include<iostream> using namespace std; int Parition(int a[], int low,int high){ int pivot=a[high]; int i=low; for(int j=low;j<high;++j) { if (a[j]<pivot) { swap(a[j], a[i]); i++; } } swap(a[i], a[high]); return i; } void QuickSort(int a[], int low, int high){ if(low<high) { int q=Parition(a,low, high); QuickSort(a, low, q-1); QuickSort(a, q+1,high); } } int main(){ int a[8] = {3,1,2,4,5,8,7,6}; QuickSort(a,0,8); for(int i=0;i<8;++i) cout<<a[i]<<" "; }