今天最后老师问当栈的链式实现完成后,再实现队列,是否会简单?我回答,是的。
我的理由很简单,因为操作相同,其他的也应该类似,所以不会太难。至于实现之后,我的感受是怎么样的,我留在最后再说,顺便总结一下。
下面是头文件:
#ifndef LINKLISTQUEUE_H
#define LINKLISTQUEUE_H
struct Node{
int data;
Node *next;
};
class Queue{
private:
Node *front, *rear;
public:
Queue(); <span style="white-space:pre"> </span>//初始化链式队列
~Queue();<span style="white-space:pre"> </span>//析构队列
bool enQueue(const int &data); //入队
bool deQueue(int &data); //出队
bool getFront(int &data)const; //得到对头元素
bool getRear(int &data) const; //得到队尾元素
bool isEmpty() const; //判断队列是否为空
int length() const; //队列的长度
void clear(); //队列恢复初始化
};
#endif
#include"LinkListQueue.h"
#include<iostream>
using std::cout;
using std::endl;
Queue::Queue(){
rear=front = new Node; //保持尾指针指向当前的节点
front->next = NULL;
}
Queue::~Queue(){
Node *pre = front, *p = front->next;
while (p != NULL){
delete pre;
pre = p;
p = p->next;
}
front = NULL; rear = NULL;//为了安全对其赋值NULL;
cout << "析构函数!" << endl;
delete pre;
}
bool Queue::enQueue(const int &data){
Node *s = new Node;
if (s == NULL){
cout << "内存分配不成功!" << endl;
return false;
}
s->data = data;
s->next = NULL;//为其他函数设置结束条件
rear->next = s;
rear = s;
return true;
}
bool Queue::deQueue(int &data){
if (front == rear) return false;
if (front->next == rear) rear = front;
Node *p = front->next;
front->next = p->next;
data = p->data;
delete p;
return true;
}
bool Queue::getFront(int &data)const{
if (front == rear) return false;
data = front->next->data;
return true;
}
bool Queue::getRear(int &data) const{
if (front == rear) return false;
data = rear->data;
return true;
}
bool Queue::isEmpty() const{
return (front == rear);
}
int Queue::length() const{
int i = 0; //计数器类似指针始终指向当前节点,保持与线性表中的序数一致!
Node *p = front;
while (p->next != NULL){ //保持与线性表中的序数一致!
i++;
p = p->next;
}
return i;
}
void Queue::clear(){
this->~Queue();
rear = front = new Node;
front->next = NULL;
}
主函数测试:
#include<iostream>
#include"LinkListQueue.h"
using namespace std;
int main(){
Queue *queue = new Queue;
for (int i = 0; i < 10; i++) queue->enQueue(i);
cout<<"队列长度:"<< queue->length() << endl;
queue->clear();
cout<<"队列长度:"<< queue->length() << endl;
for (int i = 10; i >= 4; i--) queue->enQueue(i);
while (!queue->isEmpty()){
int data;
queue->deQueue(data);
cout << data << endl;
}
delete queue;
system("pause");
return 0;
}
我总结一下:
首先是front 和 rear两个指针,一般来说,front指向队列中第一个元素的前面,所以这个自然极其的类似链表中的head指针,所以为front分配一个空间(new)。
对于rear,书中的定义是指向尾节点,所以可以用它来指向当前最后一个节点,类似链表中的尾插法的实现手段。
这两个我认为是很关键的,保持了出入于删除的一致性,当然,如果你看我的代码,你会发现有在删除之前有一个
if (front->next == rear) rear = front;
这个是防止rear成为野指针,从而不能再次插入与删除。