目录
2.DFS(Depth-First-Search)---深度优先搜索 全排列方式
·扩展: BFS(Breadth First Search)---宽度优先搜索
含有相应的**例题**来说明下两种常见的全排列方式
1.一般的全排列方式
题目详情
编写递归函数,显示n个数字的全排列。
编写主函数,输入非负整数n,调用函数显示全排列。
输入格式:
一个非负整数n.
输出格式:
全排列,每行一个,用一个空格隔开,末尾无空格。
输入样例:
4
输出样例:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 3 2
1 4 2 3
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 3 1
2 4 1 3
3 2 1 4
3 2 4 1
3 1 2 4
3 1 4 2
3 4 1 2
3 4 2 1
4 2 3 1
4 2 1 3
4 3 2 1
4 3 1 2
4 1 3 2
4 1 2 3
- 下面代码
#include <iostream>
using namespace std;
void swap(int &a, int &b)
{
int temp=a;
a=b;
b=temp;
}
void REpermutation(int *p, int pos,int n) //pos 为 position
{
if(pos==n-1){
cout<<*p;
for(int i=1;i<n;i++)
cout<<' '<<*(p+i);
putchar(10);
return ;
}
for(int i=pos;i<n;i++)
{
swap( *(p+pos),*(p+i));
REpermutation(p,pos+1,n);
swap( *(p+pos),*(p+i));
}
}
int main()
{
int n;
cin>>n;
int *p = new int [n];
for(int i=0;i<n;i++)
*(p+i)=i+1;
REpermutation(p,0,n);
delete []p;
return 0;
}
2.DFS(Depth-First-Search)---深度优先搜索 全排列方式
深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。深度优先搜索也叫递归遍历,二叉树有三种深度优先遍历:先序遍历、中序遍历和后序遍历。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。
链接:https://leetcode-cn.com/tag/depth-first-search/
来源:力扣(LeetCode)
题目详情
请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。
输入格式:
输入给出正整数n(<10)。
输出格式:
输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,⋯,an排在序列b1,b2,...,bn之前, 如果存在k使得a1=b1,...,ak=bk 并且a(k+1)<b(k+1)。
输入样例:
3
输出样例:
123
132
213
231
312
321
- 下面代码
#include <iostream>
#include <cstring>
using namespace std;
void DFS(char *p, int *pt, int n,int m) //DFS全排列
{
if(n==m){
//cout<<p<<endl;
cout<<*p;
for(int i=1;i<m;i++)
cout<<' '<<*(p+i);
putchar(10);
return ;
}
for(int i=1;i<=m;i++)
{
if( *(pt+i)!=0 ) continue;
*(p+n)=i+48; //如果i代表的数字没有被使用,则代表可以使用该数字
*(pt+i)=1; //i代表的数字被使用后需置1
DFS(p,pt,n+1,m);
*(pt+i)=0;
}
}
int main()
{
int n,m;
cin>>n;
char *p=new char [n+1]; //p所指向的数组负责保存数字字符和输出
*(p+n)='\0';
int *pt=new int [n+1]; //pt指向的数组用来记录对应的数字(用下标数来表示) 是否被占用(1为占用,0为未使用)
memset(pt,0,4*(n+1)); //作用是将pt所指位置后面的4*n个字节都用0替换
m=n;
DFS(p,pt,0,m);
delete []p;
delete []pt;
return 0;
}
下一个排列(调用STL中的库函数next_permutation() )
枚举所有排列的另一个方法是从字典序最小的排列开始,不停调用“求下一个排列”的过程。如何求下一个排列呢?枚举排列的常见方法有两种:一是递归枚举(自己设计),二是用 STL 中的 next_permutation。
C++的 STL 中提供了一个库函数 next_permutation,看看下面的代码片段,就应该会明白如何使用它了。
#include <cstdio>
#include <algorithm> //包含 next_permutation
using namespace std;
int main()
{
int n, p[10];
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &p[i]);
sort(p, p+n); //排序,得到 p 的最小排列
do {
for(int i = 0; i < n; i++) printf("%d ",p[i]); //输出排列p
printf("\n");
} while(next_permutation(p, p+n)); //求下一个排列
return 0;
}