全排列

来源:互联网 发布:淘宝网支架白板 编辑:程序博客网 时间: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--;}}
运行结果:


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手抖不会画眼线怎么办 画眼线眼睛总眨怎么办 画眼线总是晕妆怎么办 眼线笔没用完干了怎么办 新的眼线笔干了怎么办 不涂口红没气色怎么办 眼线笔容易晕妆怎么办 眼线笔老是晕妆怎么办 眼线液老是晕妆怎么办 旋转眼线笔断了怎么办 眼睛去皮以后眉眼距窄怎么办 速写型总是画不准怎么办 速写人物不会打形怎么办 鼻头又圆又大怎么办 耳鸣嘴溃疡眼流泪上火怎么办 孩子看电视总挤眼睛怎么办 小孩老是咳嗽有痰怎么办 长时间看手机眼睛模糊怎么办 长时间看电脑眼睛模糊怎么办 手机玩多了眼睛模糊怎么办 手机看多了眼睛模糊怎么办 孩子玩手机眼睛红怎么办 手机玩多了眼睛红怎么办 手机看久了眼花怎么办 玩手机眼睛近视了怎么办 近视了怎么办30个字 吃了长牙的土豆怎么办 鸡蛋和土豆吃了怎么办 狗狗眼睛流血水怎么办 石粉粘土干了怎么办 樱花针管笔干了怎么办 想学linux不会c语言怎么办 被摩托车排气管烫伤了怎么办 泡泡糖粘在衣服上怎么办 皮卡书屋办卡怎么办 照证件照齐刘海怎么办 哈挺机床卡刀了怎么办 绝地求生卡在登陆页面怎么办 白鞋子长霉了怎么办 幸福树树干烂了怎么办 花椒树树叶掉落枝干发黑怎么办