非递归方法通常就是对递归方法的栈模拟。比如输出n个字符,可以将任务分成n个子任务。任务0:将0位和0位字符交换,之后产生一个新的子任务,就是1到n-1位字符的全排列;任务1,将0位和1位字符交换,之后产生一个新的子任务,就是2到n-1位字符的全排列,以此类推,直到第n-2个子任务,是将n-1位的一个元素全排列。每个子任务完成后要将两个元素再交换回来。可以设置一个任务栈,专门存放每个任务的状态,其中有三个成员,i:当前位,j:欲交换位,n:第几次出栈。每个任务会出两次栈,第一次处理该任务,判断是否输出,是否产生新的子任务。第二次交换回来位置。
- import java.util.*;
- public class StackTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- List<Character> list = new ArrayList<Character>();
- list.add('a');
- list.add('b');
- list.add('c');
- list.add('d');
- permutation(list);
- }
- public static void permutation(List<Character> list) {
- Stack<State> stack = new Stack<State>();
- int l = list.size();
- State temp = new State(0, 0, 0);
- for (int i = 0; i < l; i++)
- // 初始化栈,l个任务
- stack.push(new State(0, i, 0));
- // 栈空则结束
- while (!stack.isEmpty()) {
- // 弹出一个当前任务
- temp = stack.pop();
- // 如果已排到最后队尾,则打印当前数组
- if (temp.i == l - 1)
- System.out.println(list);
- // 否则分解子任务
- else {
- //交换队列元素
- Collections.swap(list, temp.i, temp.j);
- if (temp.n == 0) {
- temp.n += 1;
- stack.push(temp);
- int k=temp.i+1;
- for (int x =k; x < l; ++x)
- stack.push(new State(k, x, 0));
- }
- }
- }
- }
- }
- class State {
- public int i;
- public int j;
- public int n;
- public State(int i, int j, int n) {
- this.i = i;
- this.j = j;
- this.n = n;
- }
- }
复制代码 |