當前位置:首頁 » 編程語言 » 遞歸演算法全排列c語言
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

遞歸演算法全排列c語言

發布時間: 2022-01-15 15:09:24

A. c語言遞歸演算法

int f(int n)
{
if (n>0)
{
return n*f(n/2);
}
else if(n==0)
{
return n+1;
}
}

B. 全排列遞歸演算法

希望我的答復可以幫助你加深理解:

第一,perm函數中的條件for(int i=k;i<=m;i++)應更正為 for(int i=k;i<m;i++)

第二,你可以在核心步驟的前後列印有關變數的值,分析查看每一步的具體執行情況,這是編程調試的重要能力,要加強。
第三,以下是我提供的附件程序及運行結果(以1,2,3這個數組的全排列),可輔助分析:

1. 程序源碼=================================================
#include <stdio.h>
#include <stdlib.h>
int N,P=0;

void swap(int a[],int i,int j)
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}

void perm(int a[],int k,int m,int pk,int pm)
{
int i;
/*k為中間變數,m初始化為參與排列元素的起始坐標和終止坐標
pk,pm分別表示參與排列元素的起始坐標和終止坐標,整個遞歸過程保持不變*/
if(k==m)
{
printf("----->perm %d :\n",P/N+1);/*列印提示*/
for(i=pk;i<pm;i++)
{
printf("%d ",a[i]);
P=P+1;
}
printf("\n\n");
}
else
{
for(i=k;i<m;i++)
{
printf("a %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
swap(a,k,i);
printf("b %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
perm(a,k+1,m,pk,pm);
printf("c %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
swap(a,k,i);
printf("d %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
}
}
}

int main()
{
/*調節以下N值及對應數組內容,可列印對應數組對應的全排列*/
N=3;
int t[]={1,2,3};
/*調節以上N值及對應數組內容,可列印對應數組對應的全排列*/

perm(t,0,N,0,N);
printf("----->Over!\n");/*列印提示*/
system("pause");
return 0;
}

2.列印結果 ============================================================

a 0,0,1,2,3
b 0,0,1,2,3
a 1,1,1,2,3
b 1,1,1,2,3
a 2,2,1,2,3
b 2,2,1,2,3
----->perm 1 :
1 2 3

c 2,2,1,2,3
d 2,2,1,2,3
c 1,1,1,2,3
d 1,1,1,2,3
a 2,1,1,2,3
b 2,1,1,3,2
a 2,2,1,3,2
b 2,2,1,3,2
----->perm 2 :
1 3 2

c 2,2,1,3,2
d 2,2,1,3,2
c 2,1,1,3,2
d 2,1,1,2,3
c 0,0,1,2,3
d 0,0,1,2,3
a 1,0,1,2,3
b 1,0,2,1,3
a 1,1,2,1,3
b 1,1,2,1,3
a 2,2,2,1,3
b 2,2,2,1,3
----->perm 3 :
2 1 3

c 2,2,2,1,3
d 2,2,2,1,3
c 1,1,2,1,3
d 1,1,2,1,3
a 2,1,2,1,3
b 2,1,2,3,1
a 2,2,2,3,1
b 2,2,2,3,1
----->perm 4 :
2 3 1

c 2,2,2,3,1
d 2,2,2,3,1
c 2,1,2,3,1
d 2,1,2,1,3
c 1,0,2,1,3
d 1,0,1,2,3
a 2,0,1,2,3
b 2,0,3,2,1
a 1,1,3,2,1
b 1,1,3,2,1
a 2,2,3,2,1
b 2,2,3,2,1
----->perm 5 :
3 2 1

c 2,2,3,2,1
d 2,2,3,2,1
c 1,1,3,2,1
d 1,1,3,2,1
a 2,1,3,2,1
b 2,1,3,1,2
a 2,2,3,1,2
b 2,2,3,1,2
----->perm 6 :
3 1 2

c 2,2,3,1,2
d 2,2,3,1,2
c 2,1,3,1,2
d 2,1,3,2,1
c 2,0,3,2,1
d 2,0,1,2,3
----->Over!
請按任意鍵繼續. . .

C. 遞歸全排列 c語言 看不懂

Perm(list,k,m)遞歸的產生所有後綴是list(0:k-1),且後綴是
list(k:m)的全排列的所有排列。

D. acm題 用c語言設計一個遞歸演算法求全排列

//1.cpp生成1~n的全排列
#include<stdio.h>
voidArrange(intcur,intn,int*arr)
{
if(cur==n+1)
{
for(inti=1;i<cur;i++)
printf("%d",arr[i]);
printf(" ");
return;
}
for(inti=1;i<=n;i++)
{
intok=1;
for(intj=1;j<cur;j++)
if(arr[j]==i)
ok=0;
if(ok)
{
arr[cur]=i;
Arrange(cur+1,n,arr);
}
}
}
intmain()
{
intarr[15];
//生成1~n的排列
intn;
printf("Inputn:");
scanf("%d",&n);
Arrange(1,n,arr);
return0;
}
//2.cpp生成集合中元素的全排列
#include<stdio.h>
intSet[15];
intArr[15];
intn;
voidArrange(intcur)
{
if(cur==n+1)
{
for(inti=1;i<cur;i++)
printf("%d",Arr[i]);
printf(" ");
return;
}
for(inti=1;i<=n;i++)
{
intok=1;
for(intj=1;j<cur;j++)
if(Arr[j]==Set[i])
ok=0;
if(ok)
{
Arr[cur]=Set[i];
Arrange(cur+1);
}
}
}
intmain()
{
printf("Inputnumberofelem:");
scanf("%d",&n);//元素個數
printf("Inputelems:");
for(inti=1;i<=n;i++)//元素
scanf("%d",&Set[i]);
Arrange(1);
return0;
}

E. c語言遞歸演算法

用遞歸法計算n!
用遞歸法計算n!可用下述公式表示:
n!=1 (n=0,1)
n×(n-1)! (n>1)
按公式可編程如下:
long ff(int n)
{
long f;
if(n<0) printf("n<0,input error");
else if(n==0||n==1) f=1;
else f=ff(n-1)*n;
return(f);
}
main()
{
int n;
long y;
printf("\ninput a inteager number:\n");
scanf("%d",&n);
y=ff(n);
printf("%d!=%ld",n,y);
}

程序中給出的函數ff是一個遞歸函數。主函數調用ff 後即進入函數ff執行,如果n<0,n==0或n=1時都將結束函數的執行,否則就遞歸調用ff函數自身。由於每次遞歸調用的實參為n-1,即把n-1的值賦予形參n,最後當n-1的值為1時再作遞歸調用,形參n的值也為1,將使遞歸終止。然後可逐層退回。
下面我們再舉例說明該過程。設執行本程序時輸入為5,即求5!。在主函數中的調用語句即為y=ff(5),進入ff函數後,由於n=5,不等於0或1,故應執行f=ff(n-1)*n,即f=ff(5-1)*5。該語句對ff作遞歸調用即ff(4)。
進行四次遞歸調用後,ff函數形參取得的值變為1,故不再繼續遞歸調用而開始逐層返回主調函數。ff(1)的函數返回值為1,ff(2)的返回值為1*2=2,ff(3)的返回值為2*3=6,ff(4)的返回值為6*4=24,最後返回值ff(5)為24*5=120。

F. 關於全排列遞歸演算法

這個演算法,是把每一個數與末尾的數逐一交換,
k>m 說明已交換完畢,就輸出了,這是遞歸的結束條件。
要學到一定的基本功才能明白。
---------------------------------------------------------------------------
我這個程序,我也編過,放在西祠C++BUILDER論壇里。
你先要掌握,排列的方法才能看懂這個程序。
在這知道里,也答過兩次。
為了增加可理解性,我略改了一下方法,我的方法
與你的方法遞歸方向不同。
http://www.xici.net/d190786398.htm
此演算法為遞歸法顯示排列數,沒發現比這更簡單、明了的遞
歸演算法。此演算法只要練智商的作用,沒有其它實用價值,階
乘級的佔用時間、空間,數一大,堆棧很快暴了。
演算法的要點:
1.列N個數的排列,可化為N個的N-1階排列:
最末一個數是 D[n-1],把這個位置的N個數的可能性列出,
就是每一個數 與末尾逐一交換位置,就是N種情況,每一種
情況再求N-1的全排列,就是遞歸調用了;
交換位置後,就調用自已,但必須恢復剛才的交換,以便下一次
交換;
2.當階數遞歸到1時,就直接輸出這N個數;

G. C語言遞歸問題(全排列)

可以輸出所有的排列,i和n表示排列的起始點和終止點比如說要排列"abcd"起點就是0,終點是3,perm(「abcd」,0,3)就可以了。

H. c語言,求12345的全排列,遞歸方法,在網上看了很多沒有理解,求代碼,然後一步步解析。感覺對遞歸

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int q[1000][2];

void BFS()
{
int front=-1,rear=0;
int i,s,d,ts,td;
q[0][0]=1;
q[0][1]=2;

while(front!=rear)
{
front++;
d=q[front][0];
s=q[front][1];
for(i=1;i<=5;i++)
{
if((1<<i)&s)continue;
ts=s+(1<<i);
td=d*10+i;

printf("%d\n",td);
rear++;
q[rear][0]=td;
q[rear][1]=ts;
}
}
}
int main()
{
BFS();
return 0;
}

I. C語言 求此全排列遞歸演算法解析

used數組是全局變數有隱含初值0;
關於全排列的演算法你可以理解為深搜加回溯。
#include<stdio.h>
#define
MAX
10
int
used[MAX];
//用來標記數字是否已經在前面使用過
int
result[MAX];
//存放結果
int
N;
void
print()
//輸出結果
{
int
i;
for(i=0;i<N;i++)
printf("%d
",result[i]);
printf("\n");
}
void
proc(int
step)
//step用來記錄已經擺好了幾個數
{
int
i;
if(step==N)
//如果已經擺好了N個數,那麼結果就產生了,就輸出結果
print();
else
{
for(i=0;i<N;i++)
//枚舉1-N,找到沒有使用過的最小的數
{
if(!used[i])
//沒有使用過
{
used[i]=1;
//標記i已經使用
result[step]=i+1;
//記錄結果
proc(step+1);
//遞歸求解
used[i]=0;
//這里就是所謂的回溯,也許比較難理解,你可以人工走一遍加深理解。其實回溯的主要想法是"還原現場".當執行到這一步時,i+1
這個數放在第step個位置的情況已經解決了,我們就要拿出i+1這個數,把它標記為未使用。
}
}
}
}
int
main()
{
scanf("%d",&N);
proc(0);
return
0;
}