数据结构笔记三: 栈

1. 栈的基本概念

栈是限定只在表头进行插入(入栈)和删除(出栈)操作的线性表,表头端称为栈顶,表尾端称为栈底。
设有栈 S = ( a 1 , a 2 , , a n ) 则一般称 a 1 为栈底元素, a n 为栈顶元素,按 a 1 , a 2 , , a n 的顺序依次进栈,出栈的第一个元素为栈顶元素,也就是说栈是按照后进先出的原则进行。
栈的实现和线性表类似,有两种方法——顺序栈和链栈

2. 顺序栈

//.hpp文件
#pragma once

#define DEFAULT_SIZE 10


//顺序栈类
template<typename elemType>
class SqStack
{
private:
//顺序栈的数据成员
    int count;
    int maxSize;
    elemType* elems;

    //辅助函数
    bool Full() const; //判断栈是否已满
    void Init(int size);//对栈进行初始化

public:
//抽象数据类型方法声明及重载编译系统默认方法声明
    SqStack(int size = DEFAULT_SIZE);//构造函数
    virtual ~SqStack();//析构函数
    int getLength() const;//求栈的长度
    bool isEmpty() const;//判断栈是否为空
    void Clear();//清空栈
    void Traverse(void(*Visit)(elemType &));//遍历栈
    bool Push(const elemType &e);//入栈
    bool Top(elemType &e) const;//返回栈顶元素
    bool Pop(elemType &e);//出栈

    SqStack(SqStack<elemType> &copy);//复制构造函数
    SqStack<elemType>& operator=(SqStack<elemType> &copy);//赋值运算符重载

};

//顺序栈的实现
template<typename elemType>
bool SqStack<elemType>::Full() const
{
    return count == maxSize;
}

template<typename elemType>
void SqStack<elemType>::Init(int size)
{
    maxSize = size;
    if (elems != NULL) delete[] elems;
    elems = new elemType[maxSize];
    count = 0;
}

template<typename elemType>
SqStack<elemType>::SqStack(int size = DEFAULT_SIZE)
{
    elems = NULL;
    Init(size);
}

template<typename elemType>
SqStack<elemType>::~SqStack()
{
    if (elems != NULL) delete[] elems;
}

template<typename elemType>
int SqStack<elemType>::getLength() const
{
    return count;
}

template<typename elemType>
bool SqStack<elemType>::isEmpty() const
{
    return count == 0;
}

template<typename elemType>
void SqStack<elemType>::Clear()
{
    count = 0;
}

template<typename elemType>
void SqStack<elemType>::Traverse(void(*Visit)(elemType &))
{
    for (int curPosition = 1; curPosition <= this->getLength(); curPosition++)
    {
        (*Visit)(elems[curPosition - 1]);
    }
}

template<typename elemType>
bool SqStack<elemType>::Push(const elemType &e)
{
    if (Full())
    {
        return false;
    } 
    else
    {
        elems[count++] = e;
        return true;
    }
}

template<typename elemType>
bool SqStack<elemType>::Top(elemType &e) const
{
    if (isEmpty())
    {
        return false;
    } 
    else
    {
        e = elems[count - 1];
        return true;
    }
}

template<typename elemType>
bool SqStack<elemType>::Pop(elemType &e)
{
    if (isEmpty())
    {
        return false;
    } 
    else
    {
        e = elems[--count];
        return true;
    }
}

template<typename elemType>
SqStack<elemType>::SqStack(SqStack<elemType> &copy)
{
    elems = NULL;
    Init(copy.maxSize);//这里为什么可以直接访问私有成员maxSize
    count = copy.getLength();
    for (int curPosition = 1; curPosition <= count; curPosition++)
    {
        elems[curPosition - 1] = copy.elems[curPosition - 1];
    }
}

template<typename elemType>
SqStack<elemType>& SqStack<elemType>::operator =(SqStack<elemType> &copy)
{
    if (&copy != this)
    {
        Init(copy.maxSize);
        count = copy.getLength();
        for (int curPosition = 1; curPosition <= count; curPosition++)
        {
            elems[curPosition - 1] = copy.elems[curPosition - 1];
        }
    }
    return *this;
}
//测试文件
#include <iostream>
#include "SqStack.hpp"

using namespace std;

template<typename elemType>
void Visit2(elemType &e)
{
    cout << e << endl;
}

int main(int argc, char* argv[])
{
    SqStack<int> mySqStack;
    mySqStack.Push(1);
    mySqStack.Push(2);
    mySqStack.Traverse(Visit2);//使用函数指针!!!

    SqStack<int> mySqStack1(mySqStack);
    mySqStack1.Traverse(Visit2);
    getchar();
    return 0;
}

3. 链表栈

在程序中同时使用多个栈的情形下,使用链式栈不但可以提高存储效率,同时还可以达到共享存储空间的目的。(如何达到共享存储空间的目的?)

//.hpp文件
#pragma once

//节点类
template<typename elemType>
struct Node
{
    //数据成员
    elemType data;//数据域
    Node<elemType>* next;//指针域

    //构造函数
    Node();//无参构造函数
    Node(elemType item, Node<elemType>* Link = NULL);//已知数据域和指针域建立结构
};

//节点类的实现部分
template<typename elemType>
Node<elemType>::Node()
//操作结果:构造指针域为空的节点
{
    this->next = NULL;
}

template<typename elemType>
Node<elemType>::Node(elemType item, Node<elemType>* Link)
//操作结果:构造数据域为item指针域为Link的节点
{
    this->data = item;
    this->next = Link;
}


//链栈类
template<typename elemType>
class LinkStack
{
private:
    //链栈实现的数据成员
    Node<elemType>* top;//栈顶指针

    //辅助函数
    void Init();//初始化栈

public:
    //抽象数据类型方法声明及重载编译系统默认方法声明
    LinkStack();//无参构造函数
    virtual ~LinkStack();//析构函数
    int getLength() const;//获取栈的长度
    bool isEmpty() const;//判断栈是否为空
    void Clear();//将栈清空
    void Traverse(void(*Visit)(elemType &e));//遍历栈
    bool Push(const elemType & e);//入栈
    bool Top(elemType& e) const;//返回栈顶的元素
    bool Pop(elemType& e);//出栈

    LinkStack(LinkStack<elemType> & copy);//复制构造函数
    LinkStack<elemType>& operator=(LinkStack<elemType> & copy);//重载赋值运算符
};


//链栈类的实现
template<typename elemType>
void LinkStack<elemType>::Init()
//对链栈进行初始化,外部不可调用
{
    top = NULL;
}

template<typename elemType>
LinkStack<elemType>::LinkStack()
{
    Init();
}

template<typename elemType>
LinkStack<elemType>::~LinkStack()
{
    Clear();
}

template<typename elemType>
int LinkStack<elemType>::getLength() const
{
    int count = 0;
    for (Node<elemType>* curPosition = top; curPosition != NULL; curPosition = curPosition->next)
    {
        count++;
    }
    return count;
}

template<typename elemType>
bool LinkStack<elemType>::isEmpty() const
{
    return top == NULL;
}

template<typename elemType>
void LinkStack<elemType>::Clear()
{
    elemType e;
    while (top != NULL)
    {
        Pop(e);//删除链表元素的技巧
    }
}

template<typename elemType>
void LinkStack<elemType>::Traverse(void(*Visit)(elemType &e))
{
    for (Node<elemType>* curPosition = top; curPosition != NULL; curPosition = curPosition->next)
    {
        (*Visit)(curPosition->data);
    }
}

template<typename elemType>
bool LinkStack<elemType>::Push(const elemType & e)
{

    Node<elemType>* tempNode = top;
    top = new Node < elemType > ;
    if (top == NULL)//如果动态内存耗尽
    {
        return false;
    }
    top->data = e;
    top->next = tempNode;
    return true;
}

template<typename elemType>
bool LinkStack<elemType>::Top(elemType& e) const
{
    if (isEmpty())
    {
        return false;
    }
    else
    {
        e = top->data;
        return true;
    }
}

template<typename elemType>
bool LinkStack<elemType>::Pop(elemType& e)
{
    if (isEmpty())
    {
        return false;
    } 
    else
    {
        e = top->data;
        Node<elemType>* tempPtr = top;
        top = top->next;
        delete tempPtr;
        return true;
    }
}

template<typename elemType>
LinkStack<elemType>::LinkStack(LinkStack<elemType> & copy)
{
    if (copy.isEmpty())
    {
        Init();
    }
    else
    {
        top = new Node<elemType>(copy.top->data);
        Node<elemType>* tempPtr = top;
        for (Node<elemType>* curPosition = copy.top->next; curPosition != NULL; curPosition = curPosition->next)
        {
            tempPtr->next = new Node<elemType>(curPosition->data);
            tempPtr = tempPtr->next;
        }

    }
}

template<typename elemType>
LinkStack<elemType>& LinkStack<elemType>::operator=(LinkStack<elemType> & copy)
{
    if (&copy != this)
    {
        if (copy.isEmpty())
        {
            Init();
        }
        else
        {
            Clear();
            top = new Node<elemType>(copy.top->data);
            Node<elemType>* tempPtr = top;
            for (Node<elemType>* curPosition = copy.top->next; curPosition != NULL; curPosition = curPosition->data)
            {
                tempPtr->next = new Node<elemType>(copy.top->data);
                tempPtr = tempPtr->next;
            }
        }
    }
    return *this;
}
//测试文件
#include "LinkStack.hpp"
#include <iostream>

using namespace std;
template<typename elemType>
void Visit2(elemType &e)
{
    cout << e << endl;
}

int main(int argc, char* argv[])
{
    LinkStack<int> myLinkStack;
    using namespace std;

    myLinkStack.Push(1);
    myLinkStack.Push(2);
    myLinkStack.Push(3);
    myLinkStack.Traverse(Visit2);//使用函数指针!!!

    LinkStack<int> mySqStack1(myLinkStack);
    mySqStack1.Traverse(Visit2);

    getchar();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wuye999/article/details/79485431
今日推荐