队列是限制性的数据结构,在队头可以进行删除(出队)操作,在队尾进行入队操作。和以前一样队列的存储结构有俩种:顺序存储和链式存储。
1.顺序存储:
如果和堆栈一样使用位置指针的话,会产生假溢出的问题,对此进行了修改。(这里的位置指针不是指针,只是指向当前位置的称呼),同时还可以用循环队列解决假溢出问题(下一篇介绍循环队列)。
头文件:
由于操作函数比较简单,就直接定义在类中。
#ifndef QUEUE_H
#define QUEUE_H
//队列只能在队尾进行进队操作,队头进行删除操作
#include<iostream>
template<class T>
class queue
{
public:
queue()
{
top = -1;
end = -1;
size = 0;
que = nullptr;
length = 0;
}
queue(int s) :size(s)
{
que = new T[size];
length = 0;
}
~queue()
{
delete[] que;
}
public:
void pop()
{
if (end == -1)
{
std::cout << "队列为空" << std::endl;
top = -1;
return ;
}
else
{
++top;
for (int i = 0; i < end-top; ++i) //元素向前移
que[i] = que[top + i + 1];
end = end - top - 1; //重新定位队头和队尾位置
top = -1;
--length;
}
}
void push(T dat)
{
if (length == size)
{
std::cout << "队列已满" << std::endl;
return;
}
else
{
++end;
que[end] = dat;
++length;
}
}
void print() const
{
if (end == -1)
{
std::cout << "队列为空" << std::endl;
return ;
}
else
{
for (int i = 0; i < length; ++i)
std::cout << que[i] << " ";
std::cout << std::endl;
}
}
private:
int top ; //队头指向已经出队的数据,即队头的前一个位置
int end ;//指向队尾元素
T* que;
int size;
int length;
};
#endif
main文件:
#include<iostream>
#include"queue.h"
using namespace std;
int main()
{
queue<int> liner(5);
liner.push(1);
liner.pop();
liner.print();
liner.push(1);
liner.push(2);
liner.push(3);
liner.push(4);
liner.push(5);
liner.push(6);
liner.print();
liner.pop();
liner.pop();
liner.pop();
liner.print();
system("pause");
return 0;
}
2.链式存储
链式队列分为带头结点和不带头节点俩种方式,带头结点时,队列是空的条件:头指针和尾指针同时指向头结点。不带头结点,队列为空的条件是:头结点指针和尾结点指针都为nullptr。
头文件:
#ifndef QUEUE_H
#define QUEUE_H
//不带头结点的链表结构
#include<iostream>
template<class T>
class node
{
template<class T>
friend class queue;
public:
node()
{
next = nullptr;
data = 0;
}
~node()
{
}
private:
node<T>* next;
T data;
};
template<class T>
class queue
{
public:
queue()
{
top = nullptr;
end = nullptr;
length = 0;
}
~queue()
{
while (top)
{
node<T>* tep = top;
top = top->next;
delete tep;
tep = nullptr;
}
}
public:
bool isempty()
{
return top == nullptr;
}
void pop();
void push(const T dat);
void print();
private:
node<T>* top;
node<T>* end;
int length;
};
template<class T>
void queue<T>::push(const T dat)
{
node<T>* ptr = new node < T >;
ptr->data = dat;
ptr->next = nullptr;
if (isempty())
top = end = ptr;
else
{
end->next = ptr;
end = ptr;
}
++length;
}
template<class T>
void queue<T>::pop()
{
if (isempty())
{
std::cout << "队列为空" << std::endl;
return;
}
else
{
node<T>* temp = top;
top = top->next;
delete temp;
--length;
}
}
template<class T>
void queue<T>::print()
{
if (isempty())
{
std::cout << "队列为空" << std::endl;
return;
}
else
{
node<T>* pp = top;
for (int i = 1; i < length; ++i)
{
std::cout << pp->data << " ";
pp = pp->next;
}
}
std::cout<< std::endl;
}
#endif
main文件:
#include<iostream>
#include"queue.h"
using namespace std;
int main()
{
queue<int> liner;
liner.push(1);
liner.pop();
liner.print();
liner.push(1);
liner.push(2);
liner.push(3);
liner.push(4);
liner.push(5);
liner.push(6);
liner.print();
liner.pop();
liner.pop();
liner.pop();
liner.print();
system("pause");
return 0;
}