全排列
来源:互联网 发布:淘宝网支架白板 编辑:程序博客网 时间:2024/04/28 13:32
全排列顾名思义指的是给定一个序列找出其所有的排列方式,例如给定字符串"abc",全排列为:abc、acb、bac、bca、cab、cba。对于不包含相同字符的字符串而言共有n!个排列方式。
解法一、字典序排列算法(非递归)
在字典序排列算法中,排列出现的不同次序是按照从右到左对字符的比较而确定的。例如,我们要对1、2、3、4进行全排列,第一个排列为1234,最后一个排列为4321,也就是说后一个排列要大于前一个排列,那么3142的下一个排列必为3214,这个3214是如何得来的呢?现在我们来看看字典序排列算法的基本思想:
给定已知序列A=P1 P2 P3 P4......Pn(其中1、2、3、4...n为下标)
<1>对输入序列进行升序排列
<2>从序列的右端开始,向左寻找相邻两个字符中第一个比右端小的字符,下标记为i。
<3>在Pi的右边寻找比Pi大的所有字符中最小的一个字符,下标记为j,交换Pi与Pj的值,然后颠倒i右边字符
<4>重复步骤<2>和<3>
例如数字698752431是1~9的一个全排列 ,那么它的下一个排列的计算如下:
我们发现从右端开始,相邻字符中第一个比右端小的字符为2(2 < 4) 698752431
在2的右边所有比2大的字符中最小的一个为3, 698752431
交换2和3的位置 698753421
对3右边的字符进行颠倒 698753124
代码如下:
#include <iostream>using namespace std;void permutation(int array[], int n);bool has_next(int array[], int n);void print_permutation(int array[], int n);void quick_sort(int array[],int start,int end);int partion(int array[], int start, int end);void reserve(int array[], int satrt, int end);int main(){int array[5] = { 1, 3, 5, 7};permutation(array, 4);}void permutation(int array[],int n){/*对输入字符进行升序排序:快速排序*/quick_sort(array, 0, n - 1);print_permutation(array, n);while (has_next(array, n))print_permutation(array, n);}/**/bool has_next(int array[],int n){/*寻找相邻两个元素中第一个比右端小的元素*/int i;for (i = n - 2; i >= 0;i--){if (array[i] < array[i+1])break;}if (i < 0)//没有下一个元素return false;/*寻找array[i]右端比array[i]大的所有元素中最小的元素*/int j = i+1,k;for (k = i + 2; k < n;k++){if (array[k] > array[i] && array[k] < array[j])j = k;}/*交换array[i]与array[j]的位置*/int tmp;tmp = array[i];array[i] = array[j];array[j] = tmp;/*颠倒array[i]右端的元素*/reserve(array, i + 1, n-1);return true;}void print_permutation(int array[], int n){for (int i = 0; i < n; i++)cout << array[i];cout << endl;}void quick_sort(int array[], int start, int end){if (start < end){int p = partion(array,start,end);quick_sort(array, start, p - 1);quick_sort(array, p + 1, end);}}int partion(int array[], int start, int end){int key = array[end];int i, j;j = 0;int tmp;for (i = 0; i < end;i++){if (array[i] < key){tmp = array[i];array[i] = array[j];array[j] = tmp;j++;}}array[end] = array[j];array[j] = key;return j;}void reserve(int array[], int satrt, int end){int tmp;while (satrt < end){tmp = array[satrt];array[satrt] = array[end];array[end] = tmp;satrt++;end--;}}运行结果:
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 全排列
- 菜单导航 纯CSS3液态胶合效果的环形菜单按钮特效
- OpenCV 相关记录
- Photoshop插件parker真正破解方法
- Servlet
- android 布局分析工具HierarchyView
- 全排列
- ios导入静态库时报错:"_OBJC_CLASS_$_"
- centos安装mongodb3.0及php mongo扩展和代码测试
- 解题报告:POJ_3460&HDU_1685 Booksort IDA*
- 39.Glide图片加载框架的使用
- 数据结构学习笔记(一)
- DAY4 单片机入门必备(硬件篇 二)
- 处理大并发之五 使用libevent利器bufferevent
- codis 3.0安装部署