1.歸併排序
分治模式:
(1)分解原問題為若干子問題,這些子問題是原問題的規模較小的例項。
(2)解決子問題,遞迴求解子問題。子問題規模足夠小時,直接求解。
(3)合併子問題的解,得到原問題的解。
歸併排序完全遵循分治模式。
(1)分解待排序的n個元素列成各具n/2個元素的兩個子串行。
(2)使用歸併排序遞迴地排序兩個子串行。
(3)合併兩個已排序的子串行,產生已排序的答案。
時間複雜度:t(n)=o(n*lgn)
**:
#include#includeusing
namespace
std;
vector
merge(vector vec1, vectorvec2)
else
}while (it1 !=vec1.end())
while (it2 !=vec2.end())
return
vec;
}void merge_sort(vector &vec)
merge_sort(vec1);
//vector
vec2;
for (auto it = vec.begin()+(vec.end() - vec.begin()) / 2 ; it != vec.end(); ++it)
merge_sort(vec2);
//vector
temp = merge(vec1, vec2);//
vec = temp;///
/儲存已排序的部分元素 }}
intmain()
; merge_sort(vec);
for(auto c : vec)
cout
<< c << ","
; cout
"pause");
return0;
}
2.最大子陣列問題
在含有負數(如果陣列元素全部為正數,那最大子陣列就是整個陣列)的陣列中找出元素之和最大的子陣列。
使用分治策略的求解方法:
設有a[low...high],mid=(low+high)/2,則最大子陣列a[i...j]:
(1)完全在a[low...mid]中,low<=i<=j<=mid.//子問題
(2)完全在a[mid+1...high]中,mid(3)跨越了中點,low<=i<=mid在三種情況中選取和最大者。
偽**:
array find_max_subarray(ivec,int low,inthigh)
;//base case:only one element
else
array
find_max_crossing_subarray(ivec,int low,int mid,int
high)
}sum=0
;
for(int j=mid+1;j<=high;j++)
}return ;//
最左下標、最右下標、元素之和
}
時間複雜度:t(n)=o(n*lgn)
不難發現,如果陣列元素全為負數,則最大子陣列就是最大元素。相應地,也有最小子陣列問題。
如果修改最大子陣列定義,允許最大子陣列為空,其和為0。在find_max_crossing_subarray函式中設定left-max,right-max初始值設為-1,left-sum,right-sum初始值設為0。另外find_max_subarray函式中,當low==high時
if(low==high);//base case:only one element
}
else
}}
更多討論。
最大子串行和 歸併排序
今天看劉汝佳看到歸併排序還看了分治求最大子串行和,感覺簡單多了,剛開始學時看了幾天都沒看會,現在在看感覺果然不一樣 先打乙個歸併排序,馬上就打子串行和,哎 為什麼總打這些水題呢,一是我現在很水,二是涉及人生完不完整的八數碼暫時理解不深 哈哈 勉強看懂,等過幾天就會相對高階的演算法了,這裡複製上一段話...
陣列歸併排序
include include using namespace std void print int a 歸併排序 思路 1 歸併排序 條件 小下標小,大下標大 分別對左半段和右半段進行歸併排序,然後合併 2 合併 把當前待排序列複製乙份 原來的陣列放排好序的元素 分兩段,依次比較左半段和右半段的元...
陣列的歸併排序
歸併排序 利用遞迴與分治的思想,先將陣列對半劃分,再對半劃分的陣列排序,從而使左右兩個子陣列各自有序,最後再將兩排序號的子陣列進行歸併成乙個大的有序陣列。具體 如下 include include using namespace std void mergesort vector arr,int s...