日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java 全排列非递归算法_全排列的非递归算法 - osc_ivkc73ze的个人空间 - OSCHINA - 中文开源技术交流社区...

發(fā)布時(shí)間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 全排列非递归算法_全排列的非递归算法 - osc_ivkc73ze的个人空间 - OSCHINA - 中文开源技术交流社区... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.全排列的定義和公式:

從n個(gè)數(shù)中選取m(m<=n)個(gè)數(shù)按照一定的順序進(jìn)行排成一個(gè)列,叫作從n個(gè)元素中取m個(gè)元素的一個(gè)排列。由排列的定義,顯然不同的順序是一個(gè)不同的排列。從n個(gè)元素中取m個(gè)元素的所有排列的個(gè)數(shù),稱為排列數(shù)。從n個(gè)元素取出n個(gè)元素的一個(gè)排列,稱為一個(gè)全排列。全排列的排列數(shù)公式為n!,通過(guò)乘法原理可以得到。

2.時(shí)間復(fù)雜度:

n個(gè)數(shù)(字符、對(duì)象)的全排列一共有n!種,所以全排列算法至少時(shí)間O(n!)的。如果要對(duì)全排列進(jìn)行輸出,那么輸出的時(shí)間要O(n?n!),因?yàn)槊恳粋€(gè)排列都有n個(gè)數(shù)據(jù)。所以實(shí)際上,全排列算法對(duì)大型的數(shù)據(jù)是無(wú)法處理的,而一般情況下也不會(huì)要求我們?nèi)ケ闅v一個(gè)大型數(shù)據(jù)的全排列。

3.列出全排列的初始思想:

解決一個(gè)算法問(wèn)題,我比較習(xí)慣于從基本的想法做起,我們先回顧一下我們自己是如何寫(xiě)一組數(shù)的全排列的:1,3,5,9(為了方便,下面我都用數(shù)進(jìn)行全排列而不是字符)。

【1,3,5,9】(第一個(gè))

首先保持第一個(gè)不變,對(duì)【3,5,9】進(jìn)行全排列。

同樣地,我們先保持3不變,對(duì)【5,9】進(jìn)行全排列。

保持5不變,對(duì)9對(duì)進(jìn)行全排列,由于9只有一個(gè),它的排列只有一種:9。

故排列為【1,3,5,9】

接下來(lái)5不能以5打頭了,5,9相互交換,得到

【1,3,9,5】

此時(shí)5,9的情況都寫(xiě)完了,不能以3打頭了,得到

1,5,3,9

1,5,9,3

1,9,3,5

1,9,5,3

這樣,我們就得到了1開(kāi)頭的所有排列,這是我們一般的排列數(shù)生成的過(guò)程。再接著是以3、5、9打頭,得到全排列。

我們現(xiàn)在做這樣的一個(gè)假設(shè),假設(shè)給定的一些序列中第一位都不相同,那么就可以認(rèn)定說(shuō)這些序列一定不是同一個(gè)序列,這是一個(gè)很顯然的問(wèn)題。有了上面的這一條結(jié)論,我們就可以同理得到如果在第一位相同,可是第二位不同,那么在這些序列中也一定都不是同一個(gè)序列。

那么,這個(gè)問(wèn)題可以這樣來(lái)看。對(duì)

T=【x1,x2,x3,x4,x5,........xn?1,xn】

我們獲得了在第一個(gè)位置上的所有情況之后(注:是所有的情況),對(duì)每一種情況,抽去序列T中的第一個(gè)位置,那么對(duì)于剩下的序列可以看成是一個(gè)全新的序列

T1=【x2,x3,x4,x5,........xn?1,xn】

序列T1可以認(rèn)為是與之前的序列毫無(wú)關(guān)聯(lián)了。同樣的,我們可以對(duì)這個(gè)T1進(jìn)行與T相同的操作,直到T中只一個(gè)元素為止。這樣我們就獲得了所有的可能性。所以很顯然,這是一個(gè)遞歸算法。

第一位的所有情況:無(wú)非是將x1與后面的所有數(shù)x2,x3,.......xn依次都交換一次

示意圖如下:

4.全排列的非去重遞歸算法

算法思路:全排列可以看做固定前i位,對(duì)第i+1位之后的再進(jìn)行全排列,比如固定第一位,后面跟著n-1位的全排列。那么解決n-1位元素的全排列就能解決n位元素的全排列了,這樣的設(shè)計(jì)很容易就能用遞歸實(shí)現(xiàn)。

【附代碼段:】

1 #include

2 using namespacestd;3 int arr[5]={0,1,2,3,4};4 void swap(int x,int y)//用于交換數(shù)組的兩個(gè)數(shù)

5 {6 int temp=arr[x];7 arr[x]=arr[y];8 arr[y]=temp;9 }10 int resove(int n)//遞歸函數(shù)

11 {12 if(n==5)//當(dāng)嘗試對(duì)不存在的數(shù)組元素進(jìn)行遞歸時(shí),標(biāo)明所有數(shù)已經(jīng)排列完成,輸出。

13 {14 for(int i=0;i<5;i++)15 cout<

20 {//i是從n開(kāi)始 i=n;swap(n,i)相當(dāng)于固定當(dāng)前位置,在進(jìn)行下一位的排列。

21 swap(n,i);22 resove(n+1);23 swap(n,i);24 }25

26 }27 intmain()28 {29 resove(0);30 }

排列模板

1 void permutation1(char* str,int sbegin,int send) //全排列的非去重遞歸算法

2 {3 if( sbegin == send) //當(dāng) sbegin = send時(shí)輸出

4 {5 for(int i = 0;i <= send; i++) //輸出一個(gè)排列

6 cout <

10 {11 for(int i = sbegin; i <= send; i++) //循環(huán)實(shí)現(xiàn)交換和sbegin + 1之后的全排列

12 {13 swap(str[i],str[sbegin]); //把第i個(gè)和第sbegin進(jìn)行交換

14 permutation1(str,sbegin + 1,send);15 swap(str[i],str[sbegin]); //【注1】交換回來(lái)

16 }17 }18 }

【注1】swap(str[i],str[sbegin])//交換回來(lái)

我們來(lái)仔細(xì)推敲一下循環(huán)體里的代碼,當(dāng)我們對(duì)序列進(jìn)行交換之后,就將交換后的序列除去第一個(gè)元素放入到下一次遞歸中去了,遞歸完成了再進(jìn)行下一次循環(huán)。這是某一次循環(huán)程序所做的工作,這里有一個(gè)問(wèn)題,那就是在進(jìn)入到下一次循環(huán)時(shí),序列是被改變了。可是,如果我們要假定第一位的所有可能性的話,那么,就必須是在建立在這些序列的初始狀態(tài)一致的情況下,所以每次交換后,要還原,確保初始狀態(tài)一致。

總結(jié)

以上是生活随笔為你收集整理的java 全排列非递归算法_全排列的非递归算法 - osc_ivkc73ze的个人空间 - OSCHINA - 中文开源技术交流社区...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。