数据结构C++边学边做--队列的链式存储结构实现

队列的链式存储结构实现

  • 一、链队列的定义
  • 二、链队列数据结构定义
  • 三、链队列类实现
    • 1.类声明
    • 2.LinkQueue->构造函数
    • 3.~LinkQueue->析构函数
    • 4.EnQueue->入队
    • 5.DeQueue->出队
    • 6.GetQueue->取队头
    • 7.Empty->判断空队列
  • 四、链队列的测试
    • 1.主函数
    • 2.输出结果
  • 五、源代码获取(免积分)

一、链队列的定义

  采用链式存储结构实现的队列称为链队列(linked queue)。可以对单链表进行改造得到链队列,表头对应队头,表尾对应队尾。为了更方便操作,头指针为front,指向头结点。附设指向队尾结点的尾指针rear,空链队列和非空链队列如下图所示:
  空链队列:
数据结构C++边学边做--队列的链式存储结构实现_第1张图片
  非空链队列:
在这里插入图片描述

二、链队列数据结构定义

  结点结构可使用C++中的结构体定义,另外,由于链队列表中的元素类型并不确定,因此可以使用模板机制。

/*位于LinkStack.h文件中*/
/*用模板的方式定义数据结点*/
template <class ElemType>
struct Node
{
	ElemType data;
	Node<ElemType>* next;
};

三、链队列类实现

1.类声明

  可以使用C++语言的类模板LinkQueue描述链队列。由于队列是操作受限的线性表,因此链队列也可以看做是操作受限的单链表。

/*位于LinkQueue.h文件中*/
/*链队列的类定义及方法声明*/
template <class ElemType>
class LinkQueue{
	public:
		LinkQueue();/*构造函数,初始化空的链队列*/
		~LinkQueue();/*析构函数,释放链队列中的所有结点*/
		void EnQueue(ElemType x);//入队操作
		ElemType DeQueue() ;//出队操作
		ElemType GetQueue();//取队头
		int Empty();//判断链队列是否为空 
	private:
		Node<ElemType>* front ,*rear;//链队列的头指针和尾指针 
}; 

2.LinkQueue->构造函数

  构造函数初始化的链队列,只需要申请头结点,将front和rear赋初值。算法描述如下:

/*位于LinkQueue.cpp文件中*/
/*构造函数*/
template <class ElemType>
LinkQueue<ElemType>::LinkQueue()
{
	front=new Node<ElemType>;
	front->next=NULL;
	rear=front; 
}

3.~LinkQueue->析构函数

  析构函数将链队列中包括头结点在内的所有结点释放掉,执行完析构函数以后,front指针和rear指针都为NULL。算法描述如下:

/*位于LinkQueue.cpp文件中*/
/*析构函数*/
template <class ElemType>
LinkQueue<ElemType>::~LinkQueue()
{
	while(front!=NULL)
	{
		Node<ElemType>* p=front;
		front=front->next;
		delete p;
	}
	rear = NULL;
}

4.EnQueue->入队

  入队操作是在链表的表尾插入新的结点s,如下图所示:
数据结构C++边学边做--队列的链式存储结构实现_第2张图片

/*位于LinkQueue.cpp文件中*/
/*入队操作*/
template <class ElemType>
void LinkQueue<ElemType>::EnQueue(ElemType x)
{
	Node<ElemType>* s=new Node<ElemType>;
	s->data=x;
	s->next=NULL;
	rear->next=s;
	rear=s;
}

5.DeQueue->出队

  链队列的出队是在链表的表头删除一个结点。如果队列中包括的元素结点个数大于1,则不会影响到rear指针,因为队尾元素不变。但是如果队列中只包括一个元素结点,出队以后,链队列为空,此时需要将rear指针指向头结点,即rear=front。链队列出队操作如下图所示:
  队列中只有一个元素结点:
数据结构C++边学边做--队列的链式存储结构实现_第3张图片
  队列中元素结点数大于1:
在这里插入图片描述

/*位于LinkQueue.cpp文件中*/
/*出队操作*/
template <class ElemType>
ElemType LinkQueue<ElemType>::DeQueue()
{
	if(front==rear)
		throw "链队列为空!";
	/*p指向头指针*/ 
	Node<ElemType>* p=front->next;
	ElemType x=p->data;
	front->next=p->next;
	/*队列长度为1时,需要修改rear指针*/
	if(p->next==NULL)
		rear=front;
	delete p;
	return x;
}

6.GetQueue->取队头

/*位于LinkQueue.cpp文件中*/
/*取队头操作*/
template <class ElemType>
ElemType LinkQueue<ElemType>::GetQueue()
{
	if(front==rear)
		throw "链队列为空!";
	else
		return front->next->data;
}

7.Empty->判断空队列

/*位于LinkQueue.cpp文件中*/
/*判断空链队列操作*/
template <class ElemType>
int LinkQueue<ElemType>::Empty()
{
	if(front==rear)
		return 1;
	else
		return 0;
}

四、链队列的测试

1.主函数

#include 
#include "LinkQueue.h"
#include "LinkQueue.cpp"


using namespace std;

int  main() {
	LinkQueue<int> q;
	if(q.Empty()==1)
		cout<<"链队列为空"<<endl;
	cout<<"元素2入队"<<endl;
	q.EnQueue(2) ;
	cout<<"元素4入队"<<endl;
	q.EnQueue(4) ;
	cout<<"元素6入队"<<endl;
	q.EnQueue(6) ;	
	cout<<"队头元素为:" <<q.GetQueue()<<endl;
	cout<<"队头出队"<<endl;
	q.DeQueue();
	cout<<"队头元素为:" <<q.GetQueue()<<endl;
	if(q.Empty()==0)
		cout<<"链队列不为空"<<endl;
	return 1; 
}

2.输出结果

链队列为空
元素2入队
元素4入队
元素6入队
队头元素为:2
队头出队
队头元素为:4
链队列不为空

五、源代码获取(免积分)

源代码地址

你可能感兴趣的:(数据结构C++边学边做,数据结构,c++,链表,队列)