全排列遞迴演算法詳解
一、概述
全排列在很多程式都有應用,是一個很常見的演算法,常規的演算法是一種遞迴的演算法,這種演算法的得到基於以下的分析思路。 給定一個具有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)式資料結構。在程式執行時,系統每次向棧中壓入一個物件,然後棧指標向下移動一個位置。當系統從棧中彈出一個物件時,最近進棧的物件將被彈出。然後棧指標向上移動一個位置。程式設計師經常利用棧這種資料