栈和队列
来源:互联网 发布:6合统计软件 编辑:程序博客网 时间:2024/06/14 18:18
- 栈的定义--Stack
栈只允许在末端(即是栈顶)进行插入和删除的线性表。栈具有后进先出的特性(LIFO,Last In First Out)。
线性表分为:顺序表和链表。
栈:只允许在尾上(即是栈顶)进行插入与删除。
队列:它是在队尾插入,队头删除。
下图是详细说明:
2、栈选数组(即顺序表)结构时(比选链表结构更好):因为选数组结构可以进行size++与size--,而且效率高。
栈选链表结构:
3、队列选数组结构时:选数组结构不好,因为删除时需要整体前移,因为队列是在队头进行删除,删除了队头元素时,其后面所跟的其他元素就需要整体向前移一位。效率较低。
队列选链表结构时:比选数组结构好,因为插入和删除元素时方便。
下面是关于栈的实现:
#include<iostream>
#include<string>
usingnamespacestd;
template<classT>
//栈有动态与静态之分
//栈适合用顺序表(无中间插入与删除时最好用数组),因为栈选顺序表(即是数组),进行size++与size--比较方便,而且效率较高。并且它的CPU高速缓存利用(即命中)率更高,命中,即是缓存中有,用时可以直接从缓存中取数据。
classstack
{
protected:
T* _a; //T类型的指针,指向顺序表(数组)
size_t_size; //数据的个数
size_t_capacity; //栈的容量
public:
stack(conststack<T> & s)//拷贝构造函数
:_a(newT[_size]) //此处的_size也可以换成_capacity,但是最好不要,因为这样会浪费空间。
,_size(s._size)
, _capacity(s._size)
{
for(size_ti = 0; i < _size; ++i)
{
_a[i] =s.q[i];
}
}
//stack<T> &operator=(const stack<T> &s) //赋值运算符重载
//{
//赋值运算符重载的传统写法
// if (this != &s) //首先判断是不是自己给自己赋值
// {
// //此处记住不能先释放空间,即delete[] _a,因为先释放再分配空间有缺陷,因为开辟空间可能会失败,但是释放空间一定会成功。
// T* tmp = new T[s._size];
// for (size_t i = 0; i < _size; ++i)
// {
// tmp[i] = s._a[i];
// }
// delete[] _a;
// _a = tmp;
// }
// return *this;
//}
stack<T> &operator=(conststack<T> &s)
{
//赋值运算符重载的现代写法(更好)
swap(_a,s._a);
swap(_size,s._size);
swap(_capacity,s._capacity);
return*this;
}
voidPush(constT&x)
{
//检查容量
_CheckCpapacity();
_a[_size++] =x;
}
voidPop()
{
assert(_size > 0);
--_size;
}
T& Top() //返回栈顶元素
{
assert(_size > 0);
return_a[_size - 1];
}
boolEmpty()
{
return_size == 0;
}
size_t size()
{
return
}
protected:
void_CheckCapacity()
{
if(_size == _capacity)
{
_capacity = _capacity * 2 + 3;
T* tmp =newT[_capacity];
if(_a)
{
for(size_ti = 0; i < _size; ++i)
{
tmp[i] = _a[i];
}
delete[] _a;
}
_a = tmp;
}
}
};
队列的定义
队列值允许在表的队尾进行插入,在表对头进行删除。队列具有先进先出的特性。(FIFO,first In First Out)
//队列全是动态,没有静态。最好用链式结构。
template<typenameT>
structNode
{
T_data;
Node<T> * _next;
};
template<classT>
classqueue
{
protected:
Node<T> * _tail;
Node<T> * _head;
public:
queue()
:_head(NULL)
, _tail(NULL)
{}
queue(constqueue<T> & q) //拷贝构造函数
:_head(NULL)
, _tail(NULL)
{
Node<T> *cur =q._head;
while(cur)
{
Push(cur->_data);
cur = cur->_next;
}
}
//queue<T> &operator=(const queue &q) //赋值运算符重载
//{
// //传统写法
// if (this != &q)
// {
// clear();
// Node<T> *cur = q._head;
// while (cur)
// {
// Push(cur->_data);
// cur = cur->_next;
// }
// }
// return *this;
//}
queue<T> &operator=(constqueue&q) //赋值运算符重载
{
//现代写法
swap(_head,q._head);
swap(_tail,q._tail);
return*this;
}
~queue()
{
Node<T> *cur = _head;
while(cur)
{
Node<T> *del = cur;
cur = cur->_next;
deletedel;
}
_head =NULL;
_tail =NULL;
}
voidPush(constT&x)
{
if(_head ==NULL)
{
_head = _tail =newNode<T>(x);
}
else
{
_tail->_next =newNode<T>(x);
_tail = _tail->_next;
}
}
voidPop() //出队操作,,有三种情况,分别为队列为空,队列只有一个结点,队列有多个结点。
{
assert(_head);
if(_head == _tail) //头指针等于尾指针,即只有一个结点。
{
delete_head;
_head = _tail =NULL;
}
else
{
Node<T> *del = _head;
_head = _head->_next;
deletedel;
}
}
T& Front() //返回队列的第一个元素
{
return_head->_data;
}
T& Back() //返回队列的最后一个元素
{
return_tail->_data;
}
boolEmpty() //判断队列是否为空
{
return_head ==NULL;
}
size_tsize() //返回队列的结点的个数
{
size_tsize = 0;
Node<T> *cur = _head;
while(cur)
{
++size;
cur = cur->_next;
}
returnsize;
}
};
0 0
- 栈和队列--队列
- 【栈和队列】队列
- 栈、队列和优先队列
- 栈和队列(队列)
- 栈和队列--栈
- 【栈和队列】栈
- 栈和队列
- 栈和队列
- 表、栈和队列
- 栈和队列
- 栈和队列应用
- 栈和队列
- 栈和队列
- 栈和队列
- 栈和队列
- 栈和队列
- 队列和栈
- 栈和队列 小结
- 取消除前三个其他所有勾选,再默认选中前三个。
- postgreSQL常用命令
- 杭电1425(sort)
- oracle笔记1-创建用户登录赋权
- 打印机智能化大势所趋,推动办公室物联网建设
- 栈和队列
- JSON与MODEL互转
- js 格式化数字,html input type=datetime-local赋值
- reportviewer 页面顶部显示总页码(去掉问号)
- iOS开发----Xcode7升级之后插件无法使用与不小心点击Skipbundle的解决办法【转载】
- 一分钟教会你如何在Android Studio中使用Gradle打包Jar
- <a> 标签的特殊用法
- oracle database的监听配置
- poj 几道简单的dp题