问题描述

设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。
设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。集合R中元素的全排列记为perm(R)。(ri)perm(Ri)表示在全排列perm(Ri)的每一个排列前加上前缀得到的排列。R的全排列可归纳定义如下:
当n=1时,perm(R)=(r),其中r是集合R中唯一的元素;
当n>1时,perm(R)由(r1)perm(R1),(r2)perm(R2),…,(rn)perm(Rn)构成。
image.png

  1. Template <class Type>
  2. void perm(Type list[], int k, int m ) //产生[list[k:m]的所有排列
  3. {
  4. if(k==m)
  5. { //只剩下一个元素
  6. for (int i=0;i<=m;i++)
  7. cout<<list[i];
  8. cout<<endl;
  9. }
  10. else //还有多个元素待排列,递归产生排列
  11. for (int i=k; i<=m; i++)
  12. {
  13. swap(list[k],list[i]);
  14. perm(list,k+1;m);
  15. swap(list[k],list[i]);
  16. }
  17. }
  1. #include<iostream>
  2. using namespace std;
  3. template<class Type>
  4. void Print(Type a[]) {
  5. for (int i = 0; i < 5; i++)
  6. cout << a[i] << " ";
  7. cout << endl;
  8. }
  9. void perim(int a[], int L, int R) {
  10. if (L == R) {
  11. Print(a);
  12. return;
  13. }
  14. for (int i = L; i < R; i++) {
  15. swap(a[i], a[L]);
  16. cout << a[1] << endl;
  17. perim(a, L + 1, R);
  18. swap(a[i],a[L]);
  19. cout << a[0] << endl;
  20. }
  21. }
  22. int main()
  23. {
  24. int a[5]={};
  25. for (int i = 0; i < 5; i++)
  26. a[i] = rand() % 10 + 1;
  27. Print(a);
  28. perim(a, 2, 5);
  29. }

运行结果
屏幕截图 2022-03-18 225216.png

思考:

对于数组list=(a,b,c,d)
分别写出perm(list,0,3),perm(list,1,3),perm(list,2,3),perm(list,3,3)的结果。
perm(list,0,3) abcd的全排列 24种
perm(list,1,3) 6种
perm(list,2,3) 2种结果
perm(list,3,3) 1种
要了解perm(list,1,3)的过程,有3次调用perm(list,2,3)过程,每次调用perm(list,2,3)有2种结果,所以一共有6种结果。