這個說起來太麻煩了, 我找了一個, 你看看行不, 不可以的話, 私聊吧.
我們提供的服務有:成都網(wǎng)站制作、成都做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、黃平ssl等。為上1000+企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的黃平網(wǎng)站制作公司
全排列用的是 置換算法,
算法這東西重在理解。具體代碼并不那么重要。
全排列是將一組數(shù)按一定順序進行排列,如果這組數(shù)有n個,那么全排列數(shù)為n!個?,F(xiàn)以{1, 2, 3, 4, 5}為
例說明如何編寫全排列的遞歸算法。
1、首先看最后兩個數(shù)4, 5。 它們的全排列為4 5和5 4, 即以4開頭的5的全排列和以5開頭的4的全排列。
由于一個數(shù)的全排列就是其本身,從而得到以上結(jié)果。
2、再看后三個數(shù)3, 4, 5。它們的全排列為3 4 5、3 5 4、 4 3 5、 4 5 3、 5 3 4、 5 4 3 六組數(shù)。
即以3開頭的和4,5的全排列的組合、以4開頭的和3,5的全排列的組合和以5開頭的和3,4的全排列的組合.
從而可以推斷,設一組數(shù)p = {r1, r2, r3, ... ,rn}, 全排列為perm(p),pn = p - {rn}。
因此perm(p) = r1perm(p1), r2perm(p2), r3perm(p3), ... , rnperm(pn)。當n = 1時perm(p} = r1。
為了更容易理解,將整組數(shù)中的所有的數(shù)分別與第一個數(shù)交換,這樣就總是在處理后n-1個數(shù)的全排列。
算法如下:
#include stdio.h
int n = 0;
void swap(int *a, int *b)
{
int m;
m = *a;
*a = *b;
*b = m;
}
void perm(int list[], int k, int m)
{
int i;
if(k m)
{
for(i = 0; i = m; i++)
printf("%d ", list[i]);
printf("\n");
n++;
}
else
{
for(i = k; i = m; i++)
{
swap(list[k], list[i]);
perm(list, k + 1, m);
swap(list[k], list[i]);
}
}
}
int main()
{
int list[] = {1, 2, 3, 4, 5};
perm(list, 0, 4);
printf("total:%d\n", n);
return 0;
}
鏈接:
#include stdio.h
char c,s[10];
int n;
void pern(int k)
{int i;
if(k==n)
printf("%s\n",s+1);
else
for(i=k;i=n;i++)
{c=s[k];s[k]=s[i];s[i]=c;
pern(k+1);
c=s[k];s[k]=s[i];s[i]=c;
}
}
int main()
{ int i;
scanf("%d",n);
for(i=1;i=n;i++)
s[i]='0'+i;
pern(1);
return 0;
}
這其實是一個遞歸
遞歸函數(shù)
意思是這樣的
比如有n個數(shù)
1
2.。。。n
把1
從第一個開始
往后
與每個數(shù)開始交換
然后
第一個數(shù)就算定了
后面的
第2個到第n個當成一個整體
再進行這個函數(shù)遞歸
也就是說
第二個到第n個進行全排列
這樣下去
當全排列到最后一組數(shù)
即第n個數(shù)一個的時候
遞歸退出條件就出來了
就可以輸出全排列的值了
當然
最后別忘記把交換的數(shù)還原
再進行下一次交換
遞歸哦
所以最后一局的交換也是很重要的
聽完我的解釋
再好好琢磨一下
相信你一定會明白的
要是還是不懂可以繼續(xù)追問我
像for(int i=0;in;i++)c語言里變量定義不能這樣吧。要把int定義前面的吧。把所有變量定義改了,用C-Free程序運行是正常的。
#include stdio.h
#define N 10
swap(int *p,int *q)
{
int temp;
temp=*p;
*p=*q;
*q=temp;
}
sort(int a[],int k,int n)
{ int temp1,temp2,j,i;
if(k==n)
{
for( i=0;i=n;i++)
printf("%d",a[i]);
printf("\n");
}
else{
for(j=k;j=n;j++)
{
swap(a[k],a[j]);
sort(a,k+1,n);
swap(a[k],a[j]);
}
}
}
main()
{
int a[N];
int n,i;
scanf("%d",n);
for(i=0;in;i++)
scanf("%d",a[i]);
sort(a,0,n-1);
}
首先,我下面的敘述是建立在樓主明白什么是遞歸調(diào)用的基礎上的。對遞歸毫無了解的話,請先看看百度百科。
然后,進入正題。
第一個return:就是返回這個函數(shù)的調(diào)用者,這個函數(shù)執(zhí)行完畢。這是一個if判斷,當帶排列的數(shù)列長度為1時,只有一種可能,輸出,則排列結(jié)束,返回。長度不只1的時候,執(zhí)行以下for。
未完待續(xù)
接著講這個
for(i=0;in;i++){----------這個循環(huán)到底怎么個看法和順序?
anagram(d,n-1); 怎么輸出的??(這塊都不明白)
temp=d[0];
for(j=1;j=n-1;j++){
d[j-1]=d[j];
}
d[n-1]=temp;
}
先講這個算法的思想,比如對abc進行全排列,那么可以看做:ab的全排列+c和ac的全排列+b和bc的全排列+a三個的組合。然后再細化,ab的全排列可以看出a的全排列+b,和b的全排列+a兩個的組合。當只有一個時,就是調(diào)用if=1的那個情況,直接print。不是1的時候,就是遞歸調(diào)用,進行不斷地分解。
這是算法思想,未完待續(xù)
兩個for循環(huán),里面的for執(zhí)行一邊后就是把數(shù)組的元素挨個往前挪一位,第一位到最后位,然后對前n-1位進行全排列,遞歸進行。從上面的算法思想中我們可以看出這樣的目的和意義,就是一個類似對上面abc的分解過程,一次a到最后排bc,一次b到最后排ac,一次c到最后排ab。
就先說這么多吧。純手打,望采納!有問題可以補充,或者百度hi我。
我?guī)湍愀牧艘幌麓a,加了幾行printf,希望可以解決你的那幾個問題:
#includestdio.h
#define NUM 3
void anagram(int[],int);
void print(int[]);
void main()
{
int d[NUM];
int i;
for(i=0;iNUM;i++)
d[i]=i + 1;
printf("初始化后的數(shù)組順序是:");
print(d);
anagram(d,NUM);
}
void anagram(int d[],int n)
{
int i,j,temp;
int p;
if(n==1){
print(d); //打印函數(shù)
return;//-------------return返回哪?
} // 和下面的for怎么聯(lián)系起來?
for(i=0;in;i++){//----------這個循環(huán)到底怎么個看法和順序?
printf("\ni = %d,n = %d, 準備調(diào)用aragram(d,%d)\n",i,n,n-1);
printf("這時候的數(shù)組順序是:");
print(d);
anagram(d,n-1); // 怎么輸出的??(這塊都不明白)
temp=d[0];
for(j=1;j=n-1;j++){
d[j-1]=d[j];
}
d[n-1]=temp;
}
}
void print(int d[]){
int i;
for(i=0;iNUM;i++){
printf("%d",d[i]);
}
printf("\n");
}
PS:
改動:1、print函數(shù)原來是逆序輸出,改成正序輸出,有利于理解;2、數(shù)組原來初始化為321,改為123,有利于理解。就改了這兩個地方,加了一些printf。
你可以運行一下。
輸出結(jié)果:
初始化后的數(shù)組順序是:123
i = 0,n = 3, 準備調(diào)用aragram(d,2)
這時候的數(shù)組順序是:123
i = 0,n = 2, 準備調(diào)用aragram(d,1)
這時候的數(shù)組順序是:123
123
i = 1,n = 2, 準備調(diào)用aragram(d,1)
這時候的數(shù)組順序是:213
213
i = 1,n = 3, 準備調(diào)用aragram(d,2)
這時候的數(shù)組順序是:231
i = 0,n = 2, 準備調(diào)用aragram(d,1)
這時候的數(shù)組順序是:231
231
i = 1,n = 2, 準備調(diào)用aragram(d,1)
這時候的數(shù)組順序是:321
321
i = 2,n = 3, 準備調(diào)用aragram(d,2)
這時候的數(shù)組順序是:312
i = 0,n = 2, 準備調(diào)用aragram(d,1)
這時候的數(shù)組順序是:312
312
i = 1,n = 2, 準備調(diào)用aragram(d,1)
這時候的數(shù)組順序是:132
132
請按任意鍵繼續(xù). . .
void chang(char str[],int m) /*定義循環(huán)左移函數(shù)(我沒有用左移函數(shù))*/
{
int i,j;
char temp=str[0];
for (i=0;im;i++) str[i]=str[i+1];
str[i]=temp;
}
void pai(char str[],int m,int n) /*定義全排列函數(shù)*/
{
int k;
void chang(char str[],int m);
if (mn) /* 定 義 遞 歸 調(diào) 用 出 口 */
{
for (k=0;k=m;k++)
{
pai(str,m+1,n); /*遞歸調(diào)用*/
chang(str,m); /*調(diào)用左移函數(shù)*/
}
}
else printf("%s\t",str);
}
#include "stdio.h"
main()
{char str[]="ABCD"; /*全排列字符,可以任意多個(相應的下面排列函數(shù)中參數(shù)"4"改成全排列字符的個數(shù))*/
clrscr();
pai(str,0,4); /*這里參數(shù)0(下標)表示從第一個元素開始,4表示元素個數(shù)(不是下標)*/
getch();
}