您的位置:首页 > 理论基础 > 数据结构算法

常用数据结构之链式存储队列

2012-03-15 00:58 281 查看
与顺序存储结构的队列不同,链式存储可以自由的扩展存储个数。设计时一般使用一个头节点和尾节点。头节点用于入队,尾节点用于出队。

其结构图如下所示:



用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: