演算法分析——分治策略
阿新 • • 發佈:2018-12-19
1 分治策略概念
分治法是講一個複雜的問題分成兩個或者更多的相同或者相似的問題,這些子問題相互獨立或者形式相同,再把子問題分解成更小的子問題,一直這樣迴圈下去,直到最後子問題可以簡單的直接求解,原問題的解即子問題解得合併。
例1.1
給定一個順序表,編寫一個求出其最大值與最小值的分治演算法。
分析:假設我們的資料按順序的存放在一個整型陣列中,如果陣列大小為1,那麼就可以直接給出結果,如果大小為2,那麼比較一次就可以給出結果,如果求解問題陣列長度大於2,我們就把問題規模縮小,直到縮小到問題可以解決為止,所以分治策略演算法如下:
#include "pch.h" #include <iostream> using namespace std; //s代表當前分治段的起始下標,e代表結束下標,meter代表陣列地址,max,min分別代表存放最大值最小值的地址 void partionGet(int s, int e, int *meter, int *max, int *min) { if (e - s <= 1) { if (meter[s] > meter[e]) { if (meter[s] > *max) *max = meter[s]; if (meter[e] < *min) *min = meter[e]; } else { if (meter[e] > *max) *max = meter[e]; if (meter[s] < *min) *min = meter[s]; } return; } int i = s+(e-s) / 2; partionGet(s, i, meter, max, min);//在這裡使用了二分法 partionGet(i+1, e, meter, max, min); } int main() { int max=0, min=0; int arr[10] = { 1,2,3,4,5,6,7,8,9,0 }; partionGet(0, 9, arr, &max, &min); cout << max << " " << min << endl; return 0; }
排序問題
例1.2
歸併排序,簡單來說,歸併排序就是利用了分治策略,樓主專門寫過一篇關於歸併排序遞迴演算法與非遞迴演算法的實現,在這裡就不在重複寫了,請點選下連線。
例1.3
快速排序是一種基於分治策略排序的一種演算法。其基本思想是對於給定的待排序序列a[p:r],按照以下步驟進行:
(1)分解,一a[p]作為基準將陣列a[p:r]劃分成三段a[p:q-1],a[q]和a[q+1:r],使a[p:q-1]中任何一個元素都小於a[q],a[q+1:r]中任何一個元素都大於a[q].下標q在劃分過程中確定。
(2)遞迴求解,通過遞迴呼叫快速排序演算法對a[p:q-1]和a[q+1:r]進行排序。
(3)合併,對於a[p:q-1]和a[q+1:r]的排序是就地進行的,所以在a[p:q-1]和a[q+1:r]都已經排好序後,,不需要進行任何計算,a[p:r]已經排好序。
基於這個思想,可實現快速排序演算法:
void quickSort(int arr[], int left, int right) {//對arr陣列進行快拍,按照非遞減有序排列 if (left < right)//如果元素序列長度小於一不處理 { int pivotpos = Partition(arr, left, right, right - left + 1);//一趟劃分 quickSort(arr, left, pivotpos);//處理左側序列 quickSort(arr, pivotpos + 1, right);//處理右側序列 }
對於含有n個元素的陣列arr[0:n],進行快速排序只要呼叫quickSort(arr,0,n)即可。
演算法中Partition是以一個確定的基準元素arr[p]對子陣列arr[p:r]進行劃分。
int Partition(int arr[], int low, int high, int num)
{
int i = low, j = high, pivot = arr[low];//基準元素
while (i < j)
{
while (i < j&&arr[j] >= pivot)//反向掃描,找第一個比基準小的元素,移到左邊
j--;
if (i < j)
{
arr[i] = arr[j];
i++;
}
while (i < j&&arr[i] < pivot)//找比基準大的元素,移到右邊
i++;
if (i < j)
{
arr[j] = arr[i];
j--;
}
}
arr[i] = pivot;//將基準元素就位
return i;
}
未完。。。。