四、栈

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012736685/article/details/83055168

前言

应用:浏览器的前进、后退功能

一、栈的概述

栈(stack)是限定仅在表尾(栈顶)进行插入和删除操作的线性表。
栈顶(top):允许插入和删除的一端,另一端成为栈底(bottom)

后进先出(Last In First Out,LIFO),先进后出
==》只允许在一端插入和删除数据。

栈主要包含两个操作:进栈和出栈 ,也就是在栈顶插入一个数据和从栈顶删除一个数据。
其中,入栈也称压栈、入栈;出栈也称弹栈。
在这里插入图片描述

二、C++栈的方法

  1. push()——向栈内压入一个成员;
  2. pop()——从栈顶弹出一个成员;
  3. empty()——如果栈为空返回true,否则返回false;
  4. top()——返回栈顶,但不删除成员;
  5. size()——返回栈内元素的大小;
#include<iostream>
#include<stack>
using namespace std;

int main()
{	
	stack <int>stk;
	//入栈
	for(int i = 0; i < 50; i++)
	{
		stk.push(i);
	}
	cout<<"栈的大小:"<<stk.size()<<endl;
	while(!stk.empty())
	{
		cout<<stk.top()<<endl;
		stk.pop();
	}
	cout<<"栈的大小:"<<stk.size()<<endl;
	return 0;
}

三、造轮子

栈可以用数组来实现,也可以用链表来实现

1、基于数组的实现

用到c++中的模板类(template)

#include <iostream>
#include <stdlib.h>
using namespace std;

#define MAXSIZE 0xffff

// 类模板声明的写法
// template <class T> class 类名{};
template<class type>
class my_stack
{
    int top;
    type* my_s;
    int maxsize;
    
public:
    // 构造函数,创建默认大小的栈
    my_stack():top(-1),maxsize(MAXSIZE)
    {
        my_s = new type[maxsize];
        if(my_s==NULL)
        {
            // 输出到标准错误的ostream对象,常用于程序错误信息;
            // 默认情况下被关联到标准输出流,但它不被缓冲,
            // 也就说错误消息可以直接发送到显示器,而无需等到缓冲区或者新的换行符时,才被显示
            cerr<<"动态存储分配失败!"<<endl;
            exit(1);
        }
    }
    // 构造函数,创建指定大小的栈
    my_stack(int size):top(-1),maxsize(size)
    {
        my_s = new type[size];
        if(my_s == NULL)
        {
            cerr<<"动态存储分配失败!"<<endl;
            exit(1);
         }
    }
    // 析构函数
    ~my_stack()
    {
        delete[] my_s;
    }

    // 判断栈是否为空
    bool Empty();
    // 压栈
    void Push(type tp);
    // 返回栈顶元素
    type Top();
    // 出栈
    void Pop();
    // 栈的大小
    int Size();
};

template<class type>
bool my_stack<type>::Empty()
{
    if(top == -1)
        return true;
    else
        return false;
}

template<class type>
void my_stack<type>::Push(type tp)
{
    if(top+1 < maxsize)
    {
        my_s[++top]=tp;
    }
    else {
        cout<<"满栈"<<endl;
        exit(1);
    }
}

template<class type>
type my_stack<type>::Top()
{
    if(top != -1)
        return my_s[top];
    else
    {
        cout<<"空栈"<<endl;
        exit(1);
    }
}

template<class type>
void my_stack<type>::Pop()
{
    if(top >= 0)
    {
        top--;
    }
    else
    {
        cout<<"空栈"<<endl;
        exit(1);
    }
}

template<class type>
int my_stack<type>::Size()
{
    return top+1;
}

// 对比测试程序
int main(int argc, char *argv[])
{
    my_stack<int> stk;
    for(int i=0; i<50; i++)
    {
        stk.Push(i);
    }
    cout<<"栈的大小:"<<sizeof(stk)<<endl;
    w/hile(!stk.Empty())
    {
        cout<<stk.Top()<<endl;
        stk.Pop();
    }
    cout<<"栈的大小:"<<sizeof(stk)<<endl;
    return 0;
}

2、基于链表的实现

用到c++中的模板类(template)

#include <iostream>
using namespace std;

template<class T> class LinkedListStack
{
public:
    LinkedListStack();
    ~LinkedListStack();
    
    // 入栈
    void Push(const T & data);
    // 只返回栈顶元素,但不删除栈顶元素
    T Top();
    // 出栈
    T Pop();
    // 返回栈的大小
    int size() const;

private:
    // 存放栈的大小,因为单链表所以这里不规定栈的最大可承载量
    int count;
    struct LinkedNode
    {
        T data;
        LinkedNode * next;
    };
    LinkedNode * head;  //单链表的头指针,不带头结点
};

// 构造函数
template<class T> LinkedListStack<T>::LinkedListStack()
{
    this->count = 0;
    this->head = new LinkedNode;
    this->head->next = NULL;
}

// 析构函数,清空栈
template<class T> LinkedListStack<T>::~LinkedListStack()
{
    LinkedNode *ptr, *temp;
    ptr = head;
    while (ptr->next != NULL) {
        temp = ptr->next;
        ptr->next = temp->next;
        delete temp;
    }
    delete head;//删除头结点
    this->head = NULL;
    this->count = 0;
}


// 入栈
template<class T> void LinkedListStack<T>::Push(const T &data)
{
    LinkedNode * insertPtr = new LinkedNode;
    insertPtr->data = data;
    insertPtr->next = this->head->next;
    head->next = insertPtr;
    this->count++;
    cout<<"Push data:"<<this->head->next->data<<endl;
}
// 返回栈顶元素,即出栈,但不删除栈顶元素
template<class T> T LinkedListStack<T>::Top()
{
    if(this->count == 0 || this->head->next == NULL)
    {
        cout<<"Stack is empty, Top fail"<<endl;
        return NULL;
    }
    else {
        LinkedNode * temp = this->head->next;
        T data = temp->data;
        return data;
    }
}
// 出栈
template<class T> T LinkedListStack<T>::Pop()
{
    if(this->count == 0 || this->head->next == NULL)
    {
        cout<<"stack is empty, Pop is fail"<<endl;
        return NULL;
    }
    else {
        LinkedNode * temp = this->head->next;
        this->head->next = temp->next;
        T data = temp->data;
        delete temp;
        this->count--;
        return data;
    }
}
// 返回栈的大小
template<class T> int LinkedListStack<T>::size() const
{
    return this->count;
}


int main(int argc, char *argv[])
{
    cout << " === StackBasedOnLinkedList test begin ===" << endl;
    LinkedListStack <float> stack;
    cout << "size==="<<stack.size()<<endl;
    stack.Push(10.1);
    stack.Push(20.2);
    stack.Push(30.);
    stack.Push(40.4);
    stack.Push(50.5);
    stack.Push(60.6);
    cout << "size==="<<stack.size()<<endl;
    cout << "stack Top  " << stack.Top() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "size==="<<stack.size()<<endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "size==="<<stack.size()<<endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Top  " << stack.Top() << endl;
    stack.Push(110.1);
    stack.Push(120.2);
    stack.Push(130.3);
    stack.Push(140.4);
    stack.Push(150.5);
    stack.Push(160.6);
    cout << "size==="<<stack.size()<<endl;
    cout << "stack Top  " << stack.Top() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Top  " << stack.Top() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    cout << "size==="<<stack.size()<<endl;
    cout << "stack Top  " << stack.Top() << endl;
    cout << "stack Pop  " << stack.Pop() << endl;
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u012736685/article/details/83055168