栈的常见递归用法
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 发布
栈的原地排序。(注:所谓原地就是指不需要额外的辅助空间,或者只需要常数个额外空间)
栈的原地倒转。
但是在这里递归的思想非常抽象,但是又不得不让人叹服!(我也是看了别人的答案,简直太经典了!)另外,虽然不允许另外使用额外空间,但实际上递归本身就要很多空间。。。
【栈的原地倒转】
这里的递归思想用语言描述太复杂,但是您一看代码,加上那一点注释,很快就能明白的。相信你也会为这个递归的用法感到奇妙!
#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 发布
相关文章推荐
- 栈的常见递归用法
- liunx 中 find常见用法示例 / linux下递归删除目录下所有asp文件
- 关于layer的常见用法
- Python——list常见用法
- IOS中NSNumber常见用法
- Linux中find常见用法示例
- JavaScript中常见的数组操作函数及用法
- Android Intent机制与常见的用法
- String的一些常见用法
- Linux常见命令的用法
- VC中MessageBox的常见用法
- Android开发之——消息模式Toast.makeText的常见用法
- java枚举类的常见用法
- set--常见成员函数及基本用法
- ACM常见高精度总结(java用法)
- 常见试题:利用递归打印前10个斐波那契数列
- find 常见用法
- linux条件锁常见用法
- JSP标签 jstl 的常见用法
- 辛星收集整理之twig的常见用法