(1小时数据结构)数据结构c++描述(十二) --- 队列(数组与链表表示)

队列概念

        像堆栈一样,队列也是一种特殊的线性表。队列的插入和删除操作分别在线性表的两端进行,因此,队列是一个先进先出(first-in-first-out, FIFO)的线性表。

         队列(quene)是一个线性表,其插入和删除操作分别在表的不同端进行。添加新元素的那一端被称为队尾( rear ),而删除元素的那一端被成为队首 ( front )。

图像解析 :

书中给了三种公式描述:

公式一:

对应的图:

公式二:

对应图:

公式三:

对应图:

由上面可以看出,公式3是最省空间的方法,也是常说的循环队列。

开始代码:

队列的数组形式:

 

/*
数组结构中的 队列 数组与链表描述

对应书中代码:数据结构算法与应用c++描述

程序编写:比卡丘不皮

编写时间:2020年7月16日 09:56:09
*/
#pragma once
#include <iostream>
#include "all_error.h"
using namespace std;

template<class T>
class Queue
{
public:
	Queue(int MaxQueueSize = 10);
	~Queue() { delete[] queue; }
	bool IsEmpty() const { return front == rear; }
	bool IsFull() const {
		return (
			((rear + 1) % MaxSize == front) ? 1 : 0);
	}
	T First() const; //返回队首元素
	T Last() const; // 返回队尾元素
	Queue<T>& Add(const T& x);
	Queue<T>& Delete(T& x);
	int Length() const;
	void Input(istream &in)      //输入一个队列
	{
		int size;
		cout << "请输入队列的大小: ";
		cin >> size;
		cout << "请输入队列元素:  " << endl;
		for (int i = 0; i < size; i++)
		{
			T x;
			in >> x;
			Add(x);
		}
		cout << endl;
	}
	void Output(ostream &out)
	{
		int frontGet = front;
		int x;
		while (!IsEmpty())
		{
			frontGet = (frontGet + 1) % MaxSize;
			if (frontGet == rear)
			{
				cout << queue[frontGet] << " ";
				break;
			}
			else
			{
				x = queue[frontGet];
				out << x << "  ";
			}
			
		}
		cout << endl;
	}
private:
	int front; //与第一个元素在反时针方向上相差一个位置 
	int rear; // 指向最后一个元素
	int MaxSize; // 队列数组的大小
	T *queue; // 数组
};

构造函数:

template<class T>
Queue<T>::Queue(int MaxQueueSize)
{
	//创建一个容量为 MaxQueueSize 的空队列
	MaxSize = MaxQueueSize + 1;
	queue = new T[MaxSize];
	front = rear = 0;
}

First函数: 

template<class T>
 T Queue<T>::First() const
{
	 if (IsEmpty())
	 {
		 throw OutOfBounds();
	 }
	 else
	 {
		 return queue[(front + 1) % MaxSize];
	 }
	
}

 Last函数:

 template<class T>
T Queue<T>::Last() const
 {
	if (IsEmpty())
	{
		throw OutOfBounds();
	}
	else
	{
		return queue[rear]; //返回
	}
	
 }

Add函数:

template<class T>
Queue<T>& Queue<T>::Add(const T & x)
{
	if (IsFull())
	{
		throw OutOfBounds();
	}
	else
	{
		rear = (rear + 1) % MaxSize;
		queue[rear] = x;
	}
	return *this;
}

Delete函数:

template<class T>
Queue<T>& Queue<T>::Delete(T & x)
{
	if (IsEmpty())
	{
		throw OutOfBounds();
	}
	else
	{
		front = (front + 1) % MaxSize;
		x = queue[front];
	}
	return *this;
	
}

获取长度:

template<class T>
 int Queue<T>::Length() const
{
	 if (IsEmpty())
	 {
		 return 0;
	 }
	 else if (IsFull())
	 {
		 return MaxSize - 1;
	 }
	 else
	 {
		 if (rear>front)
		 {
			 return rear - front;
		 }
		 else 
		 {
			 return MaxSize - front + rear;  //记录front > rear 的长度
		 }
	 }
}

重载函数:

 //重载“>>”
 template <class T>
 istream &operator >> (istream &in, Queue<T> &Q)
 {
	 Q.Input(in);
	 return in;
 }
 //重载“<<”
 template <class T>
 ostream &operator<<(ostream &out, Queue<T> &Q)
 {
	 Q.Output(out);
	 return out;
 }

测试函数:

 void testQueue()
 {
	 Queue<int> myQueue(10);
	 cin >> myQueue;
	 cout << "myQueue length is " << myQueue.Length() << endl;

	 int value;
	 myQueue.Delete(value);
	 myQueue.Delete(value);
	 cout << "请输入你要加的数据" << endl;
	 cin >> value;
	 myQueue.Add(value);
	 myQueue.Add(value + 1);
	 myQueue.Add(value + 2);

	 cout << myQueue << endl;
	 cout << "first queue " << myQueue.First() <<
		 "secend queue is " << myQueue.Last() << endl;

 }

输出结果:

队列链表:

图像描述:

 链表队列的类定义

/*
数组结构中的 队列 数组与链表描述

对应书中代码:数据结构算法与应用c++描述

程序编写:比卡丘不皮

编写时间:2020年7月16日 2020年7月16日 11:40:55
*/
#pragma once
#include <iostream>
#include "all_error.h"
using namespace std;

template<class T>
class LinkedQueue;

template<class T>
class QueueNode
{
	friend LinkedQueue<T>; //声明后会访问私有成员
private:
	T data;
	QueueNode<T> *link;
};


template<class T>
class LinkedQueue
{
	// FIFO对象
public:
	LinkedQueue() { front = rear = 0; }
	~LinkedQueue();
	bool IsEmpty() const               //判断是否为空
	{
		return front == 0;
	}
	bool IsFull() const;               //判断队列是否已满
	T Frist() const;                   //获取队列首元素
	T Last() const;                    //获取队列末尾元素
	int Length();                      //队列长度
	LinkedQueue<T> &Add(const T &x);   //添加元素
	LinkedQueue<T> &Delete(T &x);      //删除元素
	void Input(istream &in)            //输入链表队列
	{
		T x;
		int size;                      //队列大小
		cout << "请输入队列大小:  " << endl;
		cin >> size;
		cout << "请输入队列元素:    " << endl;
		while (size && !IsFull())
		{
			in >> x;
			Add(x);
			size--;
		}
	}
	void Output(ostream &out)          //输出链表队列
	{
		if (IsEmpty())
			throw OutOfBounds();
		else
		{
			QueueNode<T> *next = front;
			while (next != 0)
			{
				out << next->data << "  ";
				next = next->link;
			}
			cout << endl;
		}
	}
private:
	QueueNode<T> *front;
	QueueNode<T> *rear;
};

其他函数定义: 

template<class T>
 LinkedQueue<T>::~LinkedQueue()
{
	 QueueNode<T> * next = new QueueNode<T>;
	 while (front)
	 {
		 next = front->link;
		 delete front;
		 front = next;
	 }
}

 template<class T>
 bool LinkedQueue<T>::IsFull() const
 {
	 QueueNode<T> *p;
	 try
	 {
		 p = new QueueNode<T>;
		 delete p;
		 return false;
	 }
	 catch (Noman)
	 {
		 return true;
	 }
 }

 template<class T>
 T LinkedQueue<T>::Frist() const
 {
	 if (IsEmpty())
	 {
		 throw OutOfBounds();
	 }
	 return front->data;
 }

 template<class T>
 T LinkedQueue<T>::Last() const
 {
	 if (IsEmpty())
	 {
		 throw OutOfBounds();
	 }
	 return rear->data;
 }

 template<class T>
 int LinkedQueue<T>::Length()
 {
	 if (front == rear)
	 {
		 return 0;
	 }
	 else
	 {
		 QueueNode<T> * next = front;
		 int len = 0;
		 while (next)
		 {
			 next = next->link;
			 len++;
		 }
		 return len;
	 }
 }

 template<class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T & x)
 {
	QueueNode<T> * p = new QueueNode<T>;
	p->data = x;
	p->link = 0;

	if (front)             //队列不为空,当前末节点指向p
		rear->link = p;
	else                   //队列为空
		front = p;           //p为队列首元素        
	rear = p;              //更新队列末节点
	return *this;	 
 }

 template<class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T & x)
 {
	if (IsEmpty())
		throw OutOfBounds();
	else
	{
		x = front->data;
		QueueNode<T> *next = front;
		front = front->link;
		delete next;
	}
	return *this;
 }

//重载“>>”
template <class T>
istream &operator >> (istream &in, LinkedQueue<T> & x)
{
	x.Input(in);
	return in;
}
//重载“<<”
template <class T>
ostream &operator<<(ostream &out, LinkedQueue<T> &x)
{
	x.Output(out);
	return out;
}

测试函数:

 

void testLinkedQueue()
{
	LinkedQueue<int> cal;
	cin >> cal;
	cout << "LinkedQueue length is" << cal.Length() << endl;
	cout << cal << endl;
	int value;
	cal.Delete(value);
	cout << "delete a num is " << value << endl;
	cout << cal << endl;
}

输出结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值