首页 > 编程语言 >C++数据结构(栈)

C++数据结构(栈)

时间:2023-04-23 18:35:02浏览次数:38  
标签:SeqStack return top C++ bool template 数据结构 true

栈是一种受限的线性表,将允许插入和删除的操作的一端称为栈顶,另一端称之为栈底,向栈中插入元素叫入栈,删除元素叫出栈。栈被称为是后进先出的线性表(LIFO)

顺序栈

顺序存储,即使用一段连续内存空间依次存储栈中数据。这里通过一维数组动态分配内存的方式保存数据

定义

代码如下:

#define InitSize 10
#define IncSize 5

template <typename T>
class SeqStack {
public:
    SeqStack(int length = InitSize);
    ~SeqStack();

public:
    bool Push(const T& e);
    bool Pop(T &e);
    bool GetTop(T &e);

    void DispList();
    init ListLength();

    bool IsEmpty();
    bool IsFull();

private:
    void IncreaseSize();

private:
    T *m_data;
    int m_maxsize;
    int m_top;
};

template <typename T>
SeqStack<T>::SeqStack(int length) {
    m_data = new T[length];
    m_maxsize = length;
    m_top = -1;
}

template <typename T>
SeqStack<T>::~SeqStack() {
    delete[] m_data;
}

操作

template <typename T>
bool SeqStack<T>::Push(const T& e) {
    if (IsFull() == true) {
        IncreaseSize();
    }
    m_top++;
    m_data[m_top] = e;
    return true;
}

// 顺序栈扩容
template <typename T> 
void SeqStack<T>::IncreaseSize() {
    T *p = m_data;
    m_data = new T[m_maxsize + IncSize];

    // 将数据复制到新区域
    for (int i = 0; i <= m_top; i++) {
        m_data[i] = p[i];
    }
    m_maxsize = m_maxsize + IncSize;
    delete[] p;
}

// 出栈
template<typename T>
bool SeqStack<T>::Pop(T& e) {
    if (IsEmpty() == true) {
        std::cout << "Empty Stack" << std::endl;
        return false;
    }
    e = m_data[m_top];
    m_top--;
    return true;
}

template <typename T>
bool SeqStack<T>::GetTop(T &e) {
    if (IsEmpty() == true) {
        std::cout << "Empty Stack" << std::endl;
        return false;
    }
    e = m_data[m_top];
    return true;
}

template <class T>
void SeqStack<T>::DispList() {
    for (int i = m_top; i >= 0; i--) {
        std::cout << m_data[i] << " ";
    }
    std::cout << std::endl;
}

template <class T>
int SeqStack<T>::ListLength() {
    return m_top + 1;
}

template <class T>
bool SeqStack<T>::IsEmpty() {
    if (m_top == -1) {
        return true;
    }
    return false;
}

template <class T>
bool SeqStack<T>::IsFull() {
    if (m_top >= m_maxsize - 1) {
        return true;
    }
    return false;
}

共享栈

两个顺序栈共享存储空间为共享栈,对于顺序栈来说,一个较大的缺点是保存数据的空间初始尺寸不好确定,如果太大就会浪费空间,如果太小就得等存满数据后进行扩容

假设有两个相同数据类型的顺序栈,开辟一块保存数据的空间后,让这两个栈同时使用,也就是共享这块空间,就可以最大限度利用这块空间了

代码实现:

#include <iostream>

#define InitSize 10
#define IncSize 5

template <typename T>
class ShareStack {
public:
    ShareStack(int length = InitSize) {
        m_data = new T[length];
        m_maxsize = length;
        m_top1 = -1;
        m_top2 = length;
    }

    ~ShareStack() {
        delete[] m_data;
    }

public:
    bool IsFull() {
        if (m_top1 == m_top2) {
            return true;
        }
        return false;
    }

    bool Push(int stackNum,const T &e) {
        if (IsFull() == true) {
            std::cout << "Full Stack" << std::endl;
            return false;
        }
        if (stackNum == 1) {
            m_top1++;
            m_data[m_top1] = e;
        } else {
            m_top2--;
            m_data[m_top2] = e;
        }
        return true;
    }

    bool Pop(int stackNum,T &e) {
        if (stackNum == 1) {
            if (m_top1 == -1) {
                std::cout << "Share Stack 1 Empty" << std::endl;
                return false;
            }
            e = m_data[m_top1];
            m_top1--;
        } else {
            if (m_top2 == m_maxsize) {
                std::cout << "Share Stack 2 Empty" << std::endl;
                return false;
            }
            e = m_data[m_top2];
            m_top2++;
        }
        return true;
    }

private:
    T *m_data;
    int m_maxsize;
    int m_top1;
    int m_top2;
};

int main(void) {
    ShareStack<int> shareobj(10);
    shareobj.Push(1,150);
    shareobj.Push(2,200);

    int eval2 = 0;
    shareobj.Pop(1,eval2);
    shareobj.Pop(1,eval2);

    return 0;
}

链式栈

链式栈就是链式存储方式实现的栈,本质上是一个受限的单链表

#include <iostream>

template <typename T>
struct StackNode {
    T data;
    StackNode<T> *next;
};

template <typename T>
class LinkStack {
public:
    LinkStack();
    ~LinkStack();
public:
    bool Push(const T &e);
    bool Pop(T& e);
    bool GetTop(T &e);
    void DispList();
    int ListLength();
    bool Empty();

private:
    StackNode<T> *m_top;
    int m_length;
};

template <typename T>
LinkStack<T>::LinkStack() {
    m_top = nullptr;
    m_length = 0;
}

template <typename T>
bool LinkStack<T>::Push(const T &e) {
    StackNode<T> *node = new StackNode<T>;
    node->data = e;
    node->next = m_top;
    m_top = node;
    m_length++;
    return true;
}

template <typename T>
bool LinkStack<T>::Pop(T &e) {
    if (Empty() == true) {
        return false;
    }
    StackNode<T> *p_willdel = m_top;
    m_top = m_top->next;
    m_length--;
    e = p_willdel->data;
    delete p_willdel;
    return true;
}

template <typename T>
bool LinkStack<T>::GetTop(T &e) {
    if (Empty() == true) {
        return false;
    }
    e = m_top->data;
    return true;
}

template <class T>
void LinkStack<T>::DispList() {
    if (Empty() == true) {
        return;
    }

    StackNode<T> *p = m_top;
    while (p != nullptr) {
        std::cout << p->data << " ";
        p = p->next;
    }
    std::cout << std::endl;
}

template <class T>
int LinkStack<T>::ListLength() {
    return m_length;
}

template <class T>
bool LinkStack<T>::Empty() {
    if (m_top == nullptr) {
        return true;
    }
    return false;
}

template <typename T>
LinkStack<T>::~LinkStack() {
    T tmpnousevalue = {0};
    while (Pop(tmpnousevalue) == true) {}
}

int main(void) {
    LinkStack<int> slinkobj;
    slinkobj.Push(12);
    slinkobj.Push(24);
    slinkobj.Push(48);
    slinkobj.Push(100);

    int eval3 = 0;
    slinkobj.Pop(eval3);
    slinkobj.DispList();

    return 0;
}

链式栈没有长度限制,不存在内存空间的浪费问题。但对于数据的入栈和出栈这些需要对数据进行定位的操作,顺序栈更加方便,而链式栈中的每个数据节点都需要额外的指针域以指向下一个数据节点,这会略微降低数据的存储效率,当然也会多占用一些内存。所以,如果要存储的数据数量无法提前预估,一般考虑使用链式栈,而如果数据的数量比较固定,可以考虑使用顺序栈。

标签:SeqStack,return,top,C++,bool,template,数据结构,true
From: https://www.cnblogs.com/N3ptune/p/17347379.html

相关文章

  • 纯c++删除自身目录,和该目录下的所有内容______以及创建文件夹
    头文件.h#ifndefAUTODELETEADDFOLDER_H#defineAUTODELETEADDFOLDER_H#include<unistd.h>#include<stdlib.h>#include<errno.h>#include<dirent.h>#include<string.h>#include<iostream>#include<sys/stat.h>#inclu......
  • 解决 Visual C++ 17.5 __cplusplus 始终为 199711L 的问题
    00.软件环境VisualStudio2022,VisualC++,Version17.5.401.问题描述在应用https://github.com/ToniLipponen/cpp-sqlite的过程中,发现源代码文件sqlite.hpp中,有一处宏,和本项目的C++LanguageStandard有关,如下图所示:将鼠标悬停在__cplusplus这个宏上,可以看到它......
  • 【c&c++】std::string::npos的使用
    std::string::nposstd::string::npos是一个常数,它等于size_type类型可以表示的最大值,用来表示一个不存在的位置,类型一般是std::container_type::size_type。定义staticconstsize_typenpos=-1;#include<iostream>intmain(intargc,char*argv[]){size_ta=-1......
  • redis linux下安装 redis启动方式 redis典型场景 redis通用命令 数据结构和内部编码 r
    内容回顾#dockerfile命令 RUNCOPYADDENVEXPOSEWORKDIRCMD:可以用新命令覆盖的ENTRYPOINT:不可以被覆盖#容器要运行,必须有个前台进程#dockerfile部署图书管理系统项目 FROMpython:3.8MAINTAINERlqzWORKDIR/soft......
  • 第14届蓝桥杯C++B组省赛题解(更新中)
    目录A.日期统计题目内容思路代码答案B.01串的熵题目内容思路代码答案C.冶炼金属题目内容输入格式输出格式输入样例输出样例思路代码A.日期统计题目内容小蓝现在有一个长度为100的数组,数组中的每个元素的值都在0到9的范围之内。数组中的元素从左至右如下所示:5686......
  • C++管理堆上内存
    代码中如果有使用到堆上内存,必然涉及到内存的释放时机问题,有别于python的try...finally语法,C++中要实现类似的语法则显得比较困难,因此需要另辟蹊径,用栈内存的自动释放管理堆内存的释放。思路如下,用一个类包装好堆内存的分配(构造)和释放(析构),包装类在函数中调用时均为栈......
  • c++.12
    复习:  1、输出缓冲区    满足哪些条件会刷新输出缓冲区:    1、遇到'\n'    2、遇到输入语句    3、缓冲区满4k    4、程序正常结束    5、fflush(stdout)  2、输入缓冲区    1、当想要输入的是整型、......
  • c++ .11
    复习:  堆内存管理:    C语言没有管理堆内存的语句,只能使用标准库的函数    #include<stdlib.h>    void*malloc(size_tsize);    注意:void*在C++编译器中是不能自动转换成其它类型的指针,如果想让代码也在C++编译器中兼容,需要强制类......
  • c++.13
    预处理指令:  #define  常见笔试面试题:  1、简述#define与typedef的区别:    如果是普通类型,它们在功能上无任何区别,但本质不同,一个是代码替换,一个是类型重定义    #defineINTPint*      INTPp1,p2,p3; //p1是指针p2p3是int......
  • C与C++的区别(程序上)
    一.头文件上  1.为什么c++语言的头文件上可以使用"stdio.h"?  答:因为c++的标准库已经帮我们包含了c语言的标准库,因此c++也可以实现c语言能实现大多功能。例如"iostream"是c++的输入输出流头文件,"stdio.h"是c语言的输入输出流头文件,当在c++语言中调用"stdio.h"后便可以在c++......