问题描述:

打印输出1-9的所有全排序列,或者打印输出a-d的全排列。

思路分析:

将每个元素放到余下n-1个元素组成的队列最前方,然后对剩余元素进行全排列,依次递归下去。

比如:1 2 3 为例
首先将1放到最前方(跟第1个元素交换),然后后面2位再做全排,然后将1放回本来位置 
结果 1 2 3; 1 3 2
其次将2放到最前方(跟第1个元素交换),然后后面2位再做全排,然后将2放回原处
结果 2 1 3; 2 3 1
。。。。。

C/C++递归实现:

#include<cstdio>
#include<iostream>
using namespace std; void swap(int list[], int i, int j) //交换list中i和j位置的元素
{
int temp = list[i];
list[i] = list[j];
list[j] = temp;
} void fun(int list[], int m, int n) //输出list中m到n的全排列
{
if(m==n)
{
for(int i=; i<n; i++) //输出0-n的一个排列
{
printf("%d",list[i]);
}
printf("\n");
}
else
{
for(int i=m; i<n; i++)
{
swap(list,m,i); //把第i个和第一个(此时是m)交换
fun(list,m+,n); //余下的继续递归
swap(list,m,i); //将第i个放回原处
}
}
} int main()
{
int list[] = {,,,,,};
int length = sizeof(list)/sizeof(list[]);
fun(list,,length);
return ;
}

C/C++非递归实现:(当输入中数字有重复数字时仍能正常工作,即不会有重复输出)

/*完全参考:http://blog.csdn.net/prstaxy/article/details/8147029*/

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool next(vector<int> &v)//注意是引用
{
int i;
for(i=v.size()-;i>=;i--)
{//从数组后面往前找到第一个比后面的数小的地方
if(v[i-]<v[i])
break;
}
if(i==)//整个数组都是逆序,说明是已是排列最后一个
return false;//没有下一个
else
{
int t=v[i-],pos=i;
for(int j=i;j<v.size();j++)
{
if(v[j]>t && v[j]<=v[pos])//再往后找比v[i-1]大的数中最小的一个 //2014.10.1把<改成<=,否则输入有重复数字时会出现bug
pos=j;
}
v[i-]=v[pos];
v[pos]=t;//交换
//sort(v.begin()+i,v.end());//从小到达排序
reverse(v.begin()+i,v.end());//此时正好逆序,只需反转即可从小到达排序
return true;//还有下一个
}
}
void printVctor(vector<int> v)
{
for(int i=;i<v.size();++i)
cout<<v[i]<<" ";
cout<<endl;
}
int main()
{
int a[] = {,,,,};
vector<int> v(a,a+);
do
{
printVctor(v);
}while(next(v));
return ;
}

非递归实现

C++ STL代码实现:

C++ STL中算法库中包含了计算排列组合关系的算法next_permutation、prev_permutation,用法如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std; int main()
{
int list[] = {,,,,,};
int length = sizeof(list)/sizeof(list[]);
sort(list, list+length); /* 这个sort可以不用,因为{1,2,3,4}已经排好序*/
do /*注意这步,如果是while循环,则需要提前输出第一个次序*/
{
for(int i=; i<length; i++)
{
printf("%d",list[i]);
}
printf("\n");
}while(next_permutation(list,list+length));
//while(prev_permutation(list,list+length));//求上一个排列数,初始数组用逆序来调用可以输出全排列
return ;
}

参考链接:

next_permutation(全排列算法)     http://blog.csdn.net/c18219227162/article/details/50301513

上面这个链接开始介绍了排列组合是如何区分前一个后一个的,也就是如何排序的; 最后还包含一个 “直接算出集合{1, 2, ..., m}的第n个排列” 的代码实现

http://blog.csdn.net/prstaxy/article/details/8147029

http://blog.csdn.net/knisinf/article/details/48048011

全排列问题(递归&非递归&STL函数)的更多相关文章

  1. Reverse Linked List 递归非递归实现

    单链表反转--递归非递归实现 Java接口: ListNode reverseList(ListNode head) 非递归的实现 有2种,参考 头结点插入法 就地反转 递归的实现 1) Divide ...

  2. 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)

    一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...

  3. 二叉树——遍历篇(递归/非递归,C++)

    二叉树--遍历篇 二叉树很多算法题都与其遍历相关,笔者经过大量学习.思考,整理总结写下二叉树的遍历篇,涵盖递归和非递归实现. 1.二叉树数据结构及访问函数 #include <stdio.h&g ...

  4. 二叉树的先序、中序以及后序遍历(递归 && 非递归)

    树节点定义: class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } 递归建立二 ...

  5. 树的广度优先遍历和深度优先遍历(递归非递归、Java实现)

    在编程生活中,我们总会遇见树性结构,这几天刚好需要对树形结构操作,就记录下自己的操作方式以及过程.现在假设有一颗这样树,(是不是二叉树都没关系,原理都是一样的) 1.广度优先遍历 英文缩写为BFS即B ...

  6. java:合并两个排序的链表(递归+非递归)

    //采用不带头结点的链表 非递归实现 public static ListNode merge(ListNode list1,ListNode list2){ if(list1==null) retu ...

  7. 二叉树的递归,非递归遍历(java)

    import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private ...

  8. 二叉树的递归,非递归遍历(C++)

    二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...

  9. 递归/非递归----python深度遍历二叉树(前序遍历,中序遍历,后序遍历)

    递归代码:递归实现很简单 '二叉树结点类' class TreeNode: def __init__(self, x): self.val = x self.left = None self.righ ...

随机推荐

  1. Java——Struts2 之国际化 struts.custom.i18n.resources=globalMessages

    1.在src下 建立 struts.properties 文件,内容为:struts.custom.i18n.resources=globalMessages struts.custom.i18n.r ...

  2. Seafile 网络磁盘

    Seafile 个人 网盘 1.安装 Seafile 1.安装依赖环境 使用 yum 安装 Python 及 MySQL: yum install python python-setuptools p ...

  3. Postfix 邮件服务 - roundcube webmail

      roundcubemail作为web端的邮件客户端.是一个基于浏览器,支持多国语言的IMAP客户端,它的操作界面看起像一个桌面应用程序.它提供一个email客户端应该具备的所有功能,包括MIME支 ...

  4. mysql 原理 ~ checkpoint

    一 简介:今天咱们来聊聊checkpoint 二 定义: checkpoin是重做日志对数据页刷新到磁盘的操作做的检查点,通过LSN号保存记录,作用是当发生宕机等crash情况时,再次启动时会查询ch ...

  5. emmc基础技术8:操作模式3-interrupt mode

    1. 前言 eMMC总线操作包含: boot mode, device identification mode interrupt mode data transfer mode 本文主要描述inte ...

  6. Linux串口—struct termios结构体【转】

    转自:https://blog.csdn.net/yemingzhu163/article/details/5897156 一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步 ...

  7. How to Repair GRUB2 When Ubuntu Won’t Boot

    Ubuntu and many other Linux distributions use the GRUB2 boot loader. If GRUB2 breaks—for example, if ...

  8. Sql 插入自定义主键

    在遇到数据库设计是自增的主键,且需要插入自定义的主键Id时,这个时候如果直接Insert的话,将会发生错误,错误提示信息: 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'XXX' ...

  9. Mac Terminal 菜鸟篇之目录跳转命令

    以前一直都是使用Windows系统,连命令行都没怎么用过.来到了Mac,在某位大神的诱导下,我开始尝试使用Mac Terminal,下面总结的是一些简单的目录跳转命令(菜鸟级). 文件目录 首先要清楚 ...

  10. 同时装了Python3和Python2,怎么用pip

    作者:匿名用户链接:https://www.zhihu.com/question/21653286/answer/95532074来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...