数据结构--链式队列

本文详细介绍了如何使用C++实现链式队列,并讨论了队列初始化、销毁、入队和出队操作,特别强调了节点内存释放的处理,提出了通过全局变量避免重复释放内存的改进方案。
摘要由CSDN通过智能技术生成

代码区

#include<iostream>
#include<string>
using namespace std;
//设置节点类
class Node
{
public:
	int data;
	Node* next;
};
//设置链式队列类
class LinkQueue
{
public:
	LinkQueue();				//初始化链表队列
	~LinkQueue();				//释放队列的储存空间
	void EnQueue(int e);		//入队
	int DeQueue();				//出队
	int GetHead();				//获取队列队头元素
	int Empty();				//判断队列是否为空
	int GetLength();			//获取队列长度
private:
	Node* front, * rear;		//队头、队尾指针,只有设置为节点类型,才可以指向节点
	int Length;					//随时记录队列长度
};

//队列初始化
LinkQueue::LinkQueue()
{
	//设置空的头节点
	Node* s = nullptr;
	s = new Node;
	s->next = nullptr;
	//令队头队尾指针指向头节点s
	front = rear = s;
	Length = 0;
}

//队列销毁
LinkQueue::~LinkQueue()
{
	//设置一个临时的节点q(注意,并没有给他开辟堆区内存),储存front的下一个节点
	//以此,递推下去,直到最后
	Node* q;
	while (front)
	{
		q = front->next;
		delete front;
		front = q;
	}
}

//入队
void LinkQueue::EnQueue(int e)
{
	//建立一个需要置于队列中的节点
	Node* s = nullptr;
	s = new Node;
	s->data = e;
	s->next = nullptr;
	//将节点s插入到队尾(需注意)
	rear->next = s;
	rear = s;
	//队列长度加一
	Length++;
	cout << "入队成功" << endl
		 << "---------------" << endl;
}

//出队
int LinkQueue::DeQueue()
{
	//x用来储存出队的数据
	//设置一个节点用来截取需要出队的节点
	int x;
	Node* p = nullptr;
	if (rear == front)
	{
		cout << "队列为空" << endl
			 << "---------------" << endl;
	}
	p = front->next;
	x = p->data;
	front->next = p->next;
	if (rear == p)
	{
		front = rear;
	}
	else
	{
		//当出队节点为最后一个时,要交给析构函数来释放,
		//如果没有这个else,则会可能会出现内存二次释放的问题
		delete p;
	}
	//delete p;
	Length--;
	return x;
}

//获得队头
int LinkQueue::GetHead() 
{
	return front->next->data;
}

//判断是否为空
int LinkQueue::Empty() 
{
	if (front == rear) return 1;
	else return 0;
}

//获得队列长度
int LinkQueue::GetLength()
{
	return Length;
}

void test02()
{
	LinkQueue q;
	int a;
	int i = 0;

	//入队
	for (i = 0; i < 3; i++)
	{
		cout << "开始入队:" << endl;
		cin >> a;
		q.EnQueue(a);
	}

	//获取队列长度
	cout << "入队后,队列长度为:" << q.GetLength() << endl
		 << "---------------" << endl;

	//出队
	for (int j = 0; j < 3; j++)
	{
		cout << "开始出队:" << endl;
		cout << "第" << i - q.GetLength() << "位,出队内容为:" << q.DeQueue() << endl
			 << "---------------" << endl;
	}

	//获取队列长度
	cout << "出队后,队列长度为:" << q.GetLength() << endl
		 << "---------------" << endl;
}

int main()
{
	test02();
	
	system("pause");
	return 0;
}

写完代码之后的一些观点:

        该代码的难点就在于,对节点释放的处理,本代码中通过对象默认调用析构函数的方法,将队列的销毁融入,而不是单独在列出,也因此,在出列函数的释放中,可能会存在重复释放的冲突,

        一些解决这个冲突的想法,用宏将那个“截取出队的临时节点”定义为全局变量,如此,其释放,便不会限制在局部的函数中,变得灵活多变,让“出队函数”不会再包含释放内存相关的内容,将这个全局变量的释放放到“队列销毁函数”中,如此,再通过if的条件判断,进行讨论,这样,或许会更为直观的看到哪里需要避免重复释放。

        
        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值