数据结构与算法 (单)链队列

数据结构与算法 (单)链队列

单链表实现队列

1.初始化队列

首先创建单链表,和队列结构,在队列结构中定义两个指针变量front、rear,分别用来指向队列的首部和为尾部。判断队列是否为空,是否已满。

#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; //把对头和队尾指针同时置 0
}

//判断队列为空 
bool IsEmpty(LinkQueue *LQ) {
    
     
	if(!LQ) return 0; //不为空

	if (LQ->front == NULL)
	{
    
    
		return true;
	}
	return false;
}

//判断队列是否为满 
bool IsFull(LinkQueue *LQ) {
    
     
	if(!LQ) return false; //不为空

	if (LQ->length == MaxSize) {
    
     
		return true; 
	}
	return false; 
}

2.入队,向队列中插入元素

防御式判断队列各种不成立条件,无误后分配新节点,遵循队列规则,则(新节点)该节点为尾节点,所以next指针置为空。 若该当前队列为空队列,那么此节点就为首节点和尾节点,将首节点指针和尾节点指针同时指向该节点,否则队首指针不动,将队尾指针指向当前节点的next指针指向新节点,后将尾指针指向新节点。

//入队,将元素 data 插入到队列 LQ 中 
bool EnterQueue(LinkQueue *LQ,DataType data){
    
     
	if(!LQ) return false; 

	if(IsFull(LQ)){
    
     
		cout<<"无法插入元素 "<<data<<", 队列已满!"<<endl; 
		return false;
	}

	QNode *qNode = new QNode;//分配新节点
	qNode->data = data;
	qNode->next = NULL;		 //将新节点的next指针置为空(先进先出原则)

	if(IsEmpty(LQ)){
    
    //空队列(新插入节点为首节点)
		LQ->front = LQ->rear = qNode;//此插入节点为第一个节点也是最后一个节点
	}else {
    
     
		LQ->rear->next =qNode;//在队尾插入节点 qNode(队尾节点next指针指向新节点--实现插入)
		LQ->rear = qNode; //队尾指向新插入的节点(队尾指针指向新节点为尾节点)
	}

	LQ->length++;//队列长度加1
	return true; 
}

3.出队,删除队首

定义一个临时变量保存首节点,以便释放内存。

//出队,将队列中队头的元素出队,其后的第一个元素成为新的队首 
bool DeleteQueue(LinkQueue *LQ, DataType *data){
    
     
	QNode * tmp = NULL;//临时变量,用来保存要被释放掉资源的队首

	if (!LQ || IsEmpty(LQ)) {
    
    
		cout << "队列为空!" << endl;
		return false;
	}

	if (!data) return false; 
	tmp = LQ->front;   //保存队首节点

	LQ->front = tmp->next;//将队首指针指向原首节点的下一个节点
	if (!LQ->front) LQ->rear = NULL;//如果队头出列后不存在其他元素,则 rear 节点也要置空 

	*data = tmp->data;
	LQ->length--;    //队列长度减1

	delete tmp;      //释放内存

	return true; 
}

其他功能在完整代码中,实现与顺序队列大体相同,只是实现方式不同而已。

完整代码

#include <stdio.h> 
#include <Windows.h> 
#include <iostream> 
#include <iomanip> 

using namespace std;

#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; //把对头和队尾指针同时置 0
}

//判断队列为空 
bool IsEmpty(LinkQueue *LQ) {
    
     
	if(!LQ) return 0; //不为空

	if (LQ->front == NULL)
	{
    
    
		return true;
	}
	return false;
}

//判断队列是否为满 
bool IsFull(LinkQueue *LQ) {
    
     
	if(!LQ) return false; //不为空

	if (LQ->length == MaxSize) {
    
     
		return true; 
	}
	return false; 
}

//入队,将元素 data 插入到队列 LQ 中 
bool EnterQueue(LinkQueue *LQ,DataType data){
    
     
	if(!LQ) return false; 

	if(IsFull(LQ)){
    
     
		cout<<"无法插入元素 "<<data<<", 队列已满!"<<endl; 
		return false;
	}

	QNode *qNode = new QNode;//分配新节点
	qNode->data = data;
	qNode->next = NULL;		 //将新节点的next指针置为空(先进先出原则)

	if(IsEmpty(LQ)){
    
    //空队列(新插入节点为首节点) 
		LQ->front = LQ->rear = qNode;//此插入节点为第一个节点也是最后一个节点
	}else {
    
     
		LQ->rear->next =qNode;//在队尾插入节点 qNode(队尾节点next指针指向新节点--实现插入)
		LQ->rear = qNode; //队尾指向新插入的节点(队尾指针指向新节点为尾节点)
	}

	LQ->length++;//队列长度加1
	return true; 
}

//出队,将队列中队头的元素出队,其后的第一个元素成为新的队首 
bool DeleteQueue(LinkQueue *LQ, DataType *data){
    
     
	QNode * tmp = NULL;//临时变量,用来保存要被释放掉资源的队首

	if (!LQ || IsEmpty(LQ)) {
    
    
		cout << "队列为空!" << endl;
		return false;
	}

	if (!data) return false; 
	tmp = LQ->front;   //保存队首节点

	LQ->front = tmp->next;//将队首指针指向原首节点的下一个节点
	if (!LQ->front) LQ->rear = NULL;//如果队头出列后不存在其他元素,则 rear 节点也要置空 

	*data = tmp->data;
	LQ->length--;    //队列长度减1

	delete tmp;      //释放内存

	return true; 
}

//打印队列中的各元素 
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; 
}

//获取队首元素,不出队 
bool GetHead(LinkQueue *LQ,DataType *data) {
    
     
	if (!LQ || IsEmpty(LQ)){
    
    
		cout << "队列为空!" << endl; 
		return false;
	}
	
	if (!data) return false;

	*data = LQ->front->data; 
	return true;
}

//清空队列 
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;
}

//获取队列中元素的个数 
int getLength(LinkQueue* LQ){
    
     
	if(!LQ) return 0; 

	return LQ->length;
}

int main() {
    
     
	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; 
}

おすすめ

転載: blog.csdn.net/qq_45337964/article/details/103050924