两种常见的全排列形式(C++)---含DFS全排列 和 使用库函数排列

目录

1.一般的全排列方式

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;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重剑DS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值