细节知识点:
为解决单个队列假溢出问题,将其改为循环队列,在循环队列中,判断队列满常有两种方法:
- 设置标志位
- 重新定义队列满状态,设置队列满时保留一个元素空间;而认定头尾指针重合时为队列空;
针对第二种方法:
此时,队列满判别语句可以为:(rear+1)% 队列总大小 == front
—— “ % 队列总大小 ” 只是为了整合front为0状态时的队列满判断;
而对当前队列长度的计算公式为:( rear + 队列总大小 - front )% 队列总大小
—— “ + 队列总大小 ” 只是为了整合front为非0状态时的队列长度计算。
队列和栈的数据流:
队列是先进先出的线性表,队尾插入,在队头删除,若是链式存储通常需要头节点,头节点不存储数据,插入时在头节点后面插入;
栈是仅通过栈顶进行插入和删除操作,栈的链式结构是不需要头节点的。
关于队列的链式存储与顺序存储(基于循环队列)
1. 顺序存储(基于循环队列)
#include<iostream>
using namespace std;
const int MAX_CONT = 100;
template<class Datatype>
class clcqueue {
public:
clcqueue() { front = 0; rear = 0; }
clcqueue(Datatype* a, int num);
~clcqueue() {};
bool enqueue(Datatype a);
Datatype dequeue();
bool isfull();
private:
Datatype data[MAX_CONT];
int front;
int rear;
};
template<class Datatype>
clcqueue<Datatype>::clcqueue(Datatype* a, int num)
{
int i = 0;
front = 0; rear = 0;
if (num >= MAX_CONT)
throw "Overflow";
while (num--) {
enqueue(a[i++]);
}
}
template<class Datatype>
bool clcqueue<Datatype>::enqueue(Datatype a)
{
if (isfull() == true)
throw "Queue is Full";
data[rear] = a;
rear++;
if (rear >= MAX_CONT)
rear = 0;
return true;
}
template<class Datatype>
Datatype clcqueue<Datatype>::dequeue()
{
if (front == rear)
throw "Error : Queue is Empty!";
Datatype out = data[front++];
if (front >= MAX_CONT)
front = 0;
return out;
}
template<class Datatype>
bool clcqueue<Datatype>::isfull()
{
if ((rear + 1) % MAX_CONT == front)
return true;
else
return false;
}
int main() {
char test[] = "dhuqhdwuqopdhjwqjdi";
int num = strlen(test) + 1;
try
{
clcqueue<char> testque(test, num);
testque.enqueue('a');
while(num--)
cout << testque.dequeue() << endl;
// clcqueue<char> testque2;
// cout << testque2.dequeue() << endl;
}
catch (const char* e)
{
cout << e << endl;
}
return 0;
}
2、链式存储
#include<iostream>
using namespace std;
template<class Datatype>
class clcqueue {
public:
typedef struct node {
Datatype data;
node* next;
}Node;
clcqueue(){ front = new Node; rear = front; }
clcqueue(Datatype* a, int num);
~clcqueue();
bool enqueue(Datatype a);
Datatype dequeue();
private:
Node* front;
Node* rear;
};
template<class Datatype>
clcqueue<Datatype>::clcqueue(Datatype* a, int num) {
int i = 0;
front = new Node; rear = front;
while (num--) {
enqueue(a[i++]);
}
}
template<class Datatype>
clcqueue<Datatype>::~clcqueue()
{
while(front->next!=NULL)
dequeue();
}
template<class Datatype>
bool clcqueue<Datatype>::enqueue(Datatype a)
{
Node* temp=new Node;
temp->data = a;
temp->next = NULL;
rear->next = temp;
rear = temp;
return true;
}
template<class Datatype>
Datatype clcqueue<Datatype>::dequeue()
{
if (rear == front) throw "Underflow"; // 判断队列是否为空
Node* temp = front->next; // 注意,头节点不存数据,数据是在头节点后出队
Datatype out = temp->data;
front->next = temp->next;
delete temp;
return out;
}
int main() {
char test[] = "dhuqhdwuqopdhjwqjdi";
int num = strlen(test) + 1;
clcqueue<char> testque(test, num);
testque.enqueue('a');
while (num--)
cout << testque.dequeue() << endl;
return 0;
}