栈及栈的C++实现

栈:栈是一种数据结构,栈里元素的添加和删除只能在栈的末端进行。它是一种“后进先出”(LIFO)的数据结构。

栈的操作:

initializeStack:初始化栈,使得为一个空栈。

destroyStack:清空栈里所有的元素,使得为一个空栈。

isEmptyStack:判断栈是否为空,如果为空,返回true,否则返回false。

isFullStack  : 判断栈是否溢出,如果溢出,返回true,否则返回false。

push : 添加一个新的元素到栈顶。前提是栈存在,且栈没有溢出。

top  : 返回栈顶元素。前提是栈存在,且栈没有溢出。

pop  : 删除栈顶元素。前提是栈存在,且栈不为空。

栈的实现可以用数组和链表两种类型来实现。

1.用数组来实现栈:

因为栈里所有的元素都是同一数据类型,所以可以用数组来实现一个栈。栈的第一个元素放在数组的第一个位置,栈的第二个元素放在数组的第二个位置,以此类推。

为了跟踪数组的top position ,我们声明另一个变量stackTop.

下面的类stackType定义了一个栈为ADT。

template<class Type> class stackType
{
public:
    const stackType<Type>& operator=(const stackType<Type>&);//重载赋值运算符
    void initializeStack();
    //Function to initialize the stack to an empty state
    //precondition:stackTop=0
    bool isEmptyStack() const;
    //Function to determine whether the stack is empty
    //postcondition:Returns true if the stack is
    //              empty,otherwise returns false
    bool isFullStack() const;
    //Function to determine whether the stack is full
    //postcondition:Returns true if the stack is full
    //              otherwise returns false
    void destroyStack();
    //Function to remove all the elements from the stack
    //Postcondition: stackTop = 0.
    void push(const Type& newItem);
    //Function to add newItem to the stack.
    //precondition:The stack exists and is not full
    //postcondition:the stack is changed and newItem is
    //              added to the top of the stack.
    Type top() const;
    //Function to return the top element of the stack.
    //precondition:the stack exists and is not empty.
    //postcondition:If the stack is empty,the program
    //              terminates;otherwise ,the top element
    //              of the stack is returned.
    void pop();
    //Function to remove the top element of the stack.
    //precondition:The stack exists and is not empty.
    //postcondition:The stack is changed and the top
    //              element  is removed from the stack.
    stackType(int stackSize = 100);
    //constructor
    //Create an array of the size stackSize to hold the
    //stack elements.the default stack size is 100.
    //Postcondition:The variable list contains the base
    //address of the array,stackTop=0,
    //and maxStackSize =stackSize.
    stackType(const stackType<Type>&otherStack);
    //copy constructor
    ~stackType();
    //desturctor;
    //Remove all the elements from the stack.
    //Postcondition:The array (list)holding the stack
    //elements is deleted.

private:
    int maxStackSize;//variable to store the maximum
                    //stack size.
    int stackTop;//variable to point to the top of the
                //stack
    Type *list;//pointer to the array that holds the stack
                //elements

    void copyStack(const stackType<Type>& otherStack);
    //Function to make a copy of otherStack.
    //Postcondition:A copy of otherStack is created and
    //assigned to this stack.
};

定义栈的初始化函数:

template <class Type>
void stackType<Type>::initializeStack()
{
    stackTop = 0;
}

定义Destroy Stack函数:

在用数组实现的栈的过程中,销毁栈的操作和初始化栈操作相似。如果我们把stackTop=0,所有栈元素就被销毁了,尽管元素仍然在栈里,但是stackTop的值表明栈是否为空。

template <class Type>
void stackType<Type>::destroyStack()
{
    stackTop = 0;
}

定义Empty Stack函数

既然stackTop的值决定栈是否为空,如果stackTop = 0,则栈为空,否则栈不为空。

template <class Type>
bool stackType<Type>::isEmptyStack() const
{
    return (stackTop == 0);
}

定义Full Stack函数:

如果stackTop = maxStackSize,栈满。

template<class Type>
bool stackType<Type>::isFullStack() const
{
    return (stackTop == maxStackSize);
}

定义入栈函数:push函数

template<class Type>
void stackType<Type>::push(const Type &newItem)
{
    if (!isFullStack()) {
        list[stackTop]=newItem;
        stackTop++;
    }
    else
       cout<<"Cannot add to a full stack."<<endl;

}

定义top函数:return the top element

template<class Type >
Type stackType<Type>::top() const
{
    assert(stackTop !=0);//if the stack is empty,
                        //terminate the program.
    return list[stackTop-1];
}

定义pop函数

template<class Type >
void stackType<Type >::pop()
{
    if(!isEmptyStack())
        stackTop--;
    else
        cout<<"Cannot remove from an empty stack,"<<endl;
}//end pop

定义Copy Stack 函数:

template<class Type >
void stackType<Type>::copyStack(const stackType<Type> &otherStack)
{
    delete [] list;
    maxStackSize = otherStack.maxStackSize;
    stackTop = otherStack.stackTop;

    list = new Type(maxStackSize);
    assert(list != NULL );

    //copy otherStack into this stack.
    for(int j=0;j<stackTop;j++)
        list[j] = otherStack.list[j];
}//end copyStack

定义Constructor和Destructor函数:

//constructor
template<class Type >
stackType<Type>::stackType(int stackSize)
{
    if(stackSize <= 0)
    {
        cout<<"The size of the array to hold the stack"  <<"must be positive"<<endl;
        cout<<"Creating an array of size 100"<<endl;
        maxStackSize = 100;
    }
    else
        maxStackSize = stackSize;
    stackTop=0;
    list=new Type[maxStackSize];

    assert(list != NULL);
}//end constructor
template <class Type >
stackType<Type>::~stackType<Type>()
{
    delete [] list;//deallocate memory occupied
                    //by the array.
}

定义Copy Constructor

template<class Type >
stackType<Type>::stackType(const stackType<Type>& otherStack)
{
    list = NULL;

    copyStack(otherStack);
}//end copy constructor

重载运算符(=)

template<class Type >
const stackType<Type>& stackType<Type>::operator=(const stackType<Type> & otherStack)
{
    if(this != &otherStack)//avoid self-copy
        copyStack(otherStack);

    return *this;
}//end operator =

2.用链表实现栈

因为数组的大小是固定的,所以用数组实现的栈的元素数量是固定的。当入栈元素数量超过数组大小,程序就会终止。所以我们用链表来克服这个问题。

下面定义一个链表栈的ADT:

template<class Type>
struct nodeType
{
    Type info;
    nodeType<Type> *link;
};
template<class Type>
class linkedStackType
{
public:
    const linkedStackType<Type>& operator=(const linkedStackType<Type>&);
    void initializeStack();
    bool isEmptyStack();
    bool isFullStack();
    void destroyStack();
    void push(const Type& newItem);
    Type top() const;
    void pop();

    linkedStackType();
    linkedStackType(const linkedStackType<Type>& otherStack);
    ~linkedStack();
private:
    nodeType<Type> *stackTop;

    void copyStack(const linkedStackType<Type>& otherStack);
};

说明:链表实现的栈在存储元素时,内存是动态分配的,因此栈不会满。只有当内存满了栈才会满,因此不需要用isFullStack来判断栈是否满。为了和数组实现的栈保持一致,链表实现的栈也包含了这个操作。

对链表实现的栈的基本操作:

默认构造函数(default constructor)

//default constructor
template <class Type>
linkedStackType<Type>::linkedStackType()
{
    stackTop = NULL;
}

销毁函数(destroy stack)

在数组里只需将stackTop设为0即可,但是在链表中,由于数据存储是动态的,所以需要把stackTop设置为NULL,然后释放栈元素占用的内存空间。

template<class Type>
void linkedStackType<Type>::destroyStack()
{
    nodeType<Type> *temp;
    while (stackTop!=NULL) {
        temp = stackTop;
        stackTop = stackTop->link;
        delete temp;
    }

初始化栈:(initializeStack)

初始化操作是将栈重新初始化为空的状态。

template<class Type>
void linkedStackType<Type>::initializeStack()
{
    destroyStack();
}

判断栈是否为空和判断栈是否满:

template<class Type>
bool linkedStackType<Type>::isEmptyStack() const
{
    return(stackTop==NULL);
}

template<class Type>
bool linkedStackType<Type>::isFullStack() const
{
    return false;
}

接下来是入栈操作push:

template<class Type>
void linkedStackType<Type>::push(const Type&newItem)
{
    nodeType<Type> *newNode;
    newNode = new nodeType<Type>;//create the new node
    assert(newNode !=NULL);

    newNode->info=newItem;
    newNode->link=stackTop;
    stackTop=newNode;
}

返回栈顶元素(Return the Top element )

template <class Type>
Type linkedStackType<Type>::top()const
{
    assert(stackTop != NULL);
    return(stackTop->info);
}//end top

出栈操作:pop

template <class Type>
void linkedStackType<Type>::pop()
{
    nodeType <Type> *temp;
    if (stackTop != NULL) {
        temp = stackTop;
        stackTop=stackTop->link;
        delete temp;
    }
    else
        cout<<"cannot remove from an empty stack"<<endl;

}

复制栈操作:

template<class Type>
void linkedStackType<Type>::copyStack(const linkedStackType<Type>& otherStack)
{
    nodeType<Type> *newNode,*current,*last;
    if(stackTop != NULL)
        destroyStack();
    if(otherStack.stackTop == NULL)
        stackTop=NULL;
    else
    {
        current = otherStack.stackTop;
        stackTop = new nodeType<Type>;
        assert(stackTop!=NULL);

        stackTop->info = current->info;
        stackTop->link=NULL;

        last = stackTop;
        current=current->link;

        while (current!=NULL) {
            newNode = new nodeType<Type>;
            assert(newNode != NULL);

            newNode->info = current->info;
            newNode->link = NULL;
            last->link = newNode;
            last = newNode;
            current = current->link;
        }//end while
    }//end else
}

构造函数和解析函数:

template <class Type>
linkedStackType<Type>::linkedStackType(const linkedStackType<Type>& otherStack)
{
    stackTop = NULL;
    copyStack(otherStack);
}

template<class Type>
linkedStackType<Type>::~linkedStackType()
{

    destroyStack();
}

重载赋值运算符(=)

template<class Type>
const linkedStackType<Type>& linkedStackType<Type>::operator =(const linkedStackType<Type>& otherStack)
{
    if(this != &otherStack)
        copyStack(otherStack);
    return *this;
}//end operator =

说明:

linkedStackType<int > stack;

这个语句声明了一个类型为linkedStackType的对象,并且这个stack里的元素类型为int型

比如:linkedStackType<stirng > stringStack;

这个语句声明了一个类型为linkedStackType的对象,并且这个stringStack里的元素类型为string型

时间: 2024-10-18 12:56:56

栈及栈的C++实现的相关文章

C++中栈的出栈,入栈规则:A,B,C,D,E

考题: 栈底至栈顶一次存放元素 ABCD 在第五个元素E入栈之前  栈中元素可以出栈,则出栈序列可能是_____a d___________. a.  ABCED b.  DBCEA   c.  CDABE   d.  DCBEA 分析: 1.假定进栈序列是从小到大排练的(即A<B<C<D<E),则出栈序列中不可能有  “大小中”这种序列,因为在“大数”出栈后,在栈中“中数”是在“小数”上面的,所以只能是先出“中数”再出“小数”2.出栈序列中如包含下列序列则是错误的:CAB,DAB

栈1--出栈序列

栈1--出栈序列 一.心得 二.题目及分析 进栈序列是123,求所有的出栈序列 用回溯法做 三.代码及结果 1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 5 stack<int> sta; 6 int ans[4]; 7 int total=0; 8 9 void print(){ 10 total++; 11 cout<<total<<": &quo

压栈出栈遍历栈实例代码

#include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef struct Node//定义一个链表结构体 { int data; struct Node* pNext; }NODE,*PNODE; typedef struct Stack//定义一个栈结构体 { PNODE pTop; PNODE pBottom; }STACK,*PSTACK; void initStack(PSTACK); void

栈及栈的链式存储结构(栈链)

栈:线性结构,后进先出.栈(Stack)是一种特殊的线性表(顺序表,链表)只在表尾进行删除和插入操作. 注意:对于栈来说,表尾称为栈的栈顶(top),表头称为栈底(bottom). 栈也是线性结构的一种特例.与队列不同,他只有一个口,只能从这里读或者写数据,这个口称为栈顶(top).栈是一种先进后出的数据结构.先进来的元素会放入栈底,而后进来的元素被放在它的上面,最后进来的元素的上面的位置,称为栈顶. 栈所提供的操作比一般的线性表要少很多,只提供:初始化.销毁.判断是否为空.求栈的长度.清空栈.

顺序栈——双栈(Dual Stack)

顺序栈--双栈(Dual Stack) 1. 双栈的概念 1.1 双栈的定义 双栈是指两个顺序栈,是一种特殊的顺序栈. 1.2 双栈中各元素的逻辑及存储关系 双栈共享一个地址连续的存储单元.即程序同时需要两个栈时,可以定义一个足够的栈空间,该空间的两端分别设为两个栈的栈底,用bottom[0]=-1和bottom[1]=maxSize指示. 压入数据时,让两个栈的栈顶top[0]和top[1]都向中间伸展,如果指示栈顶的指针top[0]+1等于另一个栈顶的指针top[1]时两栈已满. 每次进栈时

ACM/ICPC 之 用双向链表 or 模拟栈 解“栈混洗”问题-火车调度(Tshing Hua OJ - Train)

本篇用双向链表和模拟栈混洗过程两种解答方式具体解答“栈混洗”的应用问题 有关栈混洗的定义和解释在此篇:手记-栈与队列相关 列车调度(Train) Description Figure 1 shows the structure of a station for train dispatching. Figure 1 In this station, A is the entrance for each train and B is the exit. S is the transfer end.

顺序栈的初始化入栈出栈以及打印栈的信息

使用的开发工具CLion CLion 2017.2.1 Build #CL-172.3544.40, built on August 2, 2017Licensed to CLion EvaluatorExpiration date: September 15, 2017JRE: 1.8.0_152-release-915-b6 x86_64JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.oMac OS X 10.12.4   1 #include

07.栈(一)栈的存储结构及操作

一.栈 1.栈(stack):是限定仅在表尾进行插入和删除操作的线性表.其中,允许插入和删除的一端被称为栈顶(top),另一端被称为栈底(bottom),不含任何数据元素的栈被称为空栈.栈又被称为后进先出(Last In First Out)的线性表,简称LIFO结构. 栈的插入操作为进栈,栈的删除操作为出栈. 2.栈的抽象数据类型 ADT 栈(stack) Data 同线性表.元素具有相同类型,相邻元素具有前驱和后继关系. Operation InitStack(*S):初始化操作,建立一个空

堆是堆,栈归栈

堆是堆,栈归栈 在阅读以下内容之前,请了解一下几点: 第一:坚决澄清:堆是堆,栈归栈. 第二:曾经的“堆栈”再不允许重谈,简直就是扯淡! 第三:下面内容均属于从内存分配角度的阐述,不要与数据结构混淆. [1]程序的内存分配 (1)内存分配详解 一个由C/C++编译的程序占用的内存分为以下几个部分 <1>栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等. <2>堆区(heap) — 一般由程序员设计分配及释放,若程序员不释放,程序结束时可能由OS回收.可能