链式队列
链式队列是基于单链表的一种存储方式。
在单链表的每一个节点中有两个域:data域存放队列元素的值,link域存放单链表下一个结点的地址。队列的队头指针指向单链表的第一个结点,队尾指针指向单链表的最后一个结点。
- 队列的队头元素存放在单链表的第一个结点内,若要从队列中退出一个元素,必须从单链表中删去第一个结点。
- 存放着新元素的结点应插在队列的队尾,即单链表的最后一个结点后面,这个新结点将成为新的队尾。
用单链表表示的链式队列特别适合于元素变动比较大的情况,而且不存在队列满而溢出的情况。
代码实现
#include<assert.h>
#include<iostream>
using namespace std;
///////////////////////
链式队列
//////////////////////
template<class T>
struct LinkNode
{
LinkNode<T> * _pNext;
T _pData;
LinkNode(const T& x)
:_pNext(NULL)
, _pData(x)
{}
};
template<class T>
class queue
{
public:
//构造函数
queue()
:front(NULL)
, rear(NULL)
{}
//析构函数
~queue()
{
makeEmpty();
}
//插入队列元素
bool enQueue(const T& x)
{
//队内无元素情况
if (IsEmpty())
{
front = rear = new LinkNode<T>(x);
if (front == NULL)
return false;
return true;
}
//有元素情况
rear->_pNext = new LinkNode<T>(x);
if (rear->_pNext == NULL)
return false;
rear = rear->_pNext;
return true;
}
//删除队列元素
bool delQueue()
{
LinkNode<T> * del;
//空队列
if (IsEmpty())
return false;
//非空队列
del = front;
front = front->_pNext;
delete del;
return true;
}
//查看队头元素
bool getFront(T& x)const
{
if (front == NULL)
return false;
x = front->_pData;
return true;
}
//置空队列
void makeEmpty()
{
LinkNode<T> * del;
while (front != rear)
{
del = front;
delete del;
front = front->_pNext;
}
}
//判断队列为空
bool IsEmpty()
{
return ((front == NULL) ? true : false);
}
private:
LinkNode<T> * front;
LinkNode<T> * rear;
};
int main()
{
int a = 0, b = 0;
queue<int> s;
s.enQueue(2);
s.enQueue(3);
s.delQueue();
s.enQueue(3);
s.getFront(a);
s.getFront(b);
cout << a << b << endl;
s.makeEmpty();
return 0;
}
双端队列
普通的队列只能实现向一个方向前进,接下来实现的双端队列,可以向两端延伸和缩进,还可以通过控制调用函数,实现单项队列,是常用的库函数。
Head为头结点,Tail为尾结点。
Deque类会提供头尾结点的插入,删除,查看函数。
代码实现
#include<assert.h>
#include<iostream>
using namespace std;
//////////////////////
//双端队列
//////////////////////
template<class T>
struct LinkNode
{
LinkNode<T> * _pNext;
T _pDate;
LinkNode(const T& x)
:_pNext(NULL)
, _pDate(x)
{}
};
template<class T>
class Deque
{
public:
//构造函数
Deque()
:Head(NULL)
, Tail(NULL)
{}
//析构函数
//队列判空
bool IsEmpty()
{
if (Head == NULL && Tail == NULL)
return true;
return false;
}
//插入队头
bool enQueueHead(const T& x)
{
if (IsEmpty())
{
Head = Tail = new LinkNode<T>(x);
return true;
}
LinkNode<T> * s = new LinkNode<T>(x);
s->_pNext = Head;
s->_pDate = x;
Head = s;
return true;
}
//删除队头
bool delQueueHead()
{
if (IsEmpty())
return false;
LinkNode<T> * del = new LinkNode;
if (del == NULL)
return false;
del = Head;
Head = Head->_pNext;
delete del;
}
//插入队尾
bool enQueueTail(const T& x)
{
if (IsEmpty())
{
Head = Tail = new LinkNode<T>(x);
return true;
}
Tail->_pNext = new LinkNode<T>(x);
if (Tail->_pNext == NULL)
Tail = Tail->_pNext;
return true;
}
//删除队尾
bool delQueueTail()
{
if (IsEmpty())
return false;
LinkNode<T> * del;
del = Head;
while (del->_pNext != Tail)
{
del = del->_pNext;
}
Tail = del;
del = del->_pNext;
delete del;
}
//得到队头
bool getHead( T& x)
{
if (Head == NULL)
return false;
x = Head->_pDate;
return true;
}
//得到队尾
bool getTail(T& x)
{
if (Tail == NULL)
return false;
x = Tail->_pDate;
return true;
}
//置空队列
void makeEmpty()
{
LinkNode<T> * del;
while (Head != Tail)
{
del = Head;
Head = Head->_pNext;
delete del;
}
return;
}
private:
LinkNode<T> * Head;
LinkNode<T> * Tail;
};
int main()
{
Deque<int> s;
int a, b;
s.enQueueTail(3);
s.enQueueHead(2);
s.getHead(a);
s.getTail(b);
cout << a << b << endl;
s.enQueueHead(1);
s.delQueueTail();
s.getHead(a);
s.getTail(b);
cout << a << b << endl;
s.enQueueHead(0);
s.delQueueTail();
s.getHead(a);
s.getTail(b);
cout << a << b << endl;
return 0;
}
如果有什么不懂的地方可以去看看这个网站,提供了数据结构的动态演示。
或者在下方给我留言——>