C++全排列中递归交换法实例详解

 更新时间:2020年02月20日 14:20:50   作者:000紫外线000  
在本篇文章里小编给各位整理的是关于C++全排列中递归交换法实例内容,有兴趣的朋友们可以学习下。

对于求解全排列问题有最暴力的递归枚举法,但是我们希望可以优化时间,因此出现了递归交换法。

例题

洛谷1706

题目描述

输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

输入格式

一个整数n。

输出格式

由1~n组成的所有不重复的数字序列,每行一个序列。

每个数字保留 5个场宽。

输入样例

3

输出样例

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

全排列问题——递归交换法

其实跟暴力枚举思路差不多,每次递归枚举第x个数字是几,之后a[x]可以选择不动,也可以选择与后面任意一个数交换位置,就是从后面选一个数放到x的位置上。

简而言之,就是每到一位就从后面选一个尚未被使用过的数字与该位数字交换,这里有些难理解,您可以自己按照程序推一下样例。

这样我们就可以打印所有的全排列了,但这样不是按顺序打印,所以这里需要每次对a[x] ~ a[n]进行排序。

举个例子,如对1、2、3进行全排列。当我们交换1和3后,序列变为3、2、1,如果说这里不排序,直接2、1都保持不动,就输出3、2、1了,可是我们先要的应该是3、1、2,所以要进行排序。

最后,算一下时间复杂度,我们发现需要从1到n一位一位的看,之后每位还要枚举x ~ n,所以总时间复杂度为O(n!)。

代码

# include <cstdio>
# include <cmath>
# include <cstring>
# include <algorithm>

using namespace std;

const int N_MAX = 10;

int n;
int a[N_MAX + 10];

void permutation(int x)
{
 if (x == n) {
  for (int i = 1; i <= n; i++)
   printf("%5d", a[i]);
  printf("\n");
  return;
 }
 for (int i = x; i <= n; i++) {
  sort(a + x, a + n + 1);
  swap(a[x], a[i]);
  permutation(x + 1);
  swap(a[x], a[i]);
 }
}

int main()
{
 scanf("%d", &n);
 for (int i = 1; i <= n; i++)
  a[i] = i;
 permutation(1);
 return 0;
}

以上就是小编给大家整理的全部相关知识点,感谢大家对脚本之家的支持。

相关文章

  • C语言数据结构实例讲解单链表的实现

    C语言数据结构实例讲解单链表的实现

    单链表是后面要学的双链表以及循环链表的基础,要想继续深入了解数据结构以及C++,我们就要奠定好这块基石!接下来就和我一起学习吧
    2022-03-03
  • C语言菜鸟基础教程之自定义函数

    C语言菜鸟基础教程之自定义函数

    自定义函数: 必须直接或间接在main中调用,否则该自定义函数不会被执行。 返回值类型 函数名(参数类型 参数名,参数类型 参数名...)
    2017-10-10
  • 详解如何用c++实现平衡二叉树

    详解如何用c++实现平衡二叉树

    平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),由前苏联的数学家Adelse-Velskil和Landis在1962年提出的高度平衡的二叉树,根据科学家的英文名也称为AVL树。本文介绍了它的原理和如何用C++代码来实现
    2021-06-06
  • C语言汉诺塔的简单了解

    C语言汉诺塔的简单了解

    这篇文章主要给大家介绍了关于C语言汉诺塔的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 浅谈C++中虚函数实现原理揭秘

    浅谈C++中虚函数实现原理揭秘

    下面小编就为大家带来一篇浅谈C++中虚函数实现原理揭秘。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • 示例详解C++语言中的命名空间 (namespace)

    示例详解C++语言中的命名空间 (namespace)

    C++名字空间是一种描述逻辑分组的机制,也就是说,如果有一些声明按照某种准则在逻辑上属于同一个模块,就可以将它们放在同一个名字空间,以表明这个事实,这篇文章主要给大家介绍了关于C++语言中命名空间 (namespace)的相关资料,需要的朋友可以参考下
    2021-08-08
  • C++数据结构之链表的创建

    C++数据结构之链表的创建

    这篇文章主要介绍了C++数据结构之链表的创建的相关资料,希望通过本文帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • C语言中计算二叉树的宽度的两种方式

    C语言中计算二叉树的宽度的两种方式

    这篇文章主要介绍了C语言中计算二叉树的宽度的两种方式的相关资料,需要的朋友可以参考下
    2017-04-04
  • C++ 计算时间差的五种方法小结

    C++ 计算时间差的五种方法小结

    本文主要介绍了C++ 计算时间差的五种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 成员函数的重载、覆盖与隐藏详细解析

    成员函数的重载、覆盖与隐藏详细解析

    成员函数的重载、覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防
    2013-10-10

最新评论