與順序存儲結構的隊列不同,鏈式存儲可以自由的擴展存儲個數。設計時一般使用一個頭節點和尾節點。頭節點用於入隊,尾節點用於出隊。
其結構圖如下所示:
用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), [email protected]
* 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), [email protected]
* 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;
}