栈和队列剖析
这两天,我刚学习了数据结构,关于数据结构,说主要说的就是一些模型结构,以方便代码的编写。。。
我们以前学习的顺序表还有链表都属于是数据结构,可以说顺序表和链表是最基本的两种数据结构了,,之后我们的大多数数据结构都是以这两中数据模型来编写的。。。
今天,我们先来学习栈 模型 。 。。 。 。
要想学习栈,,就必须先了解栈结构的特点是什么????、
栈的剖析
栈 (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;
}
生成的结果