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

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

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

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

template <class T>
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 <assert.h>
#include <iostream>
#include "stack.h"

using  namespace  std;

const int stackIncreament=20;
template <class T>
class SeqStack :public Stack<T>{
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<T>& s);
private:
    /*
    ** 存放栈中元素的栈数组
    */
    T* elements;

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

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

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

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

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

template<class T>
void SeqStack<T>::overflowProcess(){
    T * newArray = new T[maxSize+stackIncreament];
    if (newArray==NULL){cerr<<"add stack area failed!"<<endl;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<T>::Push(const T& x){
    if (isFull()==true)
    {
        overflowProcess();
    }
    elements[++top]=x;
};

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

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

template<class T>
ostream& operator<<(ostream& os,SeqStack<T>& s){
    os<<"top=="<<s.top<<endl;
    for (int i=0;i<=s.top;i++)
    {
        os<<i<<":"<<s.elements[i]<<endl;
    }
    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 <iostream>

template<class T>
class LinkedStack:public Stack<T>{
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<T>& s);

private:

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

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

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

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

template<class T>
bool LinkedStack<T>::getTop(T& x)const{
    if (isEmpty()==true)
    {
        return false;
    }
    x=top->data;
    return true;
};
template<class T>
int LinkedStack<T>::getSize()const{
    int k=0;
    LinkNode<T> *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<T>& s){
    os<<"get stack size is"<<s.getSize()<<endl;
    LinkNode<T> *p=s.top;
    int i=0;
    while(p!=NULL)
    {
        os<<++i<<":"<<p->data<<endl;
        p=p->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<<seqtop<<"  "<<linktop<<endl;
    }
    int size=inArray.getSize();
    cout<<"the seqstack current size is "<<size<<endl;
    size=linkArray.getSize();
    cout<<"the linkstack current size is "<<size<<endl;
    //清空栈
    linkArray.makeEmpty();
    size=linkArray.getSize();
    cout<<"the linkstack current size is "<<size<<endl;
    while(!inArray.isEmpty())
    {
        inArray.Pop(seqtop);
        //输出出栈元素,验证栈是“LIFO(后进先出)”
        cout<<seqtop<<endl;
        cout<<"the stack current size is "<<inArray.getSize()<<endl;
    }
    //房子窗口退出
    cin>>size;
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值