分治法中的排序問題

2021-06-07 01:04:59 字數 1698 閱讀 6421

分治法求解排序問題的思想很簡單,只需按某種方式將序列分為兩個或多個子串行,分別進行排序,再將已經排好序的子串行合併成乙個有序序列即可。合併排序和快速排序是兩種典型的符合分治策略的排序演算法。

合併排序的基本運算時把兩個或者多個有序序列合併成乙個有序序列。下面以兩路合併排序為例說明。

注:以c++為例。其中l為模板類sortlist的私有成員。

template

void  sortlist::merge(int left,int mid,int right)

t*temp=new int[right-left+1];//宣告乙個臨時陣列,用以儲存已經排好序的序列

int i=left,j=mid+1,k=0;

while((i<=mid)&&(j<=right))//兩個子串行都不為空

if(l[i]<=l[j])temp[k++]=l[i++];

else temp[k++]=l[j++];

while(i<=mid)第乙個子串行不為空,第二個序列為空。

temp[k++]=l[i++];

while(j<=right)第乙個子串行為空,第二個序列不為空。

temp[k++]=l[j++];

for( i=0;k=left;k<=right)//將排好序的temp複製到l中

l[k++]=temp[i++]                 

template

void sortlist::mergesort(int left ,int right)//將乙個序列分為兩個子串行

if(leftint mid=(left+right)/2;//將待排序的序列一分為二

mergesort(left,mid);//對做序列排序

mergesort(mid+1,right);//對有序列排序

merge(left,mid,right);//將兩個子串行合併成乙個有序序列

快速排序又稱為風化交換排序。快速排序採用一種特殊的分劃操作對排序問題進行分解,其分解方法是:在待排序的序列(k0,k1,…,kn-1)中選擇乙個元素作為分劃元素,也稱為主元(pivot)。不妨假定選擇ka為主元。經過一趟特殊的分劃處理將原序列中的元素重新排列,使得以主元為軸心,將序列分成左右兩個子串行。主元左測子串行中所有元素都不大於主元,主元右測子串行中所有元素都不小於主元。

分化函式partition,它將在下標為l[left,riht]範圍內的序列,以主元l[left]為中心分成兩個子串行,函式返回分化點j。

template

int sortlist::partition(int left,int right)//

int i=left,j=right+1;//l[riht+1]=乙個很大的數

do{while(l[i]<=l[left])i++;

while(l[j]>=left)j--;

if(iswap(i,j);//將l[i]和l[j]的值交換

swap(left,j);

return j;

template

void sortlist::quicksort(int left,int right)

if(leftint j=partition(left,right);//對l[left,right]範圍內的序列進行分化

quicksort(left,j);//對左序列實施快速排序

quicksort(j+1,right);//對又序列實施快速排序

排序問題的分治法

一 將乙個任意次序的由n個整數構成的單一序列,我們用於兩個序列,其中a為長度為n1的序列,b為長度為n2的序列,它們各自近似有n 2個元素,且這兩個序列都已經排序。二 merge 合併 演算法在o n1 n2 時間內可把兩個已經排序的序列組合成單一的排序序列。merge a,b n1 a的大小 n2...

分治法排序

分治法排序 1 把大問題分為小問題 2 求每個小問題的解 3 和1反方向,把各個解合併起來 實現 1 啟用兩個快取,乙個放前半部份問題,乙個放後半部份問題 2 只用乙個大快取,用index的大小區分問題規模 include include void megre pre int pre,int fir...

分治法排序

include include define temp 10 int a temp int b temp void merge int low,int mid,int high else k while i mid while j high for i 0 i k i b low i a i int...