字典序全排列算法(非递归全排列算法)
非递归全排列算法:
我们先看一个例子。
示例: 1 2 3的全排列如下:
1 2 3 , 1 3 2 , 2 1 3 , 2 3 1 , 3 1 2 , 3 2 1
我们这里是通过字典序法找出来的。
那么什么是字典序法呢?
从上面的全排列也可以看出来了,从左往右依次增大,对这就是字典序法。可是如何用算法来实现字典序法全排列呢?
我们再来看一段文字描述:(用字典序法找124653的下一个排列)
你主要看红色字体部分就行了,这就是步骤。
如果当前排列是124653,找它的下一个排列的方法是,从这个序列中从右至左找第一个左邻小于右邻的数,
如果找不到,则所有排列求解完成,如果找得到则说明排列未完成。
本例中将找到46,计4所在的位置为i,找到后不能直接将46位置互换,而又要从右到左到第一个比4大的数,
本例找到的数是5,其位置计为j,将i与j所在元素交换125643,
然后将i+1至最后一个元素从小到大排序(也可以说是反转,从643到346)得到125346,这就是124653的下一个排列。
对于像"654321"这种已经是最“大”的排列,采用STL中的处理方法,将字符串整个颠倒得到最“小”的排列"123456"并返回false (0)。
如此我们就可以利用字典序算法轻松实现非递归全排列算法啦。值得注意的是在循环前要对字符串排下序(升序)。
下面是程序代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>void swap(char *a,char *b)//交换
{char temp;temp = *a;*a = *b;*b = temp;
}void Reversal(char *a,char *b)//反转区间
{while(a < b){swap(a++,b--);}
}int Next_permutation(char *str)//下一个排序
{char *p,*q,*SFind;char *SEnd=str+strlen(str)-1;p=SEnd;while(p != str){q = p;p--;if(*p < *q) //找到相邻的,左邻小于右邻的地址 {SFind=SEnd;while(*SFind <= *p) //从最右端开始找大于左邻小于右邻的值得地址 {--SFind; }swap(p,SFind); //替换 Reversal(q,SEnd); //反转 return 1;}}Reversal(p,SEnd); //如果没有下一个排列,全部反转后返回0return 0;
}int compare(const void *a,const void *b)//比较函数
{return *(char*)a-*(char*)b; //升序
}int main()
{char str[10];printf("请输入排列字符串:");gets(str);qsort(str,strlen(str),sizeof(char),compare);int i=1;do{printf("第%d种排列为:\t%s\n",i++,str);}while(Next_permutation(str));return 0;
}
当然了,如果是C++中可以直接调用STL库中方法,实际上原理和上述C代码原理是一致的:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;int main(void)
{string arr="2134";int len=arr.length();sort(arr.begin(),arr.end());do{static int j=1;cout<<"第"<<j++<<"次排列:\t";for(int i=0;i<len;i++)cout<<arr[i];cout<<endl;}while(next_permutation(arr.begin(),arr.end()));return 0;
}
运行效果截图:
字典序全排列算法(非递归全排列算法)相关推荐
- 【转】全排列算法非递归实现和递归实现
来源:http://blog.csdn.net/e3399/article/details/7543861 (一)递归的全排列算法 (A.B.C.D)的全排列为 1.A后面跟(B.C.D)的全排列 2 ...
- 树:二叉树的非递归遍历算法
二叉树的递归遍历 二叉树的递归遍历算法,写法很简单,比如说前序遍历树,如下: //前序遍历 void PreOrderTraverse(BiTree tree) {if (NULL != tree){ ...
- 实现二叉树的三种非递归遍历算法
[问题描述] 编写程序,实现二叉树的三种非递归遍历算法:先序非递归,中序非递归,后序非递归. [输入形式] 输入建树序列. [输出形式] 输出三种遍历序列. [样例输入] A B C # # # # ...
- 树的递归与非递归遍历算法
树的递归与非递归遍历算法 树的递归与非递归遍历算法 树的遍历 实例 树遍历的口诀 树的递归遍历代码 树的先序遍历 树的中序遍历 树的后序遍历 递归遍历思想 树的非递归遍历 树的先序非递归遍历 先序遍历 ...
- 二分查找算法(非递归)
1.二分查找算法(非递归)介绍 前面我们讲过了二分查找算法,是使用递归的方式,下面我们讲解二分查找算法的非递归方式 二分查找法只适用于从有序的数列中进行查找(比如数字和字母等),将数列排序后再进行查找 ...
- 数据结构——二叉树的递归遍历算法与非递归遍历算法+层次遍历算法
(文章篇幅有点长,二叉树的递归遍历算法不作详细分析,但是二叉树的非递归遍历算法和层次遍历算法都有非常详细的分析过程,记得往下翻哦!) 二叉树的递归遍历算法实现 我们首先用递归的方法先序遍历创建这样一棵 ...
- python冒泡排序算法非递归_python 冒泡排序,递归
今天LeetCode的时候暴力求解233 问题: 给定一个整数 n,计算所有小于等于 n 的非负数中数字1出现的个数. 例如: 给定 n = 13, 返回 6,因为数字1出现在下数中出现:1,10,1 ...
- java版 二叉树 所有递归和非递归遍历算法
[java] 通过数组构造二叉树,所有遍历算法以及求二叉树深度的递归算法 [java] import java.util.LinkedList; public class BinaryTree { ...
- 常用十大算法 非递归二分查找、分治法、动态规划、贪心算法、回溯算法(骑士周游为例)、KMP、最小生成树算法:Prim、Kruskal、最短路径算法:Dijkstra、Floyd。
十大算法 学完数据结构该学什么?当然是来巩固算法,下面介绍了十中比较常用的算法,希望能帮到大家. 包括:非递归二分查找.分治法.动态规划.贪心算法.回溯算法(骑士周游为例).KMP.最小生成树算法:P ...
最新文章
- JQuery 1.32 DatePicker 增强版
- SAP MM ME21N 创建PO时报错 - Net price in CNY becomes too large – 之原因分析
- Java 二次MD5 32位小写加密算法与php页面加密结果相同
- BUUCTF-----actf_2019_babyheap (UAF)
- HDU 1108.最小公倍数-辗转相除法
- 【1024创造营】精彩课程回顾
- 关于angular2更新时机的一些发现
- 几种流行的JS框架的选择
- Python(13)-函数,lambda语句
- (三)微调VGG16以对服装进行分类
- 页面跳转与重定向(之二)
- 【软件使用技巧】一(截图)
- java驱动刷机_ProductTool(炬力芯片刷机工具+驱动) v5.46 中文安装免费版
- voip语音中转服务器,基于VoIP的语音应用服务器的设计与实现
- 深度学习面试题汇总大全(转)
- 离开一线三年后,码农们都过上好的生活了吗
- 阿里云CDN防盗链设置方法
- 今日小程序推荐:动态壁纸-你专属壁纸!
- 春招计算机专科学校,邵东计算机IT春招学校排名
- 四、四相节拍脉冲发生器、带启停电路的时序电路(含电路图)
热门文章
- ImageView图片圆形显示
- 2021-07-29 打印机不出现PDF打印
- 深度对话语音行业专家李秀林:十年坚守初心,加入创业公司
- 解决rpm包安装时的循环依赖问题
- 专栏▍数据智能的现在与未来
- springClound之整合Eureka
- 基于javaweb心理咨询预约管理系统
- Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释
- List集合中add()方法和addAll()方法的区别
- 什么是计算机,计算机的发展史以及计算机的一些常用的快捷方式和Dos指令···