組合與全排列非遞迴演算法

2021-06-20 02:06:41 字數 3044 閱讀 6706

組合與全排列非遞迴演算法

浩天

二進位制組合演算法:

思路是開乙個陣列,其下標表示1到m個數,陣列元素的值為1表示其下標

代表的數被選中,為0則沒選中。 

首先初始化,將陣列前n個元素置1,表示第乙個組合為前n個數。 

然後從左到右掃瞄陣列元素值的「10」組合,找到第乙個「10」組合後將其變為 

「01」組合,同時將其左邊的所有「1」全部移動到陣列的最左端。 

當第乙個「1」移動到陣列的m-n的位置,即n個「1」全部移動到最右端時,就得 

到了最後乙個組合。 

例如求5中選3的組合: 

1 1 

1 0 

0 //1,2,3 

1 1 

0 1 

0 //1,2,4 

1 0 

1 1 

0 //1,3,4 

0 1 

1 1 

0 //2,3,4 

1 1 

0 0 

1 //1,2,5 

1 0 

1 0 

1 //1,3,5 

0 1 

1 0 

1 //2,3,5 

1 0 

0 1 

1 //1,4,5 

0 1 

0 1 

1 //2,4,5 

0 0 

1 1 

1 //3,4,5 

全排列n進製演算法:

從1到n,輸出全排列,共n!條。

分析:用n進製的方法。設乙個n個單元的陣列a用來存放待全排列的陣列的下標,對第乙個單元做加一操作,滿n進一。每加一次一就判斷一下各位陣列單元有無重複,有則再轉回去做加一操作,沒有(且陣列a中沒有值為n的元素)則說明得到了乙個排列方案。

例如:求1-3的全排列,共3!條

設陣列初始狀態為0 0 0,以下為計算全排列的步驟:

0 0 0 +1

1 0 0 +1

2 0 0 +1

3 0 0 滿3進1 ->

0 1 0 +1

1 1 0 +1

2 1 0 +1

3 1 0 滿3進1 ->

0 2 0 +1

1 2 0 +1

2 2 0 +1

3 2 0 滿3進1 ->

0 3 0 滿3進1 ->

0 0 1 +1

1 0 1 +1

2 0 1 +1

3 0 1 滿3進1 ->

0 1 1 +1

1 1 1 +1

2 1 1 +1

3 1 1 滿3進1 ->

0 2 1 +1

1 2 1 +1

2 2 1 +1

3 2 1 滿3進1 ->

0 3 1 滿3進1 ->

0 0 2 +1

1 0 2 +1

2 0 2 +1

3 0 2 滿3進1 ->

0 1 2 +1

1 1 2 +1

2 1 2 +1

3 1 2 滿3進1 ->

0 2 2 +1

1 2 2 +1

2 2 2 +1

3 2 2 滿3進1 ->

0 3 2 滿3進1 ->

0 0 3 滿3進1 -> 

(最高位為進製n(這裡是3)是迴圈退出條件)

0 0 0

其中用紅色背景色

表明的6個下標序列是合格的,每乙個下標序列對應一種排列。

實現**:

#include

#include

#define n 5

void combine(int *a, int n);

void arrange(int *a, int n);

bool checksame(int *a,int n);

void main(void)

;int ntype;

while (1)

printf("n");}}

void combine(int *a, int n)

//

int *b = new int[n];

memset(b, 0, n*sizeof(int));

for(i = 0; i < m; i++)

int ncount = 0; bool bfound = false;

do }

ncount++;

printf("n");

bfound = false;

for (i = 0; i < n - 1; i++)

else if ((b[i] == 1) && (b[i+1] == 0) && (b[0] == 0))

}for(j = 0; j < i; j++)

else

}break;}}

} while (bfound == true);

printf("total number is : %dn", ncount);

delete b; 

b = null;

}void arrange(int *a, int n)

int count = 0; 

//存放總的排列數目

while(b[n-1] != n) 

//最高位為進製n是迴圈退出條件

count++;

printf("n");

}//完成進製

bool increase = false;

for(int i=0;i

}//如果沒有進過位,則使最低位加1

if(!increase)

}printf("total number is : %dn", count);

delete b; 

b = null;

}bool checksame(int *a,int n)

for(int j=i+1;j

if(a[i] == a[j]) }}

return false;

}根據網上演算法改編。

全排列演算法的遞迴與非遞迴實現

對於給定的集合a,其中的n個元素互不相同,如何輸出這n個元素的所有排列 全排列 例如 給定集合 1,2,3 它的全排列子集為 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 思路 1.保持第乙個數不變,對後面的數進行全排列 2.將第乙個數換成其它數,對後面的數進行全排列 3....

全排列的非遞迴演算法

這個講解的非常通俗易通,所以記錄下來備用。先大體介紹一下演算法思路 比如說有1234四個數字,我們要將這四個數字實現全排列。拋棄初中老師教我們的4 3 2 1的思路,我們來換一種思路。1234 當然是第乙個排列,要得到第二個排列,我們選取剛好比它大的,我們用大腦當然想的到是 1243 但是我們怎樣解...

全排列的遞迴與非遞迴

全排列是乙個十分基礎的概念,是一串有可比權值的元素出現的所有排列形式,例如 張全蛋 張蛋全 全張蛋 全蛋 張 蛋全張 蛋張全 就是張全蛋的全排列,所以我們發現全排列用來取名字是很不錯的,如果對每個漢字在名字中的權值做一 張表,再來一張可能出現的不同字同時出現在名字中的關聯權值表,那麼全排列可以算出一...