递归方式-全排列生成算法
http://blog.csdn.net/xiazdong/article/details/7986015
排列:從n個元素中任取m個元素,并按照一定的順序進行排列,稱為排列;
全排列:當n==m時,稱為全排列;
比如:集合{ 1,2,3}的全排列為:
{ 1 2 3}?
{ 1 3 2 }
{ 2 1 3 }
{ 2 3 1 }
{ 3 2 1 }
{ 3 1 2 }
方法一:
我們可以將這個排列問題畫成圖形表示,即排列枚舉樹,比如下圖為{1,2,3}的排列枚舉樹,此樹和我們這里介紹的算法完全一致;
算法思路:
(1)n個元素的全排列=(n-1個元素的全排列)+(另一個元素作為前綴);
(2)出口:如果只有一個元素的全排列,則說明已經排完,則輸出數組;
(3)不斷將每個元素放作第一個元素,然后將這個元素作為前綴,并將其余元素繼續全排列,等到出口,出口出去后還需要還原數組;
[java]?view plain?copy
public?class?Test?{??
????public?static?int?arr[]?=?new?int[]{1,2,3};??
????public?static?void?main(String[]?args)?{??
????????perm(arr,0,arr.length-1);??
????}??
????private?static?void?swap(int?i1,?int?i2)?{??
????????int?temp?=?arr[i2];??
????????arr[i2]?=?arr[i1];??
????????arr[i1]?=?temp;??
????}??
??
????/**?
?????*?對arr數組中的begin~end進行全排列?
?????*??
?????*?比如:?
?????*??arr?=?{1,2,3}?
?????*??第一步:執行?perm({1,2,3},0,2),begin=0,end=2;?
?????*??????j=0,因此執行perm({1,2,3},1,2),begin=1,end=2;?
?????*??????????j=1,swap(arr,0,0)-->arr={1,2,3},??perm({1,2,3},2,2),begin=2,end=2;?
?????*??????????????因為begin==end,因此輸出數組{1,2,3}?
?????*??????????swap(arr,1,1)?-->?arr={1,2,3};?
?????*??????????j=2,swap(arr,1,2)-->arr={1,3,2},??perm({1,3,2},2,2),begin=2,end=2;?
?????*??????????????因為begin==end,因此輸出數組{1,3,2}?
?????*??????????swap(arr,2,1)?-->?arr={1,2,3};?
?????*??????j=1,swap(arr,0,1)?-->?arr={2,1,3},?????perm({2,1,3},1,2),begin=1,end=2;?
?????*??????????j=1,swap(arr,1,1)-->arr={2,1,3}???perm({2,1,3},2,2),begin=2,end=2;?
?????*??????????????因為begin==end,因此輸出數組{2,1,3}?
?????*??????????swap(arr,1,1)-->?arr={2,1,3};?
?????*??????????j=2,swap(arr,1,2)后?arr={2,3,1},并執行perm({2,3,1},2,2),begin=2,end=2;?
?????*??????????????因為begin==end,因此輸出數組{2,3,1}?
?????*??????????swap(arr,2,1)?-->?arr={2,1,3};?
?????*??????swap(arr,1,0)??-->?arr={1,2,3}?
?????*??????j=2,swap(arr,2,0)?-->?arr={3,2,1},執行perm({3,2,1},1,2),begin=1,end=2;?
?????*??????????j=1,swap(arr,1,1)?-->?arr={3,2,1}?,?perm({3,2,1},2,2),begin=2,end=2;?
?????*??????????????因為begin==end,因此輸出數組{3,2,1}?
?????*??????????swap(arr,1,1)?-->?arr={3,2,1};?
?????*??????????j=2,swap(arr,2,1)?-->?arr={3,1,2},并執行perm({2,3,1},2,2),begin=2,end=2;?
?????*??????????????因為begin==end,因此輸出數組{3,1,2}?
?????*??????????swap(arr,2,1)?-->?arr={3,2,1};?
?????*??????swap(arr,0,2)?-->?arr={1,2,3}?
?????*???????
?????*?@param?arr?
?????*?@param?begin??
?????*?@param?end?
?????*/??
????public?static?void?perm(int?arr[],?int?begin,int?end)?{??
????????if(end==begin){?????????//一到遞歸的出口就輸出數組,此數組為全排列??
????????????for(int?i=0;i<=end;i++){??
????????????????System.out.print(arr[i]+"?");??
????????????}??
????????????System.out.println();??
????????????return;??
????????}??
????????else{??
????????????for(int?j=begin;j<=end;j++){???
????????????????swap(begin,j);??????//for循環將begin~end中的每個數放到begin位置中去??
????????????????perm(arr,begin+1,end);??//假設begin位置確定,那么對begin+1~end中的數繼續遞歸??
????????????????swap(begin,j);??????//換過去后再還原??
????????????}??
????????}??
????}??
}??
方法二:
[java]?view plain?copy
public?class?Test2?{??
????public?static?int?arr[]?=?new?int[]{0,0,0};??
????public?static?void?main(String[]?args)?{??
????????perm(3);??
????}??
????/**?
?????*?數組變化過程:?
?????*?3?0?0?
?????*?3?2?0?
?????*?3?2?1?
?????*?3?2?0?
?????*?3?0?0?
?????*?3?0?2?
?????*?3?1?2?
?????*?3?0?2?
?????*?3?0?0?
?????*?0?0?0?
?????*?0?3?0?
?????*?2?3?0?
?????*?2?3?1?
?????*?2?3?0?
?????*?0?3?0?
?????*?0?3?2?
?????*?1?3?2?
?????*?0?3?2?
?????*?0?3?0?
?????*?0?0?0?
?????*?0?0?3?
?????*?2?0?3?
?????*?2?1?3?
?????*?2?0?3?
?????*?0?0?3?
?????*?0?2?3?
?????*?1?2?3?
?????*?0?2?3?
?????*?0?0?3?
?????*?0?0?0?
?????*?@param?m?
?????*/??
????private?static?void?perm(int?m)?{??
????????if(m==0){??
????????????for(int?i=0;i<arr.length;i++){??
????????????????System.out.print(arr[i]+"?");??
????????????}??
????????????System.out.println();??
????????????return;??
????????}??
????????else{??
????????????for(int?i=0;i<arr.length;i++){??
????????????????if(arr[i]==0){??
????????????????????arr[i]?=?m;??
????????????????????perm(m-1);??
????????????????????arr[i]?=?0;??
????????????????}??
????????????}??
????????}??
????}??
}??
參考文獻:
1.全排列的遞歸算法實現 ??李盤榮
2.全排列遞歸算法在算法教學中的重要性 ?吳素萍
3.排序算法與全排列生成算法研究?陳衛東, 鮑蘇蘇
論文下載地址:http://yunpan.cn/lk/05qsom5mle
Reference:
遞歸解決全排列生成算法_xiazdong-CSDN博客_全排列遞歸
總結
以上是生活随笔為你收集整理的递归方式-全排列生成算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数码时代被外企卷死的国产相机 如今正悄悄
- 下一篇: 线性递归和尾递归