您的位置:首页 > 其它

栈的常见递归用法

2011-05-11 22:57 295 查看
下面是两道常见笔试题:

栈的原地排序。(注:所谓原地就是指不需要额外的辅助空间,或者只需要常数个额外空间)

栈的原地倒转。

但是在这里递归的思想非常抽象,但是又不得不让人叹服!(我也是看了别人的答案,简直太经典了!)另外,虽然不允许另外使用额外空间,但实际上递归本身就要很多空间。。。

【栈的原地倒转】

这里的递归思想用语言描述太复杂,但是您一看代码,加上那一点注释,很快就能明白的。相信你也会为这个递归的用法感到奇妙!

#include <iostream>
#include <stack>

using namespace std;

//display the stack
void printStack( stack<int> s );

//!!!!!!
void reverse( stack<int>& s )
{
/*
** if there is only one element pr no element in stack
** there is no need to reverse.
*/
if( s.empty() || s.size() == 1 )
return ;

/*
** GOOD!!!
** in the beginning, the stack is 1,2,



,n-1,n
*/
int top_one = s.top(); s.pop();//1,2,



,n-1
reverse( s ); //n-1,n-2,

..,2,1
int bottom = s.top(); s.pop(); //n-1,n-2,



,2
reverse( s ); //2,3,



n-1
s.push( top_one ); //2,3,



,n-1,n
reverse( s ); //n,n-1,



,3,2
s.push( bottom ); //n,n-1,



,2,1
}

int main()
{
stack<int> s;
s.push( 5 );
s.push( 6 );
s.push( 4 );
s.push( 8 );
s.push( 10 );
s.push( 11 );

printStack( s );
reverse( s );
printStack( s );
}

void printStack( stack<int> s )
{
stack<int> temp(s);
while( ! temp.empty() )
{
cout<<temp.top()<<" ";
temp.pop();
}
cout<<endl;
}

不过这里我犯了一个大错误:由于这里的函数需要对栈进行操作改变,所以需要传递一个引用(stack&),而不能只传一个值进去,否则是看不到结果的改变的。。。让我费了好久debug!

【栈的原地排序】

其实有了上面这道题,这部分代码也很容易。大致思想就是:每次从栈顶取出一个元素(记为A),都要递归的对剩下的元素排序。问题的关键在于,这个取出来的元素如何放回去,因为其余的元素都已经排好序了,不能随便放回去。我们这里实现的是最小栈(栈顶为最小元素,记为B),所以取出来的元素A需要跟当前栈顶的元素B作比较,如果它比当前栈顶B还小,那么A理所当然的应该放在栈顶;否则,就把栈顶元素B取出,把A放进去(因为B是所有元素中最小的,A比它大,当然要先入栈),递归排序,然后再把B入栈。

代码如下(只贴出了排序的函数,其余函数可以参照上面的):

//!!!!!!
void sortStack( stack<int>& s )
{
if( s.empty() || s.size() == 1 )
return;

int top_one = s.top(); s.pop();
sortStack( s );

int smallest = s.top(); s.pop();

if( smallest < top_one )//it's smallest overall
{
s.push( top_one );
//top_one may be very big
//need to sort the stack again
sortStack( s );
s.push( smallest );
}
else
{
//no need to sort again
s.push( smallest );
s.push( top_one);
}
}

通过 Wiz 发布
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: