程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 在讀算法導論關於歸並排序

在讀算法導論關於歸並排序

編輯:C++入門知識

回顧算法導論的第一個講解的算法就是歸並排序,我們把歸並排序分解為兩個步驟,第一步考慮如何進行歸並,第二步把問題分解為多次歸並排序和歸並,這是一個典型的分治思想。

每一層的調用有三個步驟:

分解:將原問題分解成若干子問題

解決:解決這些子問題,遞歸求解各個子問題。若子問題規模足夠小,則直接求解。

合並:將這些子問題的解合並成原問題的解。

要使用分治的前提是問題是線性可以合並的,如果是非線性問題,使用分治時問題將會變得很復雜。

我們將合並的數組理解為撲克牌,先把它分為兩堆牌,然後進行合並。當然數值上不會是撲克牌的數值,大家可以設想下手裡面有和他要排序數值一樣的撲克牌。

歸並排序的算法主要集中於歸並這一操作,拋開遞歸,我們單獨分析歸並這一操作,首先將兩個堆底部放入哨兵牌,可以理解為撲克牌中王一樣,它是一個還有特殊的值,為了簡化這裡放入100;結果每當顯露出哨兵牌,他不可能為較小的牌,除非兩個堆都已經顯露出哨兵牌。但這種情況一旦發生,我們的歸並操作也就結束了。因為我們事先知道剛好執行r-p+1張牌將被放置到輸出堆。

代碼如下:

 

 

[cpp]
#include <stdio.h>  
#include <iostream>  
using namespace std; 
 
void Merge(int* A,int p,int q,int r) 

    int n1= q-p+1; 
    int n2= r-q; 
     
    int *L= new int[n1+1]; 
    int *R= new int[n2+1]; 
 
 
    int i=0; 
    int j=0; 
 
 
    for(i=0;i<n1;i++) 
    { 
        L[i]=A[p+i-1]; 
         
    } 
     
    for(j=0;j<n2;j++) 
    { 
        R[j]=A[q+j]; 
     
    } 
 
 
    L[n1] = 100;//代表數組中不可能出現的無窮大的數  
    R[n2] = 100;//<SPAN style="FONT-FAMILY: Arial, Helvetica, sans-serif">代表數組中不可能出現的無窮大的數</SPAN>  
 
     
    i = 0; 
    j = 0; 
     
    for(int k = p-1;k < r; k++) 
    { 
        if(L[i]<=R[j]) 
        { 
            A[k] = L[i]; 
            i = i+1; 
        } 
        else 
        { 
            A[k] = R[j]; 
            j = j+1;     
        } 
    } 

 
 
void Merge_Sort(int *A,int p,int r) 

    if(p<r) 
    { 
        int q=(p+r)/2; 
        Merge_Sort(A,p,q); 
        Merge_Sort(A,q+1,r); 
        Merge(A,p,q,r); 
    } 

 
 
int A[15] = {11,12,13,14,15,1,2,3,4,5,6,7,8,9,10};  
 
 
int main(int argc, char **argv) 

    Merge_Sort(A,1,15); 
     
    for(int i=0;i<15;i++) 
    { 
        cout<<A[i]<<"\t"; 
    } 
    cout<<endl; 
    system("pause"); 
    return 0; 

#include <stdio.h>
#include <iostream>
using namespace std;

void Merge(int* A,int p,int q,int r)
{
 int n1= q-p+1;
 int n2= r-q;
 
 int *L= new int[n1+1];
 int *R= new int[n2+1];


 int i=0;
 int j=0;


 for(i=0;i<n1;i++)
 {
  L[i]=A[p+i-1];
  
 }
 
 for(j=0;j<n2;j++)
 {
  R[j]=A[q+j];
 
 }


 L[n1] = 100;//代表數組中不可能出現的無窮大的數
 R[n2] = 100;//代表數組中不可能出現的無窮大的數

 
 i = 0;
 j = 0;
 
 for(int k = p-1;k < r; k++)
 {
  if(L[i]<=R[j])
  {
   A[k] = L[i];
   i = i+1;
  }
  else
  {
   A[k] = R[j];
   j = j+1; 
  }
 }
}


void Merge_Sort(int *A,int p,int r)
{
 if(p<r)
 {
  int q=(p+r)/2;
  Merge_Sort(A,p,q);
  Merge_Sort(A,q+1,r);
  Merge(A,p,q,r);
 }
}


int A[15] = {11,12,13,14,15,1,2,3,4,5,6,7,8,9,10};


int main(int argc, char **argv)
{
 Merge_Sort(A,1,15);
 
 for(int i=0;i<15;i++)
 {
  cout<<A[i]<<"\t";
 }
 cout<<endl;
 system("pause");
 return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved