C++实现栈的顺序存储和链式存储

1、栈的定义(逻辑结构)

栈是一种插入和删除操作都只能在表的同一端进行的线性表。这是一种受限的线性表,满足先进后出的原则(FILO),允许进行插入和删除操作的一端叫做栈顶(Top);另一端叫做栈底(Bottom)。

2、栈的顺序存储(物理结构)

设计时:栈顶放在数组的尾地址(效率高)
通过栈顶top就可以完成一系列操作。开始将top = -1

#pragma once
#include<iostream>
using namespace std;

template<class T>
class LinerStack
{
public:
	LinerStack(int LSMaxSize);		//构造函数,创建空栈
	~LinerStack();					//析构函数,删除栈


	bool IsEmpty();				//判断栈是否为空,空返回true
	bool IsFull();				//判断栈是否为满,满返回true
	
	//int GetElementNumber();	//求栈中元素的个数
	
	bool Push(const T& x);		//进栈操作,在栈顶插入元素x,插入成功返回true
	bool Top(T& x);				//求栈顶元素的值放入x中
	bool Pop(T& x);				//出栈操作,从栈顶删除一个元素,并将该元素的值放入x
	
	void OutPut(ostream& out)const;

private:
	int top;		//用来表示栈顶下标,初始为-1
	int MaxSize;	//栈中最多能存储的元素个数
	T *element;		//一维动态数组首地址
};


template<class T>
LinerStack<T>::LinerStack(int LSMaxSize)
{
	MaxSize = LSMaxSize;
	top = -1;
	element = new T[LSMaxSize];	//开辟堆空间
}

template<class T>
LinerStack<T>::~LinerStack()
{
	delete[] element;
}


template<class T>
bool LinerStack<T>::IsEmpty()
{
	return top == -1;
}

template<class T>
bool LinerStack<T>::IsFull()
{
	return top == MaxSize - 1;
}

//int GetElementNumber();	//求栈中元素的个数

template<class T>
bool LinerStack<T>::Push(const T& x)
{
	if (IsFull())		//满栈返回false
		return false;
	else
	{
		top++;
		element[top] = x;
		return true;
	}
}

template<class T>
bool LinerStack<T>::Top(T& x)
{
	if (IsEmpty())		//空栈返回false
		return false;
	else
	{
		x = element[top];
		return true;
	}
}

template<class T>
bool LinerStack<T>::Pop(T& x)
{
	if (IsEmpty())		//空栈返回false
		return false;
	else
	{
		x = element[top];
		top--;		//不需要将原位置的元素释放啥的,因为top指针下来之后,原来的栈顶原元素就访问不到了
					//等再插入新元素时,就会把原来的覆盖掉
		return true;
	}
}

template<class T>
void LinerStack<T>::OutPut(ostream& out)const
{
	for (int i = 0; i < top; i++)
	{
		out << element[i] << endl;
	}
}

//重载插入运算符<<		全局函数
template<class T>
ostream& operator<<(ostream& out, const LinerStack<T>& x) 
{
	x.OutPut(out); 
	return out;
}

3、栈的链式存储(物理结构)

设计时:栈顶放在链表的头地址(效率高),放在尾部的话每次插入删除都需要从头遍历

#pragma once
#include<iostream>
using namespace std;

template<class T>
class LinkNode
{
	template<class T>
	friend class LinkStack;
public:
	LinkNode()			//构造函数
		next = NULL;	//每new一个结点时,先将他置空,串进链表之后才设next
private:
	T data;
	LinkNode<T>* next;
};

template<class T>
class LinkStack {
public:
	LinkStack();		//构造函数,创建空栈
	~LinkStack();		//析构函数,删除栈

	bool IsEmpty() const;		//判断栈是否为空

	bool Push(const T& x);		//在栈顶插入元素x
	bool Top(T& x);				//求栈顶元素的值放入x中
	bool Pop(T& x);				//从栈顶删除一个元素,并将该元素的值放入x中
	void OutPut(ostream& out) const;
	
private:
	LinkNode<T>* top;		//指向栈顶结点的指针
	
	int size;			//栈中元素个数
};

template<class T>
LinkStack<T>::LinkStack()
{
	top = NULL;
	size = 0;
}

template<class T>
LinkStack<T>::~LinkStack()
{
	T x;
	while (top != NULL)
	{
		Pop(x);
	}
}


template<class T>
bool LinkStack<T>::IsEmpty() const
{
	return top == NULL;
}

template<class T>
bool LinkStack<T>::Push(const T& x)		//这里x只是数据域
{
	LinkNode<T>* p = new LinkNode<T>;	//新建结点用于标记新插入的元素
	if (p == NULL)
		return false;
	else
	{
		p->data = x;
		p->next = top;
		top = p;
		size++;
		return true;
	}
}

template<class T>
bool LinkStack<T>::Top(T& x)
{
	if (IsEmpty())		//空栈返回false
		return false;
	else
	{
		x = top->data;
		return true;
	}
}

template<class T>
bool LinkStack<T>::Pop(T& x)
{
	LinkNode<T>* p = top;	//记录待删除的结点
	if (IsEmpty())			//空栈返回false
		return false;
	else
	{
		x = top->data;
		top = top->next;
		size--;	
		delete p;
		return true;
	}
}

template<class T>
void LinkStack<T>::OutPut(ostream& out)const
{
	LinkNode<T>* p;
	p = top;
	for (int i = 0; i < size; i++)
	{
		out << p->data << endl;
		p = p->next;
	}
}

//重载插入运算符<<		全局函数
template<class T>
ostream& operator<<(ostream& out, const LinkStack<T>& x)
{
	x.OutPut(out);
	return out;
}

4、测试

#include<iostream>
using namespace std;
#include"LinerStack.h"
#include"LinkStack.h"


int main()
{
	//LinerStack<int> s(5);
	LinkStack<int> s;
	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Push(4);
	s.Push(5);
	
	int x;
	s.Pop(x);
	cout << x << endl;

	s.Top(x);
	cout << x << endl;

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值