数据结构笔记

25、队列的算法实现(链表)

数组实现的队列在出队时,每出去一个数据,其他数据就得向前移动(方法1),效率比较低,方法2中移动队首指针,但是队列空间有限,队首指针一直往后移动会出现溢出,使用链表存储,插入删除数据的时候不需要移动数据。
队列的链式存储结构,其实就是线性表的单链表,只不过它只是尾进头出而已,我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端节点。请添加图片描述
1、链队列的初始化

#define MaxSize 5
typedef int DataType;

typedef struct _QNode{
	DataType data;
	struct _QNode *next;
}QNode;

typedef QNode* QueuePtr;

typedef struct Queue{
	int length;
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;
//队列的初始化、将队列初始化为空队列
void InitQueue(LinkQueue *LQ){
	if(!LQ)return;
	
	LQ->length = 0;
	LQ->front = LQ->rear = NULL;//把队头和队尾指针同时置空
}

2、判断队列是否为空、队列是否已满

int IsEmpty(LinkQueue *LQ){
	if(!LQ)return 0;
	
	if(LQ->front == NULL){
		return 1;
	}
	return 0;
}
int IsFull(LinkQueue *LQ){
	if(!LQ)return 0;
	
	if(LQ->length == MaxSize){
		return 1;
	}
	return 0;
}

3、入队,将元素data插入到队列LQ中
在这里插入图片描述

int EnterQueue(LinkQueue *LQ,DataType data){
	if(!LQ)return 0;
	
	if(isFull(LQ)){
		cout<<"无法插入元素"<<data<<",队列已满"<<endl;
		return 0;
	}
	
	QNode *qNode = new QNode;
	qNode->next = NULL;
	qNode->data = data;

	if(isEmpty(LQ)){//空队列插入
		LQ->rear->next=qNode;//在队尾插入节点qNode
		LQ->rear = qNode;	//队尾指向新插入的节点
	}
	LQ->length++;
	return 1;
}

4、出队,将队列中队头的元素出队,其后的第一个元素成为新的队首
在这里插入图片描述

int DeleteQueue(LinkQueue*LQ,DataType* data){
	QNode *tmp = NULL;
	
	if(!LQ || IsEmpty(LQ)){
		cout<<"队列为空!"<<endl;
		return 0;
	}
	if(!data)return 0;
	tmp = LQ->front;

	LQ->front = tmp->next;
	if(!LQ->front)LQ->rear = NULL;//如果队头出列后不存在其他元素,则rear节点要置空
	*data = tmp->data;
	LQ->length--;
	
	delete tmp;
	return 1;
}

5、打印队列中的元素

void PrintQueue(LinkQueue *LQ){
	QueuePtr tmp;
	if(!LQ)return;
	if(LQ->front ==NULL){
		cout<<"队列为空!";
		return;
	}
	tmp = LQ->front;
	while(tmp){
		cout<<setw(4)<<tmp->data;
		tmp= tmp->next;
	}
	cout<<endl;
}

6、获取队首元素、不出队

int GetHead(LinkQueue *LQ,DataType *data){
	if (!LQ || IsEmpty(LQ)) {
		cout << "队列为空!" << endl;
		return 0;
	}
	if (!data)return 0;
	
	*data = LQ->front->data;
	return 1;
}

7、清空队列

void ClearQueue(LinkQueue *LQ){
	if(!LQ)return;
	
	while(LQ->front){
		QueuePtr tmp = LQ->front->next;
		delete LQ->front;
		LQ->front = tmp;	
	}
	LQ->front = LQ->rear = NULL;
	LQ->length = 0;
}

8、获取队列中的元素

int getLength(LinkQueue*LQ) {
	if (!LQ)return 0;

	return LQ->lenth;
}

主函数

int main(void){
	LinkQueue *LQ = new LinkQueue;
	DataType data = -1;
	
	//初始化队列
	InitQueue(LQ);

	//入队
	for(int i = 0 ; i<7;i++){
		EnterQueue(LQ,i);
	}
	//打印队列中的元素
	printf("队列中的元素(总共是%d个):",getLength(LQ));
	PrintQueue(LQ);
	cout<<endl;
	
	//出队
	for(int i = 0;i<10;i++){
		if(DeleteQueue(LQ,&data)){
			cout << "出队的元素是:" << data << endl;
		}else{
			cout << "出队失败!" << endl;
		}
	}
	//打印队列中的元素
	printf("出队一个元素后,队列中剩下的元素[%d]:", getLength(LQ));
	PrintQueue(LQ);
	cout << endl;
	
		ClearQueue(LQ);
	cout << "清空队列!\n";
	PrintQueue(LQ);

	//清理资源
	delete LQ;

	system("pause");
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值