关于用动态数组实现堆栈的问题

warsong 2007-01-10 03:38:08
这是《C++ Primer Plus(第四版)》第12章的课后习题第四题:
有如下的类声明
// stack.h — class declaration for the stack ADT
typedef unsigned long Item;
class Stack
{
private:
enum { MAX = 10} ; // constant specific to class
Item * pitems; // holds stack items
int size; // number of elements in stack
int top; // index for top stack item
public:
Stack(int n = 10); // creates stack with n elements
Stack(const Stack & st);
~Stack();
bool isempty() const;
bool isfull() const;
// push() returns false if stack already is full, true otherwise
bool push(const Item & item); // add item to stack
// pop() returns false if stack already is empty, true otherwise
bool pop(Item & item); // pop top into item
Stack & operator=(const Stack & st);
} ;
正如私有成员表明的,这个类使用动态分配的数组来保存堆栈项,请实现该类的定义并编写一个程序来演示所有方法,包括复制构造函数和赋值操作符。

这是一个简化了的堆栈,我就不解释每个方法的意思了。如果是用数组“Item pitems[MAX]”来实现,就很简单,可是用动态数组怎么做呢?最关键的一个问题是:在push时,怎么增大动态数组,并将它与以前的数组联系起来?用链表能够实现,可是用数组该怎么办?
我能想得的方法就是:在push时,重新new一个新的数组(大小是原来的大小+1),然后将原来的数组元素和pust的那个元素拷贝进去,再把原来的那个数组delete了。可是这样太笨拙了,我觉得标准答案应该不是这样(可恶的是这本书的练习题没有答案)。
所以,只好请各位高手相助了,谢谢!^_^
BTW:STL里面也有Stack,它是用什么实现的呢?
...全文
844 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
warsong 2007-01-14
  • 打赏
  • 举报
回复
to v2002750:你的做法似乎跟我的想法一样!^_^
to jixingzhong:谢谢你写了那么多,不过可能你没有理解清楚我的意思(也可能是我没有表达清楚)。我所指的动态数组,是要求在使用stack过程中,随着push和pop的操作而改变其的大小,而不是在创建stack时就固定了大小的。
看了一下《STL源码剖析》,大概了解了:如果要用数组来实现大小动态变化stack,的确只能重新new一个新数组,然后拷贝,最后再删除原数组。不过我认为,作为一个课后练习,应该不会这样繁琐。所以真正的答案应该就如htqx和jixingzhong等人所说,用一个大小相对固定的数组来处理。
其实,真正的答案是什么并不重要,重要的是里面的思路!
iambic 2007-01-10
  • 打赏
  • 举报
回复
to eidewood:
请注意stack的接口,对于list和vector来说,复杂度是一样的。而使用+/-操作总比new/delete开销要小。
htqx 2007-01-10
  • 打赏
  • 举报
回复
聪明一点的做法是new 原来的大小 + 一个适合的大小
OOPhaisky 2007-01-10
  • 打赏
  • 举报
回复
楼主可以去看看《STL源码剖析》
eidewood 2007-01-10
  • 打赏
  • 举报
回复
数组和链表是两种不同的数据结构体,不能说喜欢用什么就用什么,根据需要的情况使用,因为数组是在内存空间是连续分布,而链表不需要,所以在搜索的时候的复杂度有所不同。

如果你想用数组实现堆栈的某些功能,那么你需要定义一个比较大的数组,用+-1的方法来实现PUSH 和 POP。但是这样就浪费了数组最好的功能,就是直接根据INDEX得到需要的数据。

打个比方,吃牛杂串,你非要用个碗和一对筷子而不用竹签。你说那个更浪费?
jixingzhong 2007-01-10
  • 打赏
  • 举报
回复
动态数组实现的堆栈
/*_############################################################################
_##
_## 动态数组实现的堆栈
_## Author: xwlee
_## Time: 2006.12.31
_## Chang'an University
_## Development condition: win2003 Server+VC6.0
_##
_## dynamic_array.cpp 文件
_##########################################################################*/
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

static STACK_TYPE *stack;
static size_t stack_size;
static int top_element = -1;

// create_stack函数
int create_stack( size_t size )
{
if( stack_size != 0)
{
printf("stack already created.");
abort();
}
stack_size = size;
stack = ( STACK_TYPE *)malloc( stack_size * sizeof( STACK_TYPE ) );
if( stack == NULL)
{
printf("create stack false,please try again(size<max(size_t)). \n");
return 0;
}

return 1;
}

// destroy_stack函数
int destroy_stack( void )
{
if( stack_size == 0 )
{
printf("destroy stack false.\n");
return 0;
}
stack_size = 0;
free( stack );
stack = NULL;
return 1;
}

// push函数
void push( STACK_TYPE value )
{
if( is_full() ) // 若堆栈已满,条件成立.
{
printf("stack already full.\n");
exit(0);
}
top_element += 1;
stack[ top_element ] = value;
}

// pop函数
void pop( void )
{
if( is_empty() ) // 若堆栈已空,条件成立.
{
printf("stack already empty.\n");
exit(0);
}
top_element -= 1;
}

// top函数
STACK_TYPE top( void )
{
if( is_empty() ) // 若堆栈已空,条件成立.
{
printf("stack already empty.\n");
exit(0);
}
return stack[ top_element ];
}

// is_empty函数
int is_empty( void )
{
if( stack_size == 0 ) // 若堆栈空时.
{
printf("stack is empty,please create stack firstly.\n");
exit(0);
}
return top_element == -1;
}

// is_full函数
int is_full( void )
{
if( stack_size == 0 ) // 若堆栈空时.
{
printf("stack is empty,please create stack firstly.\n");
exit(0);
}
return top_element == (signed int)(stack_size - 1);
}

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1470068
jixingzhong 2007-01-10
  • 打赏
  • 举报
回复
明白 stack 的特性就可以了,
看 数据结构 啊,
至于底层用什么东东, 数组/动态数组,链表,自然是随意···
dx30611 2007-01-10
  • 打赏
  • 举报
回复
stl中的堆栈是用list或者vecter实现的,这两种方法是可选的。
v2002750 2007-01-10
  • 打赏
  • 举报
回复
你可以先分配一个比较大的数组,比如说100,栈头和栈尾都指向第一个元素。
push:
if(栈尾-栈头==100){//空间如何增大可以灵活决定
重新分配更大的空间;
拷贝元素;
}
栈尾上移一位;
在栈尾加入元素;
}

大致就是这样,STL中的栈也差不多这么实现。
taodm 2007-01-10
  • 打赏
  • 举报
回复
唉,有答案的C++ Primer不用,何苦呢。
stl的stack如何实现的,去找《stl源码剖析》一看便知。
zhousqy 2007-01-10
  • 打赏
  • 举报
回复
差不多是那樣了

65,203

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧