数据结构-顺序栈和链栈

一、栈

1. stack 基本概念

概念:stack是一种先进后出的数据结构,它只有一个出口。

栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为

栈中进入数据称为 — 入栈 push

栈中弹出数据称为 — 出栈 pop

二、顺序栈

顺序栈是使用数组存储方式的栈

1.结构模型图

QQ拼音截图20220526233255

2.顺序栈的常用接口

功能描述:顺序栈容器常用的对外接口

构造函数:

  • seqStack<T> t; //seqStack采用模板类实现

数据存取:

  • push(elem); //向栈顶添加元素
  • pop(); //从栈顶移除第一个元素
  • getTop(); //返回栈顶元素

大小操作:

  • isEmpty(); //判断堆栈是否为空
  • isFull(); //判断堆栈是否已满
  • size(); //返回栈的大小
  • clear(); //清空

3.代码实现

seqStack.h

/**
 * @Author: lwj
 * @Date: 2022-05-25 23:33:43
 * @Description:数据结构---顺序栈
 * @FilePath: /Linux_C_C-plus-plus/数据结构(C++)/SeqStack.cpp
 **/
#pragma once //防止头文件重复包含
#include <iostream>
#include <assert.h>

#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 <iostream>
#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;
}

三、链栈

链栈是使用动态方式的存储,空间不连续。

1.结构模型图

QQ拼音截图20220526225311

2.链栈的常用接口

功能描述:链栈容器常用的对外接口

构造函数:

  • listStack<T> t; //listStack采用模板类实现

数据存取:

  • push(elem); //向栈顶添加元素
  • pop(); //从栈顶移除第一个元素
  • getTop(); //返回栈顶元素

大小操作:

  • isEmpty(); //判断堆栈是否为空
  • size(); //返回栈的大小
  • clear(); //清空

3.代码实现

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 <iostream>
#include <assert.h>
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;
}

四、总结

  • 栈可以有多种存储方式,它们都能实现栈的基本功能,但不同的存储方式都有自己的优缺点。

  • ​顺序栈因为是数组存储,所以我们使用的时候需要先定义数组的大小,我们大多数的时候都无法确定我们需要多少空间,导致我们往往都往大的开辟空间,导致许多空间的浪费,如果我们空间小了,还可能会发生数据溢出的可能。则它的优点是已实现,存储空间连续。

  • 链栈使用动态分配内存存储数据,不浪费内存,存储的数据不连续,在机器空间未满时,这样的存储方式是不存在数据溢出的问题。缺点就是所需的空间会比数组方式大一点。

  • 总的来说栈使用动态存储方式更好。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里狼~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值