版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012736685/article/details/83055168
前言
应用:浏览器的前进、后退功能
一、栈的概述
栈(stack)是限定仅在表尾(栈顶)进行插入和删除操作的线性表。
栈顶(top):允许插入和删除的一端,另一端成为栈底(bottom)
后进先出(Last In First Out,LIFO),先进后出
==》只允许在一端插入和删除数据。
栈主要包含两个操作:进栈和出栈 ,也就是在栈顶插入一个数据和从栈顶删除一个数据。
其中,入栈也称压栈、入栈;出栈也称弹栈。
二、C++栈的方法
- push()——向栈内压入一个成员;
- pop()——从栈顶弹出一个成员;
- empty()——如果栈为空返回true,否则返回false;
- top()——返回栈顶,但不删除成员;
- size()——返回栈内元素的大小;
#include<iostream>
#include<stack>
using namespace std;
int main()
{
stack <int>stk;
//入栈
for(int i = 0; i < 50; i++)
{
stk.push(i);
}
cout<<"栈的大小:"<<stk.size()<<endl;
while(!stk.empty())
{
cout<<stk.top()<<endl;
stk.pop();
}
cout<<"栈的大小:"<<stk.size()<<endl;
return 0;
}
三、造轮子
栈可以用数组来实现,也可以用链表来实现
1、基于数组的实现
用到c++中的模板类(template)
#include <iostream>
#include <stdlib.h>
using namespace std;
#define MAXSIZE 0xffff
// 类模板声明的写法
// template <class T> class 类名{};
template<class type>
class my_stack
{
int top;
type* my_s;
int maxsize;
public:
// 构造函数,创建默认大小的栈
my_stack():top(-1),maxsize(MAXSIZE)
{
my_s = new type[maxsize];
if(my_s==NULL)
{
// 输出到标准错误的ostream对象,常用于程序错误信息;
// 默认情况下被关联到标准输出流,但它不被缓冲,
// 也就说错误消息可以直接发送到显示器,而无需等到缓冲区或者新的换行符时,才被显示
cerr<<"动态存储分配失败!"<<endl;
exit(1);
}
}
// 构造函数,创建指定大小的栈
my_stack(int size):top(-1),maxsize(size)
{
my_s = new type[size];
if(my_s == NULL)
{
cerr<<"动态存储分配失败!"<<endl;
exit(1);
}
}
// 析构函数
~my_stack()
{
delete[] my_s;
}
// 判断栈是否为空
bool Empty();
// 压栈
void Push(type tp);
// 返回栈顶元素
type Top();
// 出栈
void Pop();
// 栈的大小
int Size();
};
template<class type>
bool my_stack<type>::Empty()
{
if(top == -1)
return true;
else
return false;
}
template<class type>
void my_stack<type>::Push(type tp)
{
if(top+1 < maxsize)
{
my_s[++top]=tp;
}
else {
cout<<"满栈"<<endl;
exit(1);
}
}
template<class type>
type my_stack<type>::Top()
{
if(top != -1)
return my_s[top];
else
{
cout<<"空栈"<<endl;
exit(1);
}
}
template<class type>
void my_stack<type>::Pop()
{
if(top >= 0)
{
top--;
}
else
{
cout<<"空栈"<<endl;
exit(1);
}
}
template<class type>
int my_stack<type>::Size()
{
return top+1;
}
// 对比测试程序
int main(int argc, char *argv[])
{
my_stack<int> stk;
for(int i=0; i<50; i++)
{
stk.Push(i);
}
cout<<"栈的大小:"<<sizeof(stk)<<endl;
w/hile(!stk.Empty())
{
cout<<stk.Top()<<endl;
stk.Pop();
}
cout<<"栈的大小:"<<sizeof(stk)<<endl;
return 0;
}
2、基于链表的实现
用到c++中的模板类(template)
#include <iostream>
using namespace std;
template<class T> class LinkedListStack
{
public:
LinkedListStack();
~LinkedListStack();
// 入栈
void Push(const T & data);
// 只返回栈顶元素,但不删除栈顶元素
T Top();
// 出栈
T Pop();
// 返回栈的大小
int size() const;
private:
// 存放栈的大小,因为单链表所以这里不规定栈的最大可承载量
int count;
struct LinkedNode
{
T data;
LinkedNode * next;
};
LinkedNode * head; //单链表的头指针,不带头结点
};
// 构造函数
template<class T> LinkedListStack<T>::LinkedListStack()
{
this->count = 0;
this->head = new LinkedNode;
this->head->next = NULL;
}
// 析构函数,清空栈
template<class T> LinkedListStack<T>::~LinkedListStack()
{
LinkedNode *ptr, *temp;
ptr = head;
while (ptr->next != NULL) {
temp = ptr->next;
ptr->next = temp->next;
delete temp;
}
delete head;//删除头结点
this->head = NULL;
this->count = 0;
}
// 入栈
template<class T> void LinkedListStack<T>::Push(const T &data)
{
LinkedNode * insertPtr = new LinkedNode;
insertPtr->data = data;
insertPtr->next = this->head->next;
head->next = insertPtr;
this->count++;
cout<<"Push data:"<<this->head->next->data<<endl;
}
// 返回栈顶元素,即出栈,但不删除栈顶元素
template<class T> T LinkedListStack<T>::Top()
{
if(this->count == 0 || this->head->next == NULL)
{
cout<<"Stack is empty, Top fail"<<endl;
return NULL;
}
else {
LinkedNode * temp = this->head->next;
T data = temp->data;
return data;
}
}
// 出栈
template<class T> T LinkedListStack<T>::Pop()
{
if(this->count == 0 || this->head->next == NULL)
{
cout<<"stack is empty, Pop is fail"<<endl;
return NULL;
}
else {
LinkedNode * temp = this->head->next;
this->head->next = temp->next;
T data = temp->data;
delete temp;
this->count--;
return data;
}
}
// 返回栈的大小
template<class T> int LinkedListStack<T>::size() const
{
return this->count;
}
int main(int argc, char *argv[])
{
cout << " === StackBasedOnLinkedList test begin ===" << endl;
LinkedListStack <float> stack;
cout << "size==="<<stack.size()<<endl;
stack.Push(10.1);
stack.Push(20.2);
stack.Push(30.);
stack.Push(40.4);
stack.Push(50.5);
stack.Push(60.6);
cout << "size==="<<stack.size()<<endl;
cout << "stack Top " << stack.Top() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "size==="<<stack.size()<<endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "size==="<<stack.size()<<endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Top " << stack.Top() << endl;
stack.Push(110.1);
stack.Push(120.2);
stack.Push(130.3);
stack.Push(140.4);
stack.Push(150.5);
stack.Push(160.6);
cout << "size==="<<stack.size()<<endl;
cout << "stack Top " << stack.Top() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Top " << stack.Top() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "stack Pop " << stack.Pop() << endl;
cout << "size==="<<stack.size()<<endl;
cout << "stack Top " << stack.Top() << endl;
cout << "stack Pop " << stack.Pop() << endl;
system("pause");
return 0;
}