棧及棧的C++實現

棧:棧是一種數據結構,棧裏元素的添加和刪除只能在棧的末端進行。它是一種「後進先出」(LIFO)的數據結構。node

棧的操做:數組

initializeStack:初始化棧,使得爲一個空棧。數據結構

destroyStack:清空棧裏全部的元素,使得爲一個空棧。函數

isEmptyStack:判斷棧是否爲空,若是爲空,返回true,不然返回false。post

isFullStack  : 判斷棧是否溢出,若是溢出,返回true,不然返回false。this

push : 添加一個新的元素到棧頂。前提是棧存在,且棧沒有溢出。spa

top  : 返回棧頂元素。前提是棧存在,且棧沒有溢出。code

pop  : 刪除棧頂元素。前提是棧存在,且棧不爲空。對象

 

棧的實現能夠用數組和鏈表兩種類型來實現。blog

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型

相關文章
相關標籤/搜索