队列的链式实现

今天最后老师问当栈的链式实现完成后,再实现队列,是否会简单?我回答,是的。

我的理由很简单,因为操作相同,其他的也应该类似,所以不会太难。至于实现之后,我的感受是怎么样的,我留在最后再说,顺便总结一下。

下面是头文件:

#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成为野指针,从而不能再次插入与删除。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值