与顺序存储结构的队列不同,链式存储可以自由的扩展存储个数。设计时一般使用一个头节点和尾节点。头节点用于入队,尾节点用于出队。
其结构图如下所示:
用C++模板类实现的代码如下:
/*
* =====================================================================================
*
* Filename: 3linkqueue.h
*
* Description: template implement of link queue
*
* Version: 1.0
* Created: 2012年03月13日 20时08分08秒
* Revision: none
* Compiler: gcc
*
* Author: Lavey Luo (lavey), luoyi.smt@gmail.com
* Organization:
*
* =====================================================================================
*/
#ifndef __LINK_QUEUE_H__
#define __LINK_QUEUE_H__
/*
* front e1 en
* --------- ---------- ----------
* | |---|--->| |---|----> .......> | | |
* | | | | | | | | |
* --------- ---------- ----------
* rear
*/
namespace st
{
#ifndef _STATUS_CONST_
#define _STATUS_CONST_
enum Status
{
OK = 0,
ERROR = -1
};
#endif
template<class T> class linkqueue;
template<class T>
class queuenode
{
friend class linkqueue<T>;
T data;
queuenode* next;
};
template<class T>
class linkqueue
{
public:
explicit linkqueue():front(0), rear(0), len(-1){};
~linkqueue(){};
public:
/* 构造一个空队列Q */
Status Init();
/* 求队列的长度 */
int Length();
/* 销毁队列 */
Status Destroy();
/* 将为空队列 */
Status Clear();
/* 若空队列,则返回TRUE,否则返回FALSE */
Status Empty();
/* 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR */
Status GetHead(T*e);
/* 插入元素e为新的队尾元素 */
Status EnQueue(T e);
/* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
Status DeQueue(T*e);
private:
queuenode<T>* front;
queuenode<T>* rear;
int len;
};
template<class T>
Status linkqueue<T>::Init()
{
if (len != -1 && front != 0 && rear != 0 )
return ERROR;
front = rear = new queuenode<T>;
len = 0;
return OK;
}
template <class T>
int linkqueue<T>::Length()
{
return len;
}
template <class T>
Status linkqueue<T>::Destroy()
{
if (len == -1)
return ERROR;
while (len >0 || front != rear)
{
queuenode<T>* p = front->next;
front->next = p->next;
if (!p->next)
rear = front;
delete p;
len --;
}
len = -1;
delete front;
return OK;
}
template <class T>
Status linkqueue<T>::Clear()
{
if (len == -1)
return ERROR;
while (len > 0 || front != rear)
{
queuenode<T>* p = front->next;
front->next = p->next;
if (!p->next) /* 若为最后一个元素则调整rear=front */
rear = front;
delete p;
len --;
}
return OK;
}
template <class T>
Status linkqueue<T>::Empty()
{
if (len == 0)
return OK;
return ERROR;
}
template <class T>
Status linkqueue<T>::GetHead(T *e)
{
if (len < 0 || !front)
return ERROR;
*e = front->next->data; /* 返回第一个元素的值 */
return OK;
}
template <class T>
Status linkqueue<T>::EnQueue(T e)
{
if (len < 0 || !front)
return ERROR;
queuenode<T>* p = new queuenode<T>;
if (!p)
return ERROR;
p->data = e;
p->next = 0;
rear->next = p; /* 调整rear的位置指向 */
rear = p;
len ++;
return OK;
}
template <class T>
Status linkqueue<T>::DeQueue(T* e)
{
if (len < 0 || front == rear) /* 空队列 */
return ERROR;
queuenode<T> *p = front->next;
front->next = p->next; /* 调整front指向的元素位置 */
if (!p->next) /* 若为最后一个元素则调整rear=front */
rear = front;
*e = p->data;
delete p;
len --;
return OK;
}
}
#endif // __LINK_QUEUE_H__
测试用列如下:
/*
* =====================================================================================
*
* Filename: test_linkqueue.cpp
*
* Description: test case of the linkqueue
*
* Version: 1.0
* Created: 2012年03月13日 21时14分11秒
* Revision: none
* Compiler: gcc
*
* Author: Lavey Luo (lavey), luoyi.smt@gmail.com
* Organization:
*
* =====================================================================================
*/
#include "3linkqueue.h"
#include <stdio.h>
int test_linkqueue(int argc, char** argv)
{
st::linkqueue<int> lq;
if (lq.Init() == st::OK)
printf("成功地构造了一个空队列!\n");
else
return -1;
printf("是否空队列?%d(0:空 -1:否) ",lq.Empty());
printf("队列的长度为%d\n", lq.Length());
lq.EnQueue(-5);
lq.EnQueue(5);
lq.EnQueue(10);
printf("插入3个元素(-5,5,10)后,队列的长度为%d\n",lq.Length());
int d = 0;
int i = lq.GetHead(&d);
if(i==st::OK)
printf("队头元素是:%d\n",d);
lq.DeQueue(&d);
printf("删除了队头元素%d\n",d);
i = lq.GetHead(&d);
if(i== st::OK)
printf("新的队头元素是:%d\n",d);
lq.Clear();
printf("清空队列后,len:%d\n",lq.Length());
printf("销毁队列\n");
lq.Destroy();
return 0;
}