这里我们通过C++实现一个顺序栈结构,内核是数组,但是需要遵循栈的规则,并包含初始化空栈,判断栈是否为空,判断栈是否已满,插入元素,删除元素,获取栈顶元素,具体操作如下所示:
堆栈的基本操作
size,以及栈顶元素指针 top。True。当堆栈不为空时,返回 False。一般只用于栈中删除操作和获取当前栈顶元素操作中。True,当堆栈未满时,返回 False。一般只用于顺序栈中插入元素和获取当前栈顶元素操作中。top 的指向位置。top 的指向位置。top 的指向位置。首先整体结构如下:
template
class Stack{public:Stack(int size); //有参构造Stack(Stack& sta); //拷贝构造~Stack();public:bool Empty(); //判空bool IsFull(); //判满void Push(T &value); //入栈void Push(T &&value); //常量入栈void Pop(); //出栈T Top(); //获取栈顶元素public:int size(){ return this->size_; };private://运算符重载T& operator[](int index) {return this->pAddr[index];}private:int size_;int capacity_; T* stack; //栈
};
如上图所示,这里定义了有参构造和拷贝构造,没定义默认构造,因为这样就涉及动态扩容,这里就不做实现。
然后是堆栈基础操作,判空,判满,入栈,出栈以及获取栈顶元素等操作。
最后还加了size(),和重载了[]运算符,一个共有,一个私有。
数据成员则有三个,分别是当前的元素个数、栈的容量以及栈指针。
接下来,我们看各自的实现。
template
Stack::Stack(int size):capacity_(size){this->size_ = 0;this->stack= new T[this->capacity_];
}template
Stack::~Stack(){if(this->stack!= NULL) delete[] this->stack;
}template
Stack::Stack(Stack& sta){//容量、大小赋值this->capacity_ = sta.capacity_;this->size_ = sta.size_;//申请空间this->stack= new T[this->capacity_];//数据拷贝for (int i = 0; i < this->size_; i++){this->stack[i] = sta.stack[i];}
}
上面三个分别为有参构造,拷贝构造和析构函数。
其中拷贝构造就用到了重载的[]运算符,不过该运算符是私有的,在实例化对象下是不可使用的,因为栈本身就只能索引。
template
bool Stack::Empty(){if(0 == this->size_) return true;return false;
}template
bool Stack::IsFull(){if(this->capacity_ == this->size_) return true;return false;
}
判空和判满的实现比较简单,主要以size_和capacity_来进行判断就可以了。
template
void Stack::Push(T &value){if(this->IsFull()){cout << "Stack is full"<this->stack[this->size_++] = value;}
}template
void Stack::Push(T&& value) {if(this->IsFull()){cout << "Stack is full"<this->stack[this->size_++] = value;}
}
之所以还需要重载一个Push函数,是因为不能对右值取引用
而解决办法就是使用&&,可以对右值取引用
template
void Stack::Pop(){if(this->Empty()){cout << "Stack is empty"<this->size_--;}
}
这里实现的是一个伪出栈,你只需要将size_这个索引-1,就能实现出栈。
template
T Stack::Top(){if(this->Empty()){cout << "Stack is empty"<stack[size_-1];
}
获取首部元素则只需要通过size_-1即可访问。
最后是测试代码
int main(void){Stack s(5);cout << s.Empty() < test(s); //测试拷贝构造函数while(!test.Empty()){cout << test.Top() << "\t";test.Pop();} cout< s_int(5);cout << s.Empty() <cout << s_int.Top() << "\t";s_int.Pop();} cout<
这里对于判满和判空还可以使用异常处理的方式进行,这里不做进一步的拓展。
老规矩,有用二连,感谢大家。
下一篇:去水印小程序