常用数据结构之基于数组的循环队列

         队列是一种FIFO的存取方式,用数组来存储普通的队列时,一方面可能存储空间不够,另一方面容易出现“假溢出”。基于数组的循环队列避免不了第一个问题,但可以很好的解决第二个问题。下面是循环队列的结构图:

                 

          如图所示队空时rear=front,对满时rear在front的后面。顺序结构循环队列没有解决存储空间溢出的问题,在rear大于front时就会出现溢出而覆盖原有元素的现象。使得实际存储元素的个数有变化。通过用len =(rear - front + MAX_LEN)%MAX_LEN的方式来做到。

      下面是其实现代码:

/*
 * =====================================================================================
 *
 *       Filename:  3queue.h
 *
 *    Description:  template of the queue
 *
 *        Version:  1.0
 *        Created:  2012年03月13日 00时12分23秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Lavey Luo (lavey), luoyi.smt@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#ifndef __QUEUE_H__
#define __QUEUE_H__

namespace st
{
#ifndef _STATUS_CONST_
#define _STATUS_CONST_
	enum Status
	{
		OK = 0, 
		ERROR = -1
	};

	const int MAX_LEN = 20;
#endif
	template<class T>
		class queue
		{
			public:
				explicit queue():rear(0), front(1){};
				~queue(){};
			public:
			/* 初始化一个空队列Q */
			Status Init();

			/* 返回Q的元素个数,也就是队列的当前长度 */
			int Length();

			/* 若队列Q为空队列,则返回TRUE,否则返回FALSE */
			Status Empty();

			/* 将Q清为空队列 */
			Status Clear();

			/* 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR */
			Status GetHead(T *e);

			/* 若队列未满,则插入元素e为Q新的队尾元素 */
			Status EnQueue(const T e);

			/* 若队列不空,则删除Q中队头元素,用e返回其值 */
			Status DeQueue(T *e);
			private:
				int rear;
				int front;
				T data[MAX_LEN];
		};

	template<class T>
		Status queue<T>::Init()
		{
			rear = front = 0;
			return OK;
		}

	template<class T>
		Status queue<T>::Clear()
		{
			rear = front = 0;
			return OK;
		}
	template<class T>
		Status queue<T>::Empty()
		{
			if (rear == front)
				return OK;
			return ERROR;
		}

	template<class T>
		int queue<T>::Length()
		{
			return (rear - front + MAX_LEN)%MAX_LEN;
		}

	template<class T>
		Status queue<T>::GetHead(T *e)
		{
			if (rear == front)             /* 队列空 */
				return ERROR;
			*e = data[front];
			return OK;
		}

	template<class T>
	Status queue<T>::EnQueue(const T e)
	{
		if ((rear+1)%MAX_LEN== front)	/* 队列满的判断 */
			return ERROR;
		data[rear] = e;			/* 将元素e赋值给队尾 */
		rear = (rear+1)%MAX_LEN;/* rear指针向后移一位置, 若到最后则转到数组头部 */
		return  OK;
	}

	template<class T>
	Status queue<T>::DeQueue(T* e)
	{
		if (front == rear)			/* 队列空的判断 */
			return ERROR;
		*e = data[front];				/* 将队头元素赋值给e */
		front = (front+1)%MAX_LEN;	/* front指针向后移一位置, */
		/* 若到最后则转到数组头部 */
		return  OK;
	}
}
#endif

测试用例如下:


/*
 * =====================================================================================
 *
 *       Filename:  test_queue.cpp
 *
 *    Description:  testcase of queue
 *
 *        Version:  1.0
 *        Created:  2012年03月13日 10时18分30秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Lavey Luo (lavey), luoyi.smt@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include "3queue.h"
#include <stdio.h>

int test_queue(int argc,  char** argv)
{
	st::queue<int> q;
	q.Init();
	printf("初始化队列后,队列空否?%u(0:空 -1:否)\n",q.Empty());

	printf("入队前,队列长度为: %d\n",q.Length());
	for ( int i = 1; i < st::MAX_LEN ; i++)
		q.EnQueue(i);
	printf("入队后,队列长度为: %d\n",q.Length());

	int d = 0;
	q.GetHead(&d);
	printf("现在队头元素为: %d\n",d);

	printf("出队至只剩2个元素\n");
	while (q.Length() > 2)
  {
		int e = 0;
		q.DeQueue(&e);
		printf(" %d",  e);
	}	
	puts("\n");
	printf("出队后,队列长度为: %d\n",q.Length());

	q.Clear();
	printf("清空队列后, 队列空否?%u(0:空 -1:否)\n",q.Empty());
	return 0;
}


          

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值