經典算法5:用分治法實現元素選擇
用分治法實現元素選擇所用函數:
在該程序中總共用了六個函數:
1、兩個數的交換函數swap( );
2、對一個數組進行劃分函數partition(int a[],int p,int r,int x);
3、快速排序函數 void quicksort(int a[],int p,int r);
4、選擇第k小數的函數int select(int a[],int p,int r,int k);
5、數組生成函數 void create_array( );
6、開始選擇函數 void begin_select( );
一、交換函數swap( )
void __fastcall TForm1:: swap(int &a,int &b)
{ //交換兩個整數a和b
int temp=a;
a=b;
b=temp;
}
二、劃分函數partition(int a[],int p,int r,int x)
int __fastcall TForm1::partition(int a[],int p,int r,int x)
{ int i=p; //把一個數組下標從p到r之間的數以x為基準
int j=r+1; //劃分為兩個部分
while(true)
{
while(a[++i]<x);
while(a[--j]>x);
if(i>=j) break; //
swap( a[i], a[j]); //調用交換函數來交換a[i]和a[j]
}
a[p]=a[j];
a[j]=x;
return j;
void __fastcall TForm1:: quicksort(int a[],int p,int r)
{ if(p<r) //把a[p]到a[r]的數進行快速排序
{
int q=partition(a,p,r,a[p]); //以a[p]為基準劃分數組
quicksort( a, p,q-1); //對左邊的數組排序
quicksort( a,q+1, r); //對右邊的數組排序
}
}
{
if(r-p<75) //當需選擇的數個數小于75時
{ //對它進行快速排序
quicksort(a,p,r);
return a[p+k-1];
}
{ //將a[p+5*i]到a[p+5*I+4]的數進行快速排序
quicksort(a,p+5*i,p+5*i+4);
swap(a[p+i],a[p+5*i+2]); // 交換a[p+i] 和a[p+5*i+2]
}
int x=select(a,p,p+(r-p-4)/5,(r-p-4)/10); //找中位數的中位數
int m=partition(a,p,r,x); //以中位數的中位數為基準劃分數組
int j=m-p+1;
if(k<=j)
else
}
{
for(int i=0;i<max;i++)
{ //循環調用隨機函數random()給array數組賦值
array[i]=random(max); //該函數中的max值可以根據需要隨意更改
str="array["+IntToStr(i)+"]="+IntToStr(array[i])+";";
Memo1->Lines->Append(str); //在Memo組件中顯示數組
Memo1->Lines->SaveToFile("array_before.txt");
} //把排序前的數組寫入文件名為array_before.txt的文件中
}
{
int no =StrToInt(Edit2->Text); //定義將要選擇的第幾小數
int first=StrToInt(Edit4->Text); //定義選擇區域的起始位置
int last=StrToInt(Edit5->Text); //定義選擇區域的終止位置
if( no>120 || no<0 || first>119 ||first<0 || last>119 || last<0 || first>last
|| first + no-1 > last)
{ //當no 、first和 last三個數的輸入不對時給出消息框
Application->MessageBoxA("輸入錯誤!","警告",48);
}
else
{
create_array(); //調用create_array()構造數組array
int result=select(array,first,last,no); //調用select函數對數組
AnsiString string;
for(int i=0;i<120;i++)
{ string="array["+IntToStr(i)+"]="+IntToStr(array[i])+";";
Memo2->Lines->Append(string); //排序顯示在Memo上
Memo2->Lines->SaveToFile("array_after.txt");
} //把排序前的數組寫入文件名為array_after.txt的文件中
}
{ //new一個AboutBox窗體
AboutBox=new TAboutBox(Application);
AboutBox->ShowModal(); //顯示該窗體
delete AboutBox; //釋放該對象
}