全排列 c++實現


全排列就是指n個元素隨機組合,不重復的所有排列方式,如{1,2,3}就有123,132,213,231,312,321一共6種排列方式。

常見的算法實現分為 遞歸 和 非遞歸 ,這里我們用一個例子來輔助說明。{1,2,3,4}

 

遞歸的實現:遞歸是一種優雅的思想,層層推進。首先,我們知道要實現1,2,3,4的全排列,每個數都會在第1個位置出現,那我們先固定第1位是1,而后我們要做的就是對后面的3位子序列進行全排列,這時固定子序列的第一位為2。 依此類推,直到子序列只剩1位,返回。畫個簡圖幫助理解。

c++實現

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 //打印數組全部元素
 6 void prt(int arr[],int end){
 7     for(int i=0;i<=end;++i){
 8             printf("%d",arr[i]);
 9     }
10 }
11 
12 void perm(int arr[],int begin,int end){
13         if(begin==end){
14         prt(arr,end);
15         printf("\n");
16         return;
17     }
18     for(int i=begin;i<=end;++i){
19         swap(arr[begin],arr[i]);  //交換兩個元素值
20         perm(arr,begin+1,end);
21         swap(arr[begin],arr[i]);
22     }
23 }

 

非遞歸的實現:這里采用的是字典序的方式生成全排列,1,2,3,4這4個數,組成形如1234,1243等序列,這些序列中1234最小,4321最大,由此我們從1234開始(或者4321也行),尋找第一個比1234大的序列,是1243;再尋找第一個比1243大的序列,是1324........依此類推,求出所有序列。

  具體實現:從右向左開始,找到第一個這樣的數A(n-1)<A(n),從A(n)向右找最后一個比A(n-1)大的數A(m),交換A(n-1)和A(m),將A(n)到末尾所有元素逆序。重復上述步驟直到第一個元素。

c++實現:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 void perm(int arr[],int len){
 6     if(len<2) return;
 7     int i,j,temp;
 8     do{
 9                 //輸出當前序列
10         prt(arr,len-1);
11         printf("\n");
12         i=j=len-1;
13                 //向前查找第一個變小的元素
14         while(i>0&&arr[i]<arr[i-1]) --i;
15         temp=i;
16         if(i==0) break;
17                 //先后查找第一個比arr[i-1]大的元素
18         while(temp+1<len&&arr[temp+1]>arr[i-1]) ++temp;
19         swap(arr[i-1],arr[temp]);  //交換兩個值
20         reverse(arr+i,arr+len);  //逆序
21     }while(true);
22 }

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM