特殊线性表(二)队列

队列是只允许在一端进行插入操作,在一端进行删除操作的线性表,允许插入的一端称为队尾,允许删除的一段称为队头.

队列具有先进先出的特性.现实世界有许多问题可以用队列描述,比如排队.而在程序设计中,也经常使用队列记录需要先进先出的方式处理的书,比如键盘缓冲区,操作系统中的作业调度等.

1)队列的顺序实现,循环队列.

由于单纯的设置头尾指针front,rear,随着头尾指针的移动,会出现假溢出的现象.所以可以把数组看成头尾相连的循环结构,即允许队列直接从数组中最大下标位置延续到最小下标位置,通过取模操作很容易实现.

队列空满的判断条件:

空:front = rear;

满:front = rear;

为了解决队满的判定条件,可以浪费一个数组元素空间,即(rear+1)%QueueSize = front;

实现:

#define QUEUE_SIZE 10
template <class T>
class CCirQueue
{
private:
	T m_array[QUEUE_SIZE];
	int front, rear; // 头尾指针
public:
	CCirQueue();
	~CCirQueue(){}
	void EnQueue(T x); // 进队
	T DeQueue(); // 出队
	T GetQueue(); // 获取队头元素
	bool Empty();
};
template <class T>
CCirQueue<T>::CCirQueue()
{
	front = rear = 0;
}

template <class T>
void CCirQueue<T>::EnQueue(T x)
{
	if ( (rear + 1) % QUEUE_SIZE == front)
	{
		throw "队列满";
	}
	rear = (rear + 1) % QUEUE_SIZE;
	m_array[rear] = x;
}

template <class T>
T CCirQueue<T>::DeQueue()
{
	if (front == rear)
	{
		throw "队列空";
	}
	front = (front + 1)%QUEUE_SIZE;
	return m_array[front];
}

template <class T>
T CCirQueue<T>::GetQueue()
{
	if (front == rear)
	{
		throw "队列空";
	}
	int n = (front + 1) % MAX_SIZE;
	return m_array[n];
}

template <class T>
bool CCirQueue<T>::Empty()
{
	return front == rear ? true : false;
}
2)队列的链接实现,链队列.

为了满足队列的操作特性,在单链表的基础上增加尾结点.

实现:

template <class T>
class CLinkQueue
{
private:
	Node<T>* m_pFront;
	Node<T>* m_pRear; // 队头,队尾指针
public:
	CLinkQueue();
	~CLinkQueue();
	void EnQueue(T x);
	T DeQueue();
	T GetQueue();
	bool Empty();
};

template <class T>
CLinkQueue<T>::CLinkQueue()
{
	m_pFront = NULL;
	m_pRear = NULL;
}

template <class T>
void CLinkQueue<T>::EnQueue(T x)
{
	Node<T>* s = new Node<T>;
	s->m_value = x;
	s->pNextNode = NULL;
	if (m_pFront == NULL)
	{
		m_pFront = s;
	}
	if (m_pRear == NULL)
	{
			m_pRear = s;
	}else
	{
		m_pRear->pNextNode = s;
		m_pRear = s;
	}
}

template <class T>
T CLinkQueue<T>::DeQueue()
{
	if (m_pFront == m_pRear && m_pFront == NULL && m_pRear == NULL)
	{
		throw "队列为空";
	}
	Node<T> * s = m_pFront;
	int value = m_pFront->m_value;
	if (m_pFront == m_pRear)
	{
		m_pFront = NULL;
		m_pRear = NULL;
	}else
	{
		m_pFront = m_pFront->pNextNode;
	}
	delete s;
	return value;
}

template <class T>
T CLinkQueue<T>::GetQueue()
{
	if (m_pFront == m_pRear && m_pFront == NULL && m_pRear == NULL)
	{
		throw "队列为空";
	}
	return m_pFront->m_value;
}

template <class T>
bool CLinkQueue<T>::Empty()
{
	return ((m_pFront == m_pRear) && (m_pFront == NULL) && (m_pRear == NULL)); 
}

template <class T>
CLinkQueue<T>::~CLinkQueue()
{
	while (m_pFront != NULL)
	{
		DeQueue();
	}
}
3)循环队列和链队列的比较

与顺序栈和链栈的比较类似,只是循环队列不能像栈那样共享空间,通常不能在一个数组中存储两个循环队列.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值