常用數據結構之鏈式存儲隊列

        與順序存儲結構的隊列不同,鏈式存儲可以自由的擴展存儲個數。設計時一般使用一個頭節點和尾節點。頭節點用於入隊,尾節點用於出隊。

       其結構圖如下所示:


     用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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章