队列的链式储存结构

      队列的链式储存结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列。(不过因为有针对队头,队尾的操作,所以我们链队列还有头指针和尾指针)

      

      链队列的结构为:

struct QNode
{
	QElemType data;//数据域
	struct QNode* next;//指针域
};
typedef struct QNode* QueuePtr;


struct LinkQueue
{
	QueuePtr front;//队头指针
	QueuePtr rear;//队尾指针
};

          

      1.创建链队列

int InitQueue(LinkQueue* L)
{
	L->front=L->rear = new QNode;//创建头结点
	L->front->next = NULL;
	if (!L->front)
		return 0;
	return 1;
}

     

      2.输出队列

void PrintQueue(LinkQueue* L)
{
	QueuePtr p = L->front->next;//用来遍历链队列
	while (p)
	{
		cout << p->data << "  ";
		p = p->next;
	}
	cout << endl;
}

      3.判断队列是否空(链队列不存在队列为满的情况)

int Judge2(LinkQueue* L)
{
	if (L->front == L->rear)
		return 0;
	return 1;
}

      

      4.入队列(注意记得将最后一个结点的指针域指向空,防止它指向一个未知的地方)

void EnQueue(LinkQueue* L, QElemType e)
{
	QueuePtr s = new QNode;
	s->data = e;
	L->rear->next = s;//把s接在目前最后一位的后面
	L->rear = s;//s变为最后一位,更新rear
	L->rear->next = NULL;
}

 

     5.出队列(注意要是只剩下最后的一个数据待出,在出队列的时候要改变尾指针rear的指向,让尾指针指向头结点,表示链队列为空)

void DeQueue(LinkQueue* L, QElemType* e)
{
	QueuePtr P = L->front->next;//用p记录即将出队列的结点
	if (P == L->rear)//链表中只剩下一个数据,在出队列时rear的指向要改变
	{
		L->rear = L->front;
	}
	L->front->next = P->next;
	*e = P->data;//将值返回到指针e指向的地址
	delete(P);
}

 

      6.清空队列(可以直接让头指针的指针域front指向null,切断头结点与其他结点的联系,让尾指针直接指向头结点)

void ClearQueue(LinkQueue* L)
{
	L->rear = L->front;//直接将尾指针移到头指针处
	QueuePtr p, q;//定义p,q来循环释放除头结点外其余结点的内存
	p = L->front->next;
	L->front->next = NULL;//直接断绝头结点和其余结点的关系
	while (p)
	{
		q = p->next;
		delete(p);
		p = q;
	}
}

      7.摧毁链队列(链队列即将清空,头指针和尾指针也没有用了,直接用头指针和尾指针遍历,删除队列。头结点也要一起摧毁)

void DestroyQueue(LinkQueue* L)
{
	//链队列即将清空,头指针和尾指针也没有用了,直接用头指针和尾指针遍历,删除队列
	
	while (L->front)
	{
		L->rear = L->front->next;
		delete(L->front);
		L->front = L->rear;
	}
}

清空和摧毁的区别就是一个没有释放头结点,一个释放了头结点

      8.队列长度

int lengQueue(LinkQueue* L)
{
	int i=0;
	QueuePtr p;
	p = L->front;
	while (p!=L->rear)
	{
		i++;
		p = p->next;
	}
	return i;
}

当然上面的写法是简便了一点点的,也可以写为

int lengQueue(LinkQueue* L)
{
	int i=0;
	QueuePtr p;
	p = L->front->next;
	while (p!=L->rear->next)
	{
		i++;
		p = p->next;
	}
	return i;
}

代码展示:

头文件PUNC.h

#pragma once
#include<iostream>
#include<ctime>
using namespace std;
typedef int QElemType;


struct QNode
{
	QElemType data;//数据域
	struct QNode* next;//指针域
};
typedef struct QNode* QueuePtr;


struct LinkQueue
{
	QueuePtr front;//队头指针
	QueuePtr rear;//队尾指针
};


//创建链队列
int InitQueue(LinkQueue* L);

//输出队列
void PrintQueue(LinkQueue* L);

//判断队列是否空
int Judge2(LinkQueue* L);

//入队列
void EnQueue(LinkQueue* L, QElemType e);

//出队列
void DeQueue(LinkQueue* L, QElemType* e);

//清空队列
void ClearQueue(LinkQueue* L);

//摧毁链表
void DestroyQueue(LinkQueue* L);

//队列长度
int lengQueue(LinkQueue* L);

源文件PUNC.cpp

#include"PUNC.h"


// 创建链队列
int InitQueue(LinkQueue* L)
{
	L->front=L->rear = new QNode;//创建头结点
	L->front->next = NULL;
	if (!L->front)
		return 0;
	return 1;
}


//输出队列
void PrintQueue(LinkQueue* L)
{
	QueuePtr p = L->front->next;//用来遍历链队列
	while (p)
	{
		cout << p->data << "  ";
		p = p->next;
	}
	cout << endl;
}


//判断队列是否空
int Judge2(LinkQueue* L)
{
	if (L->front == L->rear)
		return 0;
	return 1;
}


//入队列
void EnQueue(LinkQueue* L, QElemType e)
{
	QueuePtr s = new QNode;
	s->data = e;
	L->rear->next = s;//把s接在目前最后一位的后面
	L->rear = s;//s变为最后一位,更新rear
	L->rear->next = NULL;
}


//出队列
void DeQueue(LinkQueue* L, QElemType* e)
{
	QueuePtr P = L->front->next;//用p记录即将出队列的结点
	if (P == L->rear)//链表中只剩下一个数据,在出队列时rear的指向要改变
	{
		L->rear = L->front;
	}
	L->front->next = P->next;
	*e = P->data;//将值返回到指针e指向的地址
	delete(P);
}


//清空队列
void ClearQueue(LinkQueue* L)
{
	L->rear = L->front;//直接将尾指针移到头指针处
	QueuePtr p, q;//定义p,q来循环释放除头结点外其余结点的内存
	p = L->front->next;
	L->front->next = NULL;//直接断绝头结点和其余结点的关系
	while (p)
	{
		q = p->next;
		delete(p);
		p = q;
	}
}


//摧毁链队列
void DestroyQueue(LinkQueue* L)
{
	//链队列即将清空,头指针和尾指针也没有用了,直接用头指针和尾指针遍历,删除队列
	
	while (L->front)
	{
		L->rear = L->front->next;
		delete(L->front);
		L->front = L->rear;
	}
}


//队列长度
int lengQueue(LinkQueue* L)
{
	int i=0;
	QueuePtr p;
	p = L->front;
	while (p!=L->rear)
	{
		i++;
		p = p->next;
	}
	return i;
}

源文件text.cpp

#include"PUNC.h"
int main()
{
	cout << "欢迎调试链队列" << endl;
	LinkQueue L;//建立链队列
	srand((unsigned int)time(NULL));
	if (InitQueue(&L) == 0)
	{
		cout << "链队列创建失败" << endl;
		return 0;
	}
	cout << "链队列创建成功" << endl;
	int DBD = 1;
	int n;
	while (DBD)
	{
		system("pause");
		system("cls");
		cout << "1.输出队列  2.入队列  3.出队列  4.清空队列  5.队列的长度  6.退出队列  7.摧毁队列 " << endl;
		cin >> n;
		switch (n)
		{
		case 1:
		{
			if (Judge2(&L) == 0)
				cout << "链表为空" << endl;
			else
				PrintQueue(&L);
			break;
		}
		case 2:
		{
			QElemType e=rand()%100+1;
			EnQueue(&L, e);
			cout << "插入队列的数据为:" << e << endl;
			break;
		}
		case 3:
		{
			if (Judge2(&L) == 1)
			{
				QElemType e;//用来临时储存出队列的值
				DeQueue(&L, &e);
				cout << "出队列的值为:" << e << endl;
			}
			else
				cout << "链队列为空" << endl;
			break;
		}
		case 4:
		{
			if (Judge2(&L) == 1)
			{
				ClearQueue(&L);
				cout << "链表已清空。" << endl;
			}
			else
				cout << "链表为空" << endl;
			break;
		}
		case 5:
		{
			
			cout << "链表长度为:" << lengQueue(&L) << endl;
			break;
		}
		case 6:
		{
			DBD = 0;
			cout << "谢谢使用" << endl;
			break;
		}
		case 7:
		{
			DestroyQueue(&L);
			DBD = 0;
			cout << "队列已摧毁,谢谢使用" << endl;
			break;
		}
		}
	}
	
}

链队列完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小林想被监督学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值