数据结构笔记之用C++实现顺序栈和链式栈

这里介绍两种实现栈的方式:“顺序栈”和“链式栈”,各有各的优缺点。

不管是“顺序栈”还是“链式栈”,我们可以先定义一个栈的ADT(抽象数据类型),如下面的“stack.h”

#ifndef STACK_H
#define STACK_H
const int maxSize=50;

template 
class Stack{
public:
    Stack(){};
    virtual void Push(const T& x)=0;
    virtual bool Pop(T& x)=0;
    virtual bool getTop(T& x)const=0;
    virtual bool isEmpty()const=0;
    virtual bool isFull()const=0;
    virtual int getSize() const=0;
};
#endif
关于模版类“template”的使用可以参考网上的教程,这里定义了栈的几个基本操作:构造栈,进栈,退栈,获取栈顶元素,判断栈空,判断栈满,获取栈的元素个数 

1、“顺序栈”的实现

创建“seqstack.h”,并在里面实现顺序栈

/*
** 顺序栈的模板类及其成员函数的实现,创建“seqstack.h”
*/
#ifndef SEQSTACK_H
#define SEQSTACK_H

#include 
#include 
#include "stack.h"

using  namespace  std;

const int stackIncreament=20;
template <class T>
class SeqStack :public Stack{
public:
    /*
    ** 建立一个空栈
    */
    SeqStack(int sz=50);

    /*
    ** 析构函数
    */
    ~SeqStack(){delete[]elements;}

    /*
    ** 进栈
    */
    void Push(const T& x);

    /*
    ** 退栈
    */
    bool Pop(T& x);

    /*
    ** 获取栈顶元素
    */
    bool getTop(T& x)const;

    /*
    ** 判断栈是否为空
    */
    bool isEmpty()const {return(top == -1)?true:false;}

    /*
    ** 判断栈是否为满
    */
    bool isFull()const {return(top == maxSize-1)?true:false;}

    /*
    ** 获取栈的元素个数
    */
    int getSize()const {return top+1;}

    /*
    ** 清空栈
    */
    void MakeEmpty(){top=-1;}

    /*
    ** 输出栈中元素的重载操作<<
    */
    friend ostream& operator << (ostream& os,SeqStack& s);
private:
    /*
    ** 存放栈中元素的栈数组
    */
    T* elements;

    /*
    ** 栈顶元素
    */
    int top;

    /*
    ** 栈最大可容纳的元素个数
    */
    int maxSize;

    /*
    ** 栈溢出的处理
    */
    void overflowProcess();
};

//由于编译器的关系,模板类成员函数必须和申明在一个同一个“.h”文件里

template<class T>
SeqStack::SeqStack(int sz/* =50 */):top(-1),maxSize(sz){
    elements=new T[maxSize];
    assert(elements!=NULL);
};

template<class T>
void SeqStack::overflowProcess(){
    T * newArray = new T[maxSize+stackIncreament];
    if (newArray==NULL){cerr<<"add stack area failed!"<exit(1);}
    for (int i=0;i<=top;i++)
    {
        newArray[i]=elements[i];
    }
    maxSize=maxSize+stackIncreament;
    delete[]elements;
    elements=newArray;
};

template<class T>
void SeqStack::Push(const T& x){
    if (isFull()==true)
    {
        overflowProcess();
    }
    elements[++top]=x;
};

template<class T>
bool SeqStack::Pop(T& x)
{
    if (isEmpty()==true)
    {
        return false;
    }
    x=elements[top--];
    return true;
};

template<class T>
bool SeqStack::getTop(T& x)const
{
    if (isEmpty()==true)
    {
        return false;
    }
    x=elements[top];
    return true;
};

template<class T>
ostream& operator<<(ostream& os,SeqStack& s){
    os<<"top=="<for (int i=0;i<=s.top;i++)
    {
        os<":"<return os;
};
#endif

2、“链式栈”的实现

首先先定义一个结点结构体“LinkedList.h”

/*
** 单链表结点的结构体定义
*/
#ifndef LINKEDLIST_H
#define LINKEDLIST_H

template <class T>
struct LinkNode{
    /*
    ** 数据域
    */
    T data;

    /*
    ** 链指针域
    */
    LinkNode<T> *link;

    /*
    ** 仅初始化指针成员的构造函数
    */
    LinkNode(LinkNode<T> *ptr = NULL){link=ptr;}

    /*
    ** 初始化数据和指针成员的构造函数
    */
    LinkNode(const T& item,LinkNode<T> *ptr=NULL)
    {
        data=item;
        link=ptr;
    }
};
#endif

接着实现“链式栈”“LinkedStack.h”

/*
** 链式栈的模板类及其成员函数的实现
*/
#ifndef LINKEDSTACK_H
#define LINKEDSTACK_H

#include "LinkedList.h"
#include "stack.h"
#include "stdafx.h"
#include "seqstack.h"
#include 

template<class T>
class LinkedStack:public Stack{
public:
    /*
    ** 构造函数,置空栈
    */
    LinkedStack():top(NULL){};

    /*
    ** 析构函数
    */
    ~LinkedStack(){makeEmpty();};

    /*
    ** 进栈
    */
    void Push(const T& x);

    /*
    ** 退栈
    */
    bool Pop(T& x);

    /*
    ** 读取栈顶元素
    */
    bool getTop(T& x)const;

    /*
    ** 判断是否栈为空
    */
    bool isEmpty()const{return(top==NULL)?true:false;}

    /*
    ** 链式表不需要判断是否栈满,但必须将虚函数实例化,这里默认返回为true
    */
    bool isFull()const{return true;}

    /*
    ** 求栈的元素个数
    */
    int getSize()const;

    /*
    ** 清空栈
    */
    void makeEmpty();

    /*
    ** 输出栈中元素的重载操作<<
    */
    friend ostream& operator<<(ostream& os,SeqStack& s);

private:

    /*
    ** 栈顶指针,即链头指针
    */
    LinkNode *top;
};

template<class T>
void LinkedStack::makeEmpty(){
    LinkNode *p;
    while(top !=NULL)
    {
        p=top;
        top=top->link;
        delete p;
    }
};

template<class T>
bool LinkedStack::Pop(T& x)
{
    if (isEmpty()==true)
    {
        return false;
    }
    LinkNode *p=top;
    top=top->link;
    x=p->data;
    delete p;
    return true;
};

template<class T>
void LinkedStack::Push(const T& x){
    top=new LinkNode(x,top);
    assert(top !=NULL);
};

template<class T>
bool LinkedStack::getTop(T& x)const{
    if (isEmpty()==true)
    {
        return false;
    }
    x=top->data;
    return true;
};
template<class T>
int LinkedStack::getSize()const{
    int k=0;
    LinkNode *p=top;
    while (p !=NULL)
    {
        p=p->link;
        k++;
    }
    /*
    **一个成员函数声明为const,则这个成员函数不修改数据成员,这个书里面写错了
    */
    /*while (top !=NULL)
    {
        top=top->link;
        k++;
    }*/
    return k;
};
template<class T>
ostream& operator<<(ostream& os,LinkedStack& s){
    os<<"get stack size is"< *p=s.top;
    int i=0;
    while(p!=NULL)
    {
        os<<++i<<":"<data<link;
    }
    return os;
};
#endif

3、Main函数调用


#include "stdafx.h"
#include "seqstack.h"
#include "stack.h"
#include "LinkedStack.h"
#include "LinkedList.h"


void _tmain(int argc, _TCHAR* argv[])
{
    //申明一个int型的顺序栈
    SeqStack<int>inArray(maxSize);
    //申明一个int型的链式栈
    LinkedStack<int>linkArray;
    int seqtop,linktop;
    for (int i=0;i<50;i++)
    {
        //进栈
        inArray.Push(i);
        linkArray.Push(i);
        //获取栈顶元素,获取不会进行出栈操作,可以对比下面的Pop操作对比
        inArray.getTop(seqtop);
        linkArray.getTop(linktop);
        //输出栈顶元素
        cout<"  "<int size=inArray.getSize();
    cout<<"the seqstack current size is "<cout<<"the linkstack current size is "<//清空栈
    linkArray.makeEmpty();
    size=linkArray.getSize();
    cout<<"the linkstack current size is "<while(!inArray.isEmpty())
    {
        inArray.Pop(seqtop);
        //输出出栈元素,验证栈是“LIFO(后进先出)”
        cout<cout<<"the stack current size is "<//房子窗口退出
    cin>>size;
}

你可能感兴趣的:(C++)