栈和队列剖析

栈和队列剖析

这两天,我刚学习了数据结构,关于数据结构,说主要说的就是一些模型结构,以方便代码的编写。。。
我们以前学习的顺序表还有链表都属于是数据结构,可以说顺序表和链表是最基本的两种数据结构了,,之后我们的大多数数据结构都是以这两中数据模型来编写的。。。
今天,我们先来学习栈   模型   。 。。 。 。 
要想学习栈,,就必须先了解栈结构的特点是什么????、

栈的剖析

栈 (stack) 是限定仅在栈尾插入或删除数据的模型结构 ,,,(也就是是只能在尾部 进行操作),根据栈的这个特点我们将栈的修改原则叫做是    后进先出   原则(last in first out)(简称LIFO结构)。。。。。
针对栈这个特点我们把栈的首部叫做是   栈底  ,,,,栈的尾部叫做是 栈顶
也就是说栈的一系列的操作都是在栈顶 来完成的 ,,,,   
栈的模型图

初步了解了栈的结构特点之后接下来就要开始用代码实现     栈 的结构。。。。。
写代码之前我们 便要知道怎么 来实现这个结构  。。。。 
我们之间说  顺序表 和链表是  两种最基本 的数据结构   ,,,,所以在这里我们也可以使用 这两种数据结构实现栈结构的编写      但是这两种结构我们要使用那哪种 呢 !!!!
那就要根据栈的特点来决定了  。。。。。 。。 、
栈的特点是后进先出        ,,,,也就是在尾部    进行操作,,,,针对这种特性 ,专家们觉的使用顺序表
更为方便  ,为什么呢???
顺序表 ,,,,可以简单的看成是一个动态的数组。。。。。 
链表,,,,,可以说是有一个又一个的节点来组成的。。。。。
如果说要在尾部插入删除的话  ,,,,顺序表更为方便简洁。。。。。。
关于栈    编译器为我们要实现的一些必要基本操作有

其中push为入栈操作  ,
pop为出栈操作 ,,,
top为 取栈顶元素 
size为返回的栈的长度
empty为判空栈
下面是我自己实现的栈的操作函数
代码  清单
#include<iostream>
#include<assert.h>
using namespace std;

template<class T>
class  Stack
{
public:
	Stack()
		:_data(NULL)
		,_size(0)
		,_capacity(0)
	{}
	Stack(const Stack<T>& s)
		:_data(new T[s._capacity])
		,_size(s._size)
		,_capacity(s._capacity)
	{
		for(size_t i   = 0 ;i < _size;++i)
		{
			_data[i] = s._data[i];
		}
	}
	Stack<T> operator=(const Stack<T> & s)
	{
		if(this != &s)
		{
			Stack<T> tem(s);
			std::swap(tem._data,_data);
			_size = s._size;
			_capacity  = s._capacity;
		}
		return *this;
	}
	~Stack()
	{
		if(_data)
		{
			delete[] _data;
			_data = NULL;
		}
		_size =0 ;
		_capacity = 0;
	}
	
public:
	void Push(const T& data)
	{
		CheckCapacity();
		_data[_size++] = data;
	}
	void Pop()
	{
		assert(_size);
		_size--;
	}
	size_t Size()
	{
		return _size;
	}
	bool Empty()
	{
		 return  _size==0;
	} 
	T& Top()
	{
		assert(_size);
		return _data[_size-1];
	}
	void PrintSatck()
	{
		for(size_t  i = 0;i <_size;++i)
		{
			cout<<_data[i]<<" ";
		}
		cout<<endl;
	}
protected:
	void CheckCapacity()
	{
		if(_size >= _capacity)
		{
			size_t capacity  = _capacity*2 +3;
			T * tem = new T[capacity];
			if(_data)
			{
				for(size_t i = 0 ;i < _size;++i)
				{
					tem[i] = _data[i];
				}
				delete[] _data;
			}
			_capacity = capacity;
			_data = tem;
		}
	}
protected:
	T *_data;
	size_t  _size;
	size_t _capacity;
};


测试代码
void TestStack()
{
	Stack<int> s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	s1.PrintSatck();
	Stack<int> s2(s1);
	s2.Push(5);
	s2.PrintSatck();
	Stack<int> s3;
	s3 = s2;
	s3.Push(6);
	s3.PrintSatck();
}

生成结果:

栈的结构就是这样了,当然因为栈结构的这种特点,,,,使得栈的应用也很广泛

队列剖析

队列的结构和栈的结构正好相反 ,, , ,,队列的元素讲究的是先进先出  (FIFO结构)
换句话来说就是队列的结构是在 队首删除,在队尾插入
队列的模型结构


队列的特点是先进先出  ,,在队首和队尾操作,,,这样的操作用   链表实现更为方便

关于队列    编译器为我们实现的操作有


其中
empty为判空函数
size为队列元素个数
front为队首元素
back为队尾元素
push为插入操作
pop为删除操作
实现代码
#include<iostream>
#include<assert.h>
using namespace std;
template<class T>
struct QueueNode//链表节点
{
	T _data;
	QueueNode<T> * _next;
	QueueNode(const T& data = 0)
		:_data(data)
		,_next(NULL)
	{}
};
template<class T>
class Queue
{
	typedef QueueNode<T> Node;
public:
	Queue()
		:_phead(NULL)
		,_ptail(NULL)
	{}
	Queue(const Queue<T>& q)
		:_phead(NULL)
		,_ptail(NULL)
	{
		Node* cur =q._phead;
		while(cur)
		{
			Push(cur->_data);
			cur = cur->_next;
		} 
	}
	Queue<T> & operator= (const Queue<T>& q)
	{
		if(this!= &q)
		{
			Node * cur =_phead;
			if(!Empty())
			{
				while(cur)
				{
					Node* pur= cur->_next;
					delete cur;
					cur= pur; 
				}
			_phead =_ptail = NULL;
			}
			cur =q._phead;
			while(cur)
			{
				Push(cur->_data);
				cur = cur->_next;
			}
		}
		return *this;
	} 
	~Queue()
	{
		Node * cur =_phead;
		while(cur)
		{
			Node* pur= cur->_next;
			delete cur;
			cur= pur; 
		}
		_phead =_ptail = NULL;
	}
public:
	void Push(const T& data)
	{
		if(!_phead)
		{
			_phead = _ptail = new Node(data); 
		}
		else
		{
			_ptail->_next = new Node(data);
			_ptail = _ptail->_next;
		}
	}
	void Pop()
	{
		if(_phead==_ptail)
		{
			delete _phead;
			_phead = _ptail = NULL;
		}
		else
		{
			Node*cur = _phead->_next;
			delete _phead;
			_phead = cur;
		}
	}
	size_t Size()
	{
		size_t count = 0 ;
		Node* cur = _phead;
		while(cur)
		{
			++count;
			cur= cur->_next;
		}
		return count;
	}
	T& Front()
	{
		assert(Size());
		return _phead->_data;
	}
	const T& Front()const
	{
		asset(Size());
		return _phead->_data;
	}
	T& Back()
	{
		asset(Size());
		return _ptail->_data;
	}
	const T& Back()const
	{
		asset(Size());
		return _ptail->_data;
	}
	bool Empty()
	{
		return _phead==NULL;
	}
protected:
	Node *_phead;
	Node *_ptail;

};


测试代码
void TestQueue()
{
	Queue<int> q;
	q.Push(1);
	q.Push(2);
	q.Push(3);
	q.Push(4);
	Queue<int> q1(q);
	Queue<int> q2;
	q2 =q1;
	while(!q.Empty())
	{
		cout<<q.Front()<<" ";
		q.Pop();
	}
	cout<<endl;
	while(!q1.Empty())
	{
		cout<<q1.Front()<<" ";
		q1.Pop();
	}
	cout<<endl;
	while(!q2.Empty())
	{
		cout<<q2.Front()<<" ";
		q2.Pop();
	}
	cout<<endl;
}
生成的结果









  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值