1. 程式人生 > >全排列遞迴演算法詳解

全排列遞迴演算法詳解

一、概述

全排列在很多程式都有應用,是一個很常見的演算法,常規的演算法是一種遞迴的演算法,這種演算法的得到基於以下的分析思路。 給定一個具有n個元素的集合(n>=1),要求輸出這個集合中元素的所有可能的排列。

二、遞迴實現

2.1、例項一

    例如,如果集合是{a,b,c},那麼這個集合中元素的所有排列是{(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)},顯然,給定n個元素共有n!種不同的排列,如果給定集合是{a,b,c,d},可以用下面給出的簡單演算法產生其所有排列,即集合(a,b,c,d)的所有排列有下面的排列組成:

 (1)以a開頭後面跟著(b,c,d)的排列

(2)以b開頭後面跟著(a,c,d)的排列

(3)以c開頭後面跟著(a,b,d)的排列

(4)以d開頭後面跟著(a,b,c)的排列,這顯然是一種遞迴的思路,於是我們得到了以下的實現:
    #include "iostream"  
    using namespace std;  

    void permutation(char* a,int k,int m)  
    {  
        int i,j;  
        if(k == m)  
        {  
            for(i=0;i<=m;i++)  
                cout<<a[i];  
            cout<<endl;  
        }  
        else  
        {  
            for
(j=k;j<=m;j++) { swap(a[j],a[k]); permutation(a,k+1,m); swap(a[j],a[k]); } } } int main(void) { char a[] = "abc"; cout<<a<<"所有全排列的結果為:"<<endl; permutation(a
,0,2); system("pause"); return 0; }

2.2、STL實現

    有時候遞迴的效率使得我們不得不考慮除此之外的其他實現,很多把遞迴演算法轉換到非遞迴形式的演算法是比較難的,這個時候我們不要忘記了標準模板庫已經實現的那些演算法,這讓我們非常輕鬆。STL有一個函式next_permutation(),它的作用是如果對於一個序列,存在按照字典排序後這個排列的下一個排列,那麼就返回true且產生這個排列,否則返回false。注意,為了產生全排列,這個序列要是有序的,也就是說要呼叫一次sort。實現很簡單,我們看一下程式碼:
    #include "iostream"  
    #include "algorithm"  
    using namespace std;  

    void permutation(char* str,int length)  
    {  
        sort(str,str+length);  
        do  
        {  
            for(int i=0;i<length;i++)  
                cout<<str[i];  
            cout<<endl;  
        }while(next_permutation(str,str+length));  

    }  
    int main(void)  
    {  
        char str[] = "acb";  
        cout<<str<<"所有全排列的結果為:"<<endl;  
        permutation(str,3);  
        system("pause");  
        return 0;  
    }  

2.3、有一定約束條件的全排列

     對數1,2,3,4,5要實現全排序。要求4必須在3的左邊,其它的數位置隨意。 

     思路:首先使用上面的2種方法之一實現全排列,然後對全排列進行篩選,篩選出4在3左邊的排列。
    #include "iostream"  
    #include "algorithm"  
    using namespace std;  

    void permutation(int* a,int length)  
    {  
        int i,flag;  
        sort(a,a+length);  
        do  
        {  
            for(i=0;i<length;i++)  
            {  
                if(a[i]==3)  
                    flag=1;  
                else if(a[i]==4)             //如果3在4的左邊,執行完程式碼,flag就是2  
                    flag=2;  
            }  
            if(flag==1)          //如果4在3的左邊,執行完程式碼,flag就是1  
            {  
                for(i=0;i<length;i++)  
                    cout<<a[i];  
                cout<<endl;  
            }  
        }while(next_permutation(a,a+length));  

    }  
    int main(void)  
    {  
        int i,a[5];  
        for(i=0;i<5;i++)  
            a[i]=i+1;  
        printf("%d以內所有4在3左邊的全排列結果為:\n",i);  
        permutation(a,5);  
        system("pause");  
        return 0;  
    }  

相關推薦

排列演算法

一、概述 全排列在很多程式都有應用,是一個很常見的演算法,常規的演算法是一種遞迴的演算法,這種演算法的得到基於以下的分析思路。 給定一個具有n個元素的集合(n>=1),要求輸出這個集合中元素的所有可能的排列。 二、遞迴實現 2.1、例項一

排列演算法

遞迴求全排列演算法: 例如:char a[]=”abc”  ,(i,j,k)表示陣列現有的元素 perm(a,k,m);//從陣列下標k到m的全排列 k==m 只剩一個元素為遞迴出口 C++原始碼: #include <iostre

演算法

1. 何為遞迴? 遞迴在我們的生活中其實很常見。假設你去電影院看電影,黑漆漆一片,你不知道自己來到了第幾排,於是你問前面的人他是第幾排,知道了前面的人是第幾排,加一也就是你所在的排數。但前面的人也不知道,於是他也繼續向前問,直到第一排的人回答他在第一排,然後再依次往後傳,最後

排列+演算法的解決

1.問題介紹 全排列就是輸出一個序列的所有可能排列{a,b}的可能排列為{a,b},{b,a}; {1,2,3}的全排列為{1,2,3}、{1,3,2}、{2,1,3}、{2,3,1}、{3,2,1}、{3,1,2}。想必大家都理解了全排列,這裡就不再列舉其他情

演算法01:排列演算法

全排列是指n個元素按一定順序的所有排列組合,如{1,2,3}三個元素的全排列為{1,2,3}、{1,3,2}、{2,1,3}、{2,3,1}、{3,1,2}、{3,2,1}共3!種。 常見排列的演算法一般有: (1)遞迴法 (2)字典序法 (3)鄰位對換法 (4)遞增進位

n的排列演算法

思路: 可以通過遞迴的方法把n的全排列問題轉化為n-1的全排列問題,逐漸推導到一個數字的全排列,顯然一個數字的全排列方式只有一種,下面就展示實現該過程的實現程式碼: #include <iostream> using namespace std; void s

排列演算法(C++實現)

演算法實現思路 遞迴解決問題的方法就是將一個大問題不斷分解成小問題,直到小問題很容易解決為止 先看全排列怎麼分解成小問題:        假設要全排列“ABC”,先把A作為前部不變,全排列BC,同樣將B作為前部,全排列C,顯然是它本身 於是大問題變成了很容易解決的小問題了

二叉樹3種遍歷演算法與非實現

一, 二叉樹先序遍歷的實現     遞迴實現 void PreOrderTraverse(BiTree T) { if( T ) { VisitF(T->data);//訪問根節點 PreOrderTra

排列-去重複實現-非DFS

import java.util.*; public class Quanpaifeidigui { public static void main(String args[]){ Scanner in=new Scanner(System.in); whil

排列-(不含去重複的操作)非DFS

import java.util.*; public class Quanpaifeidigui { public static void main(String args[]){ Scanner in=new Scanner(System.in); whil

圖的深度優先遍歷(非+

圖的深度優先遍歷 非遞迴演算法: #include<iostream> #include<stack> using namespace std; const int MaxSize=100; class MGraph{//鄰接矩陣的構建 p

排列 (非字典序) 深搜(字典序)

全排列問題初探,不含重複元素情況的討論。 糊的題目: 【題目描述】 給定一個由不同的小寫字母組成的字串,輸出這個字串的所有全排列。 我們假設對於小寫字母有‘a’ <‘b’ < ... <‘y’<‘z’,而且給定的字串中的字母已經按照從小到大的順

筆記一:n個元素的所有排列演算法

求n個元素的所有排列組合 問題:給定n個元素,設序列為{a,b,c},求所有的排列組合。 思路:每次遞迴,對組合的第一個元素排序。 程式碼: #include<iostream&g

LeetCode 856 思路

題目描述 給定一個平衡括號字串 S,按下述規則計算該字串的分數: () 得 1 分。 AB 得 A + B 分,其中 A 和 B 是平衡括號字串。 (A) 得 2 * A 分,其中 A 是平衡括號字串。

入門(十) ---- 列印數字(原理)

wechat:812716131 ------------------------------------------------------ 技術交流群請聯絡上面wechat ----------------------------------------------

HDU - 1995 奇妙的塔 (漢諾塔思想

用1,2,...,n表示n個盤子,稱為1號盤,2號盤,...。號數大盤子就大。經典的漢諾塔問  題經常作為一個遞迴的經典例題存在。可能有人並不知道漢諾塔問題的典故。漢諾塔來源於  印度傳說的一個故事,上帝創造世界時作了三根金剛石柱子,在一根柱子上從下往上按大小 

python 排列 中的兩種實現

我所知道的全排列有四種: 1.迭代的排列組合全排列(非遞迴):字典序的大小,即傳說中的A33 2.鄰位置對換的全排列(非遞迴): 方法一:生成下一個排列,該方法對重複元素同樣有效 如果可以根據一個排列生成他的下一個排列,那麼生成所有排列也就不在話下了,下面以排列625431

PYTHON 函式

Python 遞迴函式 詳解 在函式內呼叫當前函式本身的函式就是遞迴函式 下面是一個遞迴函式的例項: 第一次接觸遞迴函式的人,都會被它呼叫本身而搞得暈頭轉向,而且看上面的函式呼叫,得到的結果會是: 為什麼會得出上面的結果呢?因為都把呼叫函式本身之後的程式

排列方法

(一)遞迴的全排列演算法 (A、B、C、D)的全排列為 1、A後面跟(B、C、D)的全排列 2、B後面跟(A、C、D)的全排列(A與B交換,其他次序保持不變) 3、C後面跟(B、A、D)的全排列

呼叫,分析呼叫的詳細過程

一、棧      在說函式遞迴的時候,順便說一下棧的概念。      棧是一個後進先出的壓入(push)和彈出(pop)式資料結構。在程式執行時,系統每次向棧中壓入一個物件,然後棧指標向下移動一個位置。當系統從棧中彈出一個物件時,最近進棧的物件將被彈出。然後棧指標向上移動一個位置。程式設計師經常利用棧這種資料