概念:stack是一种先进后出的数据结构,它只有一个出口。
栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为
栈中进入数据称为 — 入栈 push
栈中弹出数据称为 — 出栈 pop
顺序栈是使用数组存储方式的栈
功能描述:顺序栈容器常用的对外接口
构造函数:
seqStack t;
//seqStack采用模板类实现数据存取:
push(elem);
//向栈顶添加元素pop();
//从栈顶移除第一个元素getTop();
//返回栈顶元素大小操作:
isEmpty();
//判断堆栈是否为空isFull();
//判断堆栈是否已满size();
//返回栈的大小clear()
; //清空seqStack.h
/**
* @Author: lwj
* @Date: 2022-05-25 23:33:43
* @Description:数据结构---顺序栈
* @FilePath: /Linux_C_C-plus-plus/数据结构(C++)/SeqStack.cpp
**/
#pragma once //防止头文件重复包含
#include
#include
#define DEFAULT_SIZE 10
template <typename Type>
class SeqStack
{
private:
Type *data; //维护空间指针
int count; //空间容量
int top; //顶端元素的下一个位置
public:
SeqStack(size_t sz); // size_t相当于无符号整数unsigned int
SeqStack(const SeqStack &t); //拷贝构造
SeqStack &operator=(const SeqStack &t); //等号重载
~SeqStack();
public:
bool isEmpty() const; //判空
bool isFull() const; //判满
void push(Type &s); //插入元素
void clear(); //清空
int size() const; //返回栈元素个数
Type getTop() const; //返回栈顶元素
Type pop(); //移除栈顶元素
};
template <typename Type>
SeqStack<Type>::SeqStack(size_t sz = 0)
{
this->count = sz != 0 ? sz : DEFAULT_SIZE; //判断sz是否被赋值,没有的就默认等于DEFAULT_SIZE
this->data = new Type[count]; //分配空间
this->top = 0;
}
template <typename Type>
SeqStack<Type>::~SeqStack()
{
delete[] data;
data = nullptr;
count = top = 0;
}
//判空
template <typename Type>
bool SeqStack<Type>::isEmpty() const
{
return top <= 0 ? true : false;
}
//判满
template <typename Type>
bool SeqStack<Type>::isFull() const
{
return top >= count ? true : false;
}
//插入元素
template <typename Type>
void SeqStack<Type>::push(Type &s)
{
assert(!isFull()); //断言,如果空间已满程序会报错,程序终止
data[top++] = s;
}
//插入元素
template <typename Type>
void SeqStack<Type>::clear()
{
delete[] data;
}
//返回栈元素个数
template <typename Type>
int SeqStack<Type>::size() const
{
return top;
}
//返回栈顶元素
template <typename Type>
Type SeqStack<Type>::getTop() const
{
assert(!isEmpty()); //断言,如果空间为空程序会报错,程序终止
return data[top - 1];
}
//移除栈顶元素
template <typename Type>
Type SeqStack<Type>::pop()
{
assert(!isEmpty()); //断言,如果空间为空程序会报错,程序终止
Type tmp = data[top--];
return tmp;
}
main.cpp
/**
* @Author: lwj
* @Date: 2022-05-26 10:35:59
* @Description:测试顺序栈功能
* @FilePath: /Linux_C_C-plus-plus/数据结构(C++)/SeqStack/main.cpp
**/
#include
#include "seqStack.h"
using namespace std;
int main(void)
{
SeqStack<int> s1(8); //指定s1的容量为8
for (int i = 0; i < 8; i++)
{
s1.push(i); //插入数据
}
cout << "s1的元素的个数:" << s1.size() << endl;
cout << "栈顶元素为:" << s1.getTop() << endl;
//移除栈顶元素
s1.pop();
cout << "栈顶元素为:" << s1.getTop() << endl;
return 0;
}
链栈是使用动态方式的存储,空间不连续。
功能描述:链栈容器常用的对外接口
构造函数:
listStack t;
//listStack采用模板类实现数据存取:
push(elem);
//向栈顶添加元素pop();
//从栈顶移除第一个元素getTop();
//返回栈顶元素大小操作:
isEmpty();
//判断堆栈是否为空size();
//返回栈的大小clear()
; //清空listStack.h
/**
* @Author: lwj
* @Date: 2022-05-26 23:37:52
* @Description:数据结构---链栈
* @FilePath: /Linux_C_C-plus-plus/数据结构(C++)/Stack/listStack/listStack.h
**/
#pragma once
#include
#include
template <typename Type>
class ListStack
{
private:
struct Node //将每个结点封装成一个结构体,结构体里包含data和next
{
public:
Type data; //所要存储的数据
Node *next; //指向下个结点的指针
Node() { next = nullptr; } //创建出的对象没初始化,则默认它next成员指向空指针
Node(const Type &value, Node *p = nullptr)
{
data = value;
next = p;
}
};
Node *top; //栈顶指针,指向栈顶
public:
ListStack() { top = nullptr; }
~ListStack() { clear(); }
public:
void clear(); //清空
bool isEmpty() const; //判空
int size() const; //返回元素个数
void push(const Type &elem); //插入数据
Type getTop() const; //返回栈顶元素
Type pop(); //移除栈顶元素
};
//清空
template <typename Type>
void ListStack<Type>::clear()
{
Node *tmp = nullptr;
tmp = top;
while (top)
{
tmp = top;
top = top->next;
delete tmp;
}
}
//判空
template <typename Type>
bool ListStack<Type>::isEmpty() const
{
return top->next == nullptr;
}
//返回回元素个数,也可以在类数据成员增加一个变量记录元素个数
//这样就不用遍历,达到用空间换时间的目的
template <typename Type>
int ListStack<Type>::size() const
{
Node *tmp = nullptr;
int count = 0;
tmp = top;
while (tmp)
{
count++;
tmp = tmp->next;
}
return count;
}
//插入数据
template <typename Type>
void ListStack<Type>::push(const Type &elem)
{
Node *tmp = new Node(elem, top);
top = tmp;
}
//返回栈顶元素
template <typename Type>
Type ListStack<Type>::getTop() const
{
return top->data;
}
//移除栈顶元素
template <typename Type>
Type ListStack<Type>::pop()
{
assert(!isEmpty()); //断言,如果栈为空程序会报错,程序终止
Node *tmp = nullptr;
tmp = top;
top = top->next;
return tmp->data;
}
main.cpp
/**
* @Author: lwj
* @Date: 2022-05-27 15:33:58
* @Description:测试链栈的功能
* @FilePath: /Linux_C_C-plus-plus/数据结构(C++)/Stack/listStack/main.cpp
**/
#include "listStack.h"
int main(void)
{
ListStack<int> L1;
for (int i = 0; i < 5; i++)
{
L1.push(i); //插入数据
}
std::cout << "栈元素个数为:" << L1.size() << std::endl;
std::cout << "栈顶元素为:" << L1.getTop() << std::endl;
std::cout << "移除栈顶元素后:" << L1.pop() << std::endl;
std::cout << "栈顶元素为:" << L1.getTop() << std::endl;
std::cout << "栈清空栈元素后:" << std::endl;
L1.clear();
std::cout << "栈元素个数为:" << L1.size() << std::endl;
std::cout << "栈为空时出栈:" << std::endl;
L1.pop();
return 0;
}
栈可以有多种存储方式,它们都能实现栈的基本功能,但不同的存储方式都有自己的优缺点。
顺序栈因为是数组存储,所以我们使用的时候需要先定义数组的大小,我们大多数的时候都无法确定我们需要多少空间,导致我们往往都往大的开辟空间,导致许多空间的浪费,如果我们空间小了,还可能会发生数据溢出的可能。则它的优点是已实现,存储空间连续。
链栈使用动态分配内存存储数据,不浪费内存,存储的数据不连续,在机器空间未满时,这样的存储方式是不存在数据溢出的问题。缺点就是所需的空间会比数组方式大一点。
总的来说栈使用动态存储方式更好。