DFS求解出栈顺序,输出所有情况

版权声明:转载请注明出处 https://blog.csdn.net/yjpeng125/article/details/78369648

给定一个入栈顺序,输出所有出栈顺序及其方法数。对于一个一入栈的的数,他有两种选择,出栈进而输出,或者不出栈,等待新的元素进栈,不论哪一种操作,操作完成之后都会形成一个新的序列,这跟进行出栈,入栈操作之前一样,因此可以用递归的方法来模拟实现。输入的参数有3个,输入队列,中间用来存储的栈,用于输出的队列。我们在进行某一种操作后,这三种数据结构中的数会发生变化,但我们可以把它看做是初始的一种状态,从而进行递归。
递归的终止条件是:输入队列为空,并且中间栈也为空,此时所有数据都存储在输出队列中,可以输出队列,并且在终止条件中可以统计所有可能的方法数,num++;此时这种情况已经结束,可以返回到调用他的最初函数处,再考虑另一种操作(相等于另一条路径,但是要保存好之前的状态),再进行递归。

/*
已知入栈顺序,但可以在任意时刻出栈,求所有出栈顺序
输入队列 q1 中间栈st  输出队列q2
if(输入队列为空)
    {
        if(中间栈为空)//递归结束条件
        {
            //在递归结束条件里,可以输出所有序列,可以记录总数
            cnt++;
            cout<<str;
        }
        else//中间栈不为空
        {
            元素出栈,并添加到输出队列中去
            在进行DFS递归调用,因为此时输入队列为空,只能把栈中的元素放到输入了
        }
    }
else//输入队列不为空,
{
    if(中间栈为空)//最初始状态
    {
        //输入队列元素出队,添加到中间栈中
    }
    else//中间栈不为空,此时有两种情况,一是继续向栈中添加元素,二是直接出栈,添加到输出队列中,不过为了
    //实现这种情况递归返回后,还能保持之前的状态,应该在递归之前先记录原先队列和栈的情况
    {
        //记录栈,队列,复制
        出栈添加到队列
        DFS()
        从输入队列中出队,入栈
        DFS()
        //实际每一种操作后(入栈,出栈,入队,出队)都会使这3个序列发生改变,我们每次操作后,应该把这三个数据结构看做
        //是一开始的情况,最初的3中输入输入,中间栈,这样就是一个重复的事件,可以进行递归操作
    }
}
*/
int num = 0;
void clear_st(stack <char> &s)
{
    while (!s.empty())
        s.pop();
}
void clear_qu(queue <char> &s)
{
    while (!s.empty())
        s.pop();
}
void printQueue(queue<char> q)
{
    while (!q.empty())
    {
        char a = q.front();
        q.pop();
        cout << a;
    }
    cout << endl;
}

void DFS(queue<char>&in,stack<char>&st, queue<char> &out)
{

    if (in.empty())//输入为空
    {
        if (st.empty())//递归结束条件,栈为空
        {
            //输出队列元素
            num++;
            printQueue(out);
        }
        else//栈不为空
        {
            char a = st.top();
            st.pop();
            out.push(a);
            DFS(in, st, out);//这里也可是作为一种初始状态,继续搜素
        }
    }
    else//输入不为空
    {
        //栈为空,对应最开始的情况
        if (st.empty())
        {
            st.push(in.front());
            in.pop();
            DFS(in, st, out);//到这也可以作为一种初始化状态
        }
        else//栈不为空
        {
            queue<char> in0(in);
            queue<char> out0(out);
            stack<char> st0(st);
            //一个元素出栈,得到一种状态,相当于是一种新的初始状态
            out.push(st.top());
            st.pop();
            DFS(in, st, out);
            //或者 先不出栈先添加一个元素
            st0.push(in0.front());
            in0.pop();
            DFS(in0, st0, out0);
        }
    }
}

运行结果如下,实际上对于一个输入数量为n的序列(n<=10),共有C(2n,n)/(n+1)中情况,称之为卡特兰数。
这里写图片描述

展开阅读全文

没有更多推荐了,返回首页