[数据结构]队列实现、循环队列的不同实现

队列的概念:

只允许在一端进行插入,一端进行删除的特殊线性表。进行插入的称为队尾,删除一端的称为队头。队列具有先进先出的特性(FIFO)。

一、顺序队列:

1、队头不动,入队时,尾部后移一位,出队时,队头后的每一个元素向前搬移。



程序实现

#define size 10
template<class T>
class Queue
{
public:
	Queue()
		:array(new T[size])
		, front(0)
		, rear(0)
	{}

	//入队列
	void push(const T& data)
	{
		if (rear==size)
			cout << "队列已满!" << endl;
		array[rear++] = data;
	}
	//出队列
	void pop()
	{
		if (empty())
			return;
		//从前往后搬移元素
		for (size_t i = 0; i < Size(); ++i)
		{
			array[i] = array[i + 1];
		}
		rear--;
	}
	//队列元素个数
	size_t Size()
	{
		return rear;
	}
	T& first()
	{
		return array[front];
	}
	const T& first()const
	{
		return array[front];
	}
	T& Back()
	{
		return array[rear - 1];
	}
	const T& Back()const
	{
		return array[rear - 1];
	}
	bool empty()
	{
		if (front == rear)
		{
			return true;
		}
		return false;
	}

	
private:
	T* array;
	size_t front;
	size_t rear;
};
缺点:有大量的数据搬移。

2、出队列时,队头向后移动一个位置。

程序实现:

#define size 5
template<class T>
class Queue
{
public:
	Queue()
		:array(new T[size])
		, front(0)
		, rear(0)
	{}

	//入队列
	void push(const T& data)
	{
		if (rear == size)
			cout << "队列已满!" << endl;
		array[rear++] = data;
	}
	//出队列
	void pop()
	{
		front++;
	}
	//队列元素个数
	size_t Size()
	{
		return rear-front;
	}
	T& first()
	{
		return array[front];
	}
	const T& first()const
	{
		return array[front];
	}
	T& Back()
	{
		return array[rear - 1];
	}
	const T& Back()const
	{
		return array[rear - 1];
	}
	bool empty()
	{
		if (front == rear)
		{
			return true;
		}
		return false;
	}


private:
	T* array;
	size_t front;
	size_t rear;
};
缺点:会出现“假溢出”的现象。

假溢出:顺序队列因多次入队列和出队操作,出现尚有存储空间但不能进行入队列的操作而引起的溢出。

真溢出:顺序队列最大存储空间已存满而要求进入队列的操作引起的溢出。

解决假溢出的方法就是让队列头尾相接,就出现了循环队列。

二、循环队列


循环队列实现起来,当front==rear时,究竟是队满和队空?

给出三个解决方法:

1.少用一个存储单元

#define capacity 8
template<class T>
class Queue
{
public:
	Queue()
		:array(new T[capacity])
		, front(0)
		, rear(0)
	{}

	//入队列
	void push(const T& data)
	{
		if ((rear + 1) % capacity == front)
		{
			cout << "队列已满!" << endl;
		}
		else
		{
			array[rear++] = data;
			rear = rear%capacity;
		}
	}
	//出队列
	void pop()
	{
		if (rear%capacity == front%capacity)
			cout << "队列为空!" << endl;
		else
		{
			front++;
		}
	}
	//队列元素个数
	const size_t Size()const
	{
		return (rear+capacity-front)%capacity;
	}
	T& first()
	{
		return array[front%capacity];
	}
	const T& first()const
	{
		return array[front%capacity];
	}
	T& Back()
	{
		return array[(rear + capacity- 2)%(capacity - 1)];
	}
	const T& Back()const
	{
		return array[(rear + capacity - 2) % (capacity - 1)];
	}
	bool empty()
	{
		if (front == rear)
		{
			return true;
		}
		return false;
	}


private:
	T* array;
	size_t front;
	size_t rear;
};
2.标记flag

#define capacity 5
template<class T>
class Queue
{
public:
	Queue()
		:array(new T(capacity))
		,_front(0)
		,_back(0)
	{}
	
	bool flag = false;
	void push_back(const T& data)
	{
		//队满
		if (_front == _back&&flag == true)
		{
			cout << "队列已满!" << endl;
			return;
		}
		else
		{
			array[_back++] = data;
			_back %= capacity;
			flag = true;
		}
	}

	void pop_front()
	{
		if (empty())
		{
			cout << "队列为空!" << endl;
			return;
		}
		else
		{
			_front++;
			_front %= capacity;
			flag = false;
		}
	}

	const size_t Size()const
	{
		if (_front == _back)
		{
			if (flag == true)
				return capacity;
			else
				return 0;
		}
		return (_back + capacity - _front) % capacity;
	}

	T& first()
	{
		return array[_front];
	}

	const T& first()const
	{
		return array[_front];
	}

	T& back()
	{
		return array[_back - 1];
	}

	const T& back()const
	{
		return array[_back - 1];
	}

	bool empty()
	{
		if (_front == _back&&flag == false)
			return true;
		return false;
	}
private:
	T* array;
	int _front;
	int _back;
};
3.计数器count

#define N 5
template<class T>
class Queue
{
public:
	Queue()
	:_array(new T(N))
	,_front(0)
	, _rear(0)
	, count(0)
	{}

	void push_back(const T& data)
	{
		if (count == N)//判满
		{
			cout << "队列已满!" << endl;
		}
		else
		{
			_array[_rear++] = data;//将元素入队
			count++;
			if (_rear == N)//走出来了
				_rear = 0;//清零
			else
				_rear %= N;
		}
	}

	void pop_front()
	{
		if (count == 0)
			cout << "队列为空!" << endl;
		else
		{
			_front++;
			count--;
		}
	}

	const size_t Size()const 
	{
		return count;
	}

	T& first()
	{
		return _array[_front % N];
	}

	const T& first()const
	{
		return _array[_front % N];
	}

	T& back()
	{
		return _array[(_rear - 1 + N) % N];
	}

	const T& back()const
	{
		return _array[(_rear - 1 + N) % N];
	}

	bool empty()
	{
		return count == 0;
	}

private:
	T* _array;
	int _front;
	int _rear;
	int count;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值