前一段時間總結了全排列問題的幾種遞迴解法,今天再總結一下如何通過對系統棧行為的模擬來非遞迴的實現全排列問題。
我們用乙個陣列stack來表示乙個棧,用乙個top指標來表示棧頂,用乙個flags陣列來標示每乙個數字的可用性;用i來表示當前的狀態。
初始狀態top=0;i=-1;flags陣列全為1;
i遞增,如果i沒有越界並且flags[i]==1,那麼就將i寫入棧中,棧頂往前移動一位;最後把flags[i]賦值為0,i回溯到初始狀態-1;
當棧頂越界,就將整個棧的資訊列印出來,然後top指標回退1,i回歸棧頂的狀態,flags[i]標記為1;
當i越界,意味著當前棧頂的狀態已經窮盡,應該將該元素彈出棧,即top--;然後i回歸到棧頂的狀態,flags[i]標記為1;
最後,當棧中元素全被彈出,棧頂和棧底相遇,則所有狀態全被窮盡。
語言描述的有點抽象,可以根據這個在紙上畫畫圖,這整個過程就是系統棧的行為過程。主要的點就是每次棧頂的變化都伴隨i的變化,i要回溯到前乙個狀態。
最後放上c++的**,可以參考著再理解理解,我的表達能力確實有點捉急。。。
1 #include 23using
namespace
std;45
int stack[100];6
int flags[50];7
8void printstack(int* stack,int
n)12 cout<
1415
void perm(int
n)else
28 }else
if(flags[i]==1)34
if(top==n)40}
41}4243
int main(int argc, const
char *argv)
4449
perm(n);
50return0;
51 }
全排列演算法之非遞迴實現
演算法的核心思想是如何求下乙個排列?例如求23543的下乙個排列我們從後往前找相鄰的2個遞減數字即3,5,那麼3就是我們要替換的數字,再從後面找乙個比3大的最小數即4,把它們交換,就變成了24533,再對4後面的數進行反轉,得到24335,完成了下乙個排列的生成。下面是參照stl中next perm...
全排列的非遞迴演算法
這個講解的非常通俗易通,所以記錄下來備用。先大體介紹一下演算法思路 比如說有1234四個數字,我們要將這四個數字實現全排列。拋棄初中老師教我們的4 3 2 1的思路,我們來換一種思路。1234 當然是第乙個排列,要得到第二個排列,我們選取剛好比它大的,我們用大腦當然想的到是 1243 但是我們怎樣解...
遞迴演算法之全排列問題
2 數字全排列 numlist.pas in out 列出所有從數字1到數字n的連續自然數的排列,要求所產生的任一數字序列中不允許出現重複的數字。輸入乙個整數n 1 n 9 輸出由1 n組成的所有不重複的數字序列,每行乙個序列,數字與數字之間用空格隔開,行首行尾不留空格。樣例輸入 numlist.i...