算法学习(二) 全排列问题的非递归算法——模拟堆栈

      前一段时间总结了全排列问题的几种递归解法,今天再总结一下如何通过对系统栈行为的模拟来非递归的实现全排列问题。

      我们用一个数组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 <iostream>
 2 
 3 using namespace std;
 4 
 5 int stack[100];
 6 int flags[50];
 7 
 8 void printStack(int* stack,int n){
 9     for (int i=0; i<n; i++) {
10         cout<<stack[i]+1;
11     }
12     cout<<endl;
13 }
14 
15 void perm(int n){
16     int top=0;
17     int i=-1;
18     while (true) {
19         i++;
20         if (i==n) {
21             if (top==0) {
22                 break;
23             }else{
24                 top--;
25                 i=stack[top];
26                 flags[i]=1;
27             }
28         }else if(flags[i]==1){
29             flags[i]=0;
30             stack[top]=i;
31             top++;
32             i=-1;
33         }
34         if(top==n){
35             top--;
36             i=stack[top];
37             flags[i]=1;
38             printStack(stack, n);
39         }
40     }
41 }
42 
43 int main(int argc, const char * argv[])
44 {
45     int n=4;
46     for(int i=0;i<50;i++){
47         flags[i]=1;
48     }
49     perm(n);
50     return 0;
51 }

 

posted @ 2014-08-21 21:35  福尔摩斯の子弟  阅读(2489)  评论(2编辑  收藏  举报