經典算法5:用分治法實現元素選擇

cwf8 11年前發布 | 3K 次閱讀 C/C++ 算法

用分治法實現元素選擇所用函數:

在該程序中總共用了六個函數:
    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;

}

三、快速排序函數 quicksort(int a[],int p,int r)
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);                     //對右邊的數組排序
}   
 }
四、選擇第k小數的函數int select(int a[],int p,int r,int k)
int __fastcall TForm1::select(int a[],int p,int r,int k)
{
   if(r-p<75)                 //當需選擇的數個數小于75時
  {                        //對它進行快速排序
      quicksort(a,p,r);   
      return a[p+k-1];
   }
for(int i=0;i<=(r-p-4)/5;i++)
   {                        //將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)  
return  select(a,p,m,k);   //在中位數的中位數左邊選擇
   else
return  select(a,m+1,r,k-j);       //在中位數的中位數右邊選擇
}
五、數組生成函數 void create_array( )
void __fastcall TForm1::create_array()
{  
int max=120;                 //定義數組大小為120;
    AnsiString str;
  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的文件中
}
六、開始選擇函數 void begin_select( );
void __fastcall TForm1::begin_select( )

  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函數對數組    
Edit3->Text=IntToStr(result);                       //進行選擇
    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的文件中
}  
}
七、動態產生AboutBox窗體的代碼
void __fastcall TForm1::N3Click(TObject *Sender)
{                                           //new一個AboutBox窗體
      AboutBox=new TAboutBox(Application);
      AboutBox->ShowModal();             //顯示該窗體
      delete AboutBox;                             //釋放該對象
}

 本文由用戶 cwf8 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!