线性表——队列的c++实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


队列

队列: 是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一一样,队列是一种操作受限的线性表。进行插入操作的端称队尾,进行插入操作的端称为队尾,进行删除操作的端称为队头;

队列的特点: 先进先出;

队列中有两个值,一个是front记录队头的位置,另一个是rear记录队尾的位置。

在这里插入图片描述
在实际应用时,由于数组队列的缺点是由于一端插入一端删除,当不断从头部删除数据,头部会大量留有空闲内存,无法插入,造成空间流失,这种属于假溢出的情况。但如果将队头指针在每次删除之后往前移动一个位置,这是一个时间复杂度为O(n)的操作。因此,通常将队列设计为循环队列来克服上述问题。

循环队列: 可以看作是一个环形结构。有一个maxsize表示数组的长度。当队列未满,并且队头已经到达了maxsize的位置,再次插入数据的时候,队头则从0位置开始插入。

在这里插入图片描述
在设计的时候,一般要注意以下几点:

(1)队列初始化时,front和rear值都为零。

(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置。

(3)当队列为空时,front与rear的值相等,但不一定为零。

循环队列满的时候会满足这个计算公式 : (rear+1)%maxsize=front

计算循环队列长度 : (rear-front+maxsize)%maxsize


c++的代码实现

1.数组实现

首先定义一个Queue类

class Queue
{
private:
	ElemType *_data;
	int _head;
	int _tail;
	bool IsFull();
	bool IsEmpty();
public:
	Queue();
	Queue(const Queue &src);
	Queue& operator= (const Queue& src);
	~Queue();
	bool Push(ElemType val);
	bool Pop();
	ElemType GetQue();
	void show();
};

判空和判满的实现

bool Queue::IsFull()
{
	assert(this != NULL);
 
	if ((_tail + 1) % SIZE == _head)
	{
		return true;
	}
 
	return false;
}
bool Queue::IsEmpty()
{
	assert(this != NULL);
 
	if (_head == _tail)
	{
		return true;
	}
 
	return false;
}

出队列、入队列、获得队头的数据的功能实现

bool Queue::Push(ElemType val)
{
	assert(this != NULL);
 
	if (IsFull())
	{
		return false;
	}
 
	_data[_tail++] = val;
	_tail %= SIZE;
 
	return true;
}
bool Queue::Pop()
{
	assert(this != NULL && _data != NULL);
 
	if (IsEmpty())
	{
		return false;
	}
 
	_head++;
	_head %= SIZE;
 
	return true;
}
ElemType Queue::GetQue()
{
	assert(this != NULL);
 
	if (IsEmpty())
	{
		return 0;
	}
 
	return _data[_head];
}
 

2.链表实现

2.1 单向链表实现

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

struct Node
{
	int val;
	Node* next;
	Node(int v) : val(v),next(nullptr)
	{
	}
};

class Queue
{
	int size;
	Node* head;
	Node* back;
public:
	Queue() : size(0),head(nullptr),back(nullptr){}
	bool empty(){ return 0 ==  size;}
	Node* front()
	{
		return head;
	}
	Node* push_back(int v)
	{
		if(0 == size)
		{
			head->next = head = back = new Node(v);
		}
		else if(1 == size)
		{
			head->next = back = new Node(v);
		}
		else
		{
			
		}
	}
};

2.2 双向链表实现

#include <iostream>
using namespace std;

typedef struct node
{
	int data;
	node* prev;
	node* next;
}Node;

typedef struct queue
{
	Node* front;
	Node* rear;
}LinkDQueue;
				
void En_DQueuelist(LinkDQueue* q,int e);				//入队函数
int De_DQueuelist(LinkDQueue* q);						//出队函数
void Print_DQueuelist(LinkDQueue* q);					//打印队列
int Getlength_DQueuelist(LinkDQueue* q);            //计算双端队列长度函数

//创建双端队列函数
LinkDQueue* Creat_DQueuelist() 
{
	LinkDQueue* queue = new LinkDQueue;
	queue->front = queue->rear = new Node;
	queue->front->data = 0;
	queue->front->prev = NULL;
	queue->front->next = NULL;
	queue->rear->next = NULL;
	int length = 0;
	int number = 0;
	cout << "请输入双端队列长度:";
	cin >> length;
	if (!length) 
	{
		return queue;
	}
	cout << "请输入双端队列数据:";
	for (int i = 0; i < length; i++) //端口2创建双端队列
	{
		Node* pnew = new Node;
		if (!pnew)
			cout << "内存分配失败!" << endl;
		cin >> number;
		pnew->data = number;
		pnew->next = NULL;
		queue->rear->next = pnew;
		pnew->prev = queue->rear;
		queue->rear = pnew;
	}
	return queue;
}

void En_DQueuelist(LinkDQueue* q, int e) {
	int n = 0;
	Node* tmp = new Node;
	tmp->data = e;
	cout << "请输入顺序入队端口:";
	cin >> n;
	if (q->front == q->rear) {
		q->rear->next = tmp;
		tmp->prev = q->rear;
		tmp->next = NULL;
		q->rear = tmp;
		return;
	}
	switch (n) {
	case 1:
		tmp->next = q->front->next;
		q->front->next->prev = tmp;
		q->front->next = tmp;
		tmp->prev = q->front;
		break;
	case 2:
		tmp->next = NULL;
		q->rear->next = tmp;
		tmp->prev = q->rear;
		q->rear = tmp;
		break;
	}
}
 
int De_DQueuelist(LinkDQueue* q) {
	int data = INT_MAX;
	if (!q || q->front == q->rear) {
		cout << "队列为空!" << endl;
		return data;
	}
	int n = 0;
	Node* tmp = NULL;
	cout << "请输入顺序出队端口:";
	cin >> n;
	switch (n) {
	case 1:
		tmp = q->front->next;
		data = tmp->data;
		q->front->next = tmp->next;
 
		if (q->rear == tmp) {
			q->rear = q->front;
		} else {
			tmp->next->prev = q->front;
		}
		delete tmp;
		return data;
	case 2:
		tmp = q->rear;
		data = tmp->data;
		tmp->prev->next = NULL;
		q->rear = tmp->prev;
//		tmp->prev = NULL;
		delete tmp;
		return data;
	}
}
 
void Print_DQueuelist(LinkDQueue* q) {
 
	int n = 0;
	Node * tmp = NULL;
	cout << "请输入顺序打印端口:";
	cin >> n;
	switch (n) {
	case 1:
		tmp = q->front->next;
		while (tmp) {
			cout << tmp->data << ' ';
			tmp = tmp->next;
		}
		break;
	case 2:
		tmp = q->rear;
		while (tmp != q->front) {
			cout << tmp->data << ' ';
			tmp = tmp->prev;
		}
		break;
	}
}
 
int Getlength_DQueuelist(LinkDQueue* q) {
	int length = 0;
	Node* tmp = q->front->next;
	while (tmp) {
		length++;
		tmp = tmp->next;
	}
	return length;
}

int main() 
{
	LinkDQueue* queue = Creat_DQueuelist();
	Print_DQueuelist(queue);
	cout << "length: " << Getlength_DQueuelist(queue) << endl;
 
	En_DQueuelist(queue, 4);
	Print_DQueuelist(queue);
	cout << "length: " << Getlength_DQueuelist(queue) << endl;
 
	int data = De_DQueuelist(queue);
	if (data != INT_MAX) {
		cout << "删除元素:" << data << endl;
	}
	Print_DQueuelist(queue);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值