队列(FIFO)

1 队列也是一种退化的表,它在队尾(rear)入队(enqueue),在队首(front)出队(dequeue).和栈一样除了clear之外的所有操作都具有O(1)的时间复杂度。

2 循环队列是队列的一个特殊,队首作为队尾的后继,若是双向队列,那么队首的前驱也是队尾。

        作为一种最常用的线性表,它通常用作资源缓存,因此,有必要关心队列的容量,即超出容量的情况,而其设计实现,每个程序员都有自己的一套轮子,可谓五花八门。本文介绍两种最常用实现:链表实现、数组实现。

链表实现队列

#pragma once
#include <iostream>
template<typename T_data>
struct EntryQueue
{
	T_data _data;
	EntryQueue() {};
	EntryQueue(const T_data& data) :_data(data) {}
};
template<typename T_data>
struct NodeQueue
{
	EntryQueue<T_data> _entry;
	NodeQueue* _next;
	NodeQueue(NodeQueue* next) :_next(next) {}
	NodeQueue(const EntryQueue<T_data>& entry, NodeQueue* next) :_entry(entry), _next(next) {}
};

template<typename T_data>
class QueueByLink
{
public:
	static size_t constexpr MAX_CAPACITY =	1024 * 10;
public:
	QueueByLink(size_t capacity = MAX_CAPACITY);
	~QueueByLink();
	size_t size() { return _size; }
	bool empty() { return _size == 0; }
	void clear();
	NodeQueue<T_data>* enqueue(const EntryQueue<T_data>& entry);
	void dequeue();
	NodeQueue<T_data>* front();
	NodeQueue<T_data>* rear();


private:
	size_t _size, _capacity;
	NodeQueue<T_data>* _front, * _rear;
private:
	void print();
	friend void test_queuebylist();
};
void test_queuebylist()
{
	QueueByLink<int> queue_link;
	for (size_t i = 0; i < 129; i++)
	{
		EntryQueue<int> entry(i);
		queue_link.enqueue(entry);
	}
	std::cout << "\nqueue_link size after enqueue " << queue_link.size() <<",front:"<<queue_link.front()<<",rear:"<<queue_link.rear()<< std::endl;
	queue_link.print();
	for (size_t i = 0; i < 129; i++)
	{
		queue_link.dequeue();
	}
	std::cout << "\nqueue_link size after dequeue " << queue_link.size() << ",front:" << queue_link.front() << ",rear:" << queue_link.rear() << std::endl;
	queue_link.print();
	queue_link.clear();
	std::cout << "\nqueue_link size after clear " << queue_link.size() << ",front:" << queue_link.front() << ",rear:" << queue_link.rear() << std::endl;
}



template<typename T_data>
inline void QueueByLink<T_data>::clear()
{
	while (_front)
	{
		NodeQueue<T_data>* next = _front->_next;
		_front->_next = nullptr;
		delete _front;
		_front = next;
		_size--;
	}
}

template<typename T_data>
inline NodeQueue<T_data>* QueueByLink<T_data>::enqueue(const EntryQueue<T_data>& entry)
{
	NodeQueue<T_data>* node;
	if (_size > _capacity)
	{
		std::cout << "queue_by_link is full!!!\n";
		return nullptr;
	}
	node = new NodeQueue<T_data>(entry,nullptr);
	if (_rear)
	{
		_rear->_next = node;

	}
	else
	{
		_front = node;
	}
	_rear = node;
	_size++;
	return node;
}

template<typename T_data>
inline void QueueByLink<T_data>::dequeue()
{
	if (_front)
	{
		NodeQueue<T_data>* next = _front->_next;
		_front->_next = nullptr;
		delete _front;
		_front = next;
		_size--;
		if (!next)
		{
			_rear = nullptr;
		}
	}
}

template<typename T_data>
inline NodeQueue<T_data>* QueueByLink<T_data>::front()
{
	return _front;
}

template<typename T_data>
inline NodeQueue<T_data>* QueueByLink<T_data>::rear()
{
	return _rear;
}

template<typename T_data>
inline QueueByLink<T_data>::QueueByLink(size_t capacity):
	_size(0) , _capacity(capacity), _front(nullptr), _rear(nullptr)
{
	if (_capacity > MAX_CAPACITY)
	{
		_capacity = MAX_CAPACITY;
	}
}

template<typename T_data>
inline QueueByLink<T_data>::~QueueByLink()
{
	clear();
}

template<typename T_data>
inline void QueueByLink<T_data>::print()
{
	NodeQueue<T_data>* node = _front;
	while (node)
	{
		std::cout << "{" << node->_entry._data << "},";
		node = node->_next;
	}
}

数组实现

/*数组实现的每个元素就是一个条目entry*/
template<typename T_data>
class QueueByArray
{
public:
	static constexpr size_t MAX_CAPACITY = 128;
public:
	QueueByArray(const size_t capacity = MAX_CAPACITY);
	~QueueByArray();
	size_t size() { return _size; }
	bool empty() { return _size == 0; }
	void clear();
	size_t enqueue(const EntryQueue<T_data>& entry);
	void dequeue();
	size_t front();
	size_t rear();

private:
	size_t _size, _capacity;
	int64_t _front, _rear;
	std::shared_ptr<EntryQueue<T_data>>* _array;
private:
	void print();
	friend void test_queuebyarray();
};

template<typename T_data>
inline QueueByArray<T_data>::QueueByArray(const size_t capacity):
	_size(0),_capacity(capacity), _front(-1), _rear(-1)
{
	if (_capacity > MAX_CAPACITY)
	{
		_capacity = MAX_CAPACITY;
	}
	_array = new std::shared_ptr<EntryQueue<T_data>>[_capacity];
}

template<typename T_data>
inline QueueByArray<T_data>::~QueueByArray()
{
	delete[] _array;
}

template<typename T_data>
inline void QueueByArray<T_data>::clear()
{
	_front = _rear;
}

template<typename T_data>
inline size_t QueueByArray<T_data>::enqueue(const EntryQueue<T_data>& entry)
{
	if (_front == -1) _front++ ;//首个元素
	if (_rear == (_capacity - 1))
	{
		std::cout << "\nQueueByArray Is Full!!!" << std::endl;
		return -1;
	}
	_array[++_rear] = std::make_shared<EntryQueue<T_data>>(entry);
	_size++;
	return _rear;
}

template<typename T_data>
inline void QueueByArray<T_data>::dequeue()
{
	if (_front < 0 || _front >= _capacity)
	{
		std::cout << "\nQueueByArray invalid position " << _front << std::endl;
		return;
	}
	else
	{
		_front++;
	}
	_size--;
}

template<typename T_data>
inline size_t QueueByArray<T_data>::front()
{
	return _front;
}

template<typename T_data>
inline size_t QueueByArray<T_data>::rear()
{
	return _rear;
}

template<typename T_data>
inline void QueueByArray<T_data>::print()
{
	for (size_t i = _front; i <= _rear; i++)
	{
		std::shared_ptr<EntryQueue<T_data>> &entry = _array[i];
	
		std::cout << entry->_data << ",";
	}
}

inline void test_queuebyarray()
{
	QueueByArray<int> queue_array;
	for (size_t i = 0; i < 129; i++)
	{
		EntryQueue<int> entry(i);
		queue_array.enqueue(entry);
	}
	std::cout << "queue_array size after enqueue " << queue_array.size()<<std::endl;
	queue_array.print();
	for (size_t i = 0; i < 129; i++)
	{
		queue_array.dequeue();
	}
	std::cout << "\nqueue_array size after dequeue " << queue_array.size() << std::endl;
	queue_array.print();
	queue_array.clear();
	std::cout << "\nqueue_array size after clear " << queue_array.size() << ",front:" << queue_array.front() << ",rear:" << queue_array.rear() << std::endl;
}

测试

#include <iostream>
#include "myqueue.hpp"

int main()
{
    test_queuebyarray();
    std::cout << "\n\n";
    test_queuebylist();
}

结果

总结:当节点数目较少,建议使用数组实现,效率更高,需要更高容量的使用链表实现 。

  • 24
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值