编写一个返回堆栈的函数,该函数包含小于给定数字的所有元素,并且顺序相同?

时间:2013-11-17 16:41:34

标签: c++ recursion stack

美好的一天,并提前感谢。

我的问题就像在标题中所说的那样,编写一个接收堆栈和数字的函数,并返回一个新堆栈,其中包含旧堆栈的所有元素,而不是给定的数字,并且顺序相同。

算法必须使用递归来实现,并且具有尽可能低的时间和空间复杂度。

由于我对递归不好,我已经通过以下方式实现了这个:

template<typename T>
Stack<T> lesserStack(Stack<T> s, const T& max){

Stack<T> s1;
for(int i = 0; i <= s.numberOfElements() ; i++){
    if(s.top() < max) s1.push(s.top());
    s.pop();
}
s1.reverse();
return s1;
}

它有效,但它不应该是什么,我根本不知道如何使它递归:(

其他信息:

Stack实现为动态数组,pop函数返回弹出元素,top返回top元素。反向功能反转堆栈中的元素(以便保留原始顺序)。

2 个答案:

答案 0 :(得分:2)

您可以尝试以下几行(我还没有测试过)。我的想法是首先深入到递归中并在从递归返回后推送条目。

template<typename T>
Stack<T> lesserStack(Stack<T> s, Stack<T> s2, const T& max){

if ( s.size() == 0 )
  return s2;

T top = s.top();
s.pop();
Stack<T> s1 = lesserStack( s, s2, max);
if ( top < max )
  s1.push( top );
 return s1;
}

编辑:很高兴听到它有效。但是,我认为可以进一步改善,避免不必要的并发症。

它作为您的原始代码,但以下内容除外: 一旦它从原始堆栈中取出顶部元素,就不会立即将其推入新堆栈。相反,它首先弹出元素并再次为堆栈中的其他元素调用此函数。这是因为你想要保留顺序,并且这样做,首先从原始堆栈中弹出的那个,需要被推入新堆栈的最后一个。

在推动其他项目后,控件返回到此功能的下一行,然后按下该项目。

答案 1 :(得分:1)

递归执行此操作效率相当低。非递归版本看起来像这样:

template<typename T>
Stack<T> lesserStack(Stack<T> source, const T& max)
{
    Stack<T> dest;
    while (s.numberOfElements())
    {
        T t = s.top();
        if (t < max)
        {
            dest.push(t);
        }
        s.pop();
    }
    dest.reverse();
    return dest;
}

要转换它,您将删除循环:

template<typename T>
Stack<T> lesserStack(Stack<T> source, Stack<T>& dest, const T& max)
{
    if (source.numberOfElements() == 0)
    {
        return dest; // break out of your recursion
    }

    T t = s.top(); // get the "last" element
    source.pop();
    lesserStack(source, dest, max); // make the recursive call
    if (t < max)
    {
        dest.push(t); // push the last element - this will be done in the correct order
    }
    // no need to reverse the order as the unwinding of the call stack will put them in the reverse order already
    return dest;
}