链表实现队列与队列原理

续:
    上一节: 队列--数组实现

上一节:队列–数组实现

创建队列并初始化

入队与出队

清空队列以及队列元素获取

1.创建并初始化
#include <iostream>
#include <iomanip>
#include <Windows.h>

#define MaxSize 5  //队列长度
using namespace std;

typedef int DataType;

typedef struct _Qnode {
 DataType data;  //int data
 struct _Qnode* next;
}QNode;

typedef QNode* QueuePtr;

typedef struct Queue {
 int length;   //队列保存的个数
 QueuePtr fron;  //队头指针 Qnode* fron
 QueuePtr rear;  //队尾指针 Qnode* rear
}LinkQueue;

//初始化
bool InitQueue(LinkQueue*LQ){
 	if (!LQ) return false;
	 LQ->length = 0; //初始化长度
	 LQ->fron = LQ->rear = NULL; //初始化队头与队尾
 	return true;
 }
2.0入队原理:
           判断队列是否为满, 在创建一个新节点,节点的数据要等于写入的数据,
           再把next置为NULL,之后就有两种情况一种是空队列,一种是有元素的队列,
           空队列就需要把头指针与尾指针指向新创建的节点,
           有元素的队列就需要在对尾插入节点qNode,然后尾部节点在指向新的节点,
           再把元素队列元素++就ok了
入队实现:
//判断队列是否为满
bool FullQueue(LinkQueue* LQ) {
 	if (!LQ) return false;
 
	 if (LQ->length == MaxSize) return true;
 	return false;
}

//判断队列是否为空
bool EmptyQueue(LinkQueue* LQ) {
 	if (!LQ) return false;
 
	 if (LQ->fron == NULL) return true;
 	return false;
}

bool EnterQueue(LinkQueue* LQ, DataType data) {
 if (!LQ) return false;
 	//判断队列是否为
if (FullQueue(LQ)) {
    cout << "无法插入元素:" << data << " 队列已满!" << endl;
 return false;
}

//创建一个节点
 	QNode* qNode = new QNode;
 //要入队的数值
	 qNode->data = data;
 //再把next置为0
	 qNode->next = NULL;

//空队列处理
 	if (EmptyQueue(LQ)) {
 	    LQ->fron = LQ->rear = qNode;
 	} else { 
  //若队列不为空:
     //就在队尾插入节点
 	 LQ->rear->next = qNode;
  //尾部指向新的节点
 	 LQ->rear = qNode;
       }
  //队列元素++
	 LQ->length++;
 return true;
}
2.1出队原理:
          创建一个临时节点,判断队列是否为空,吧要删除的节点指向临时节点,
          头节点指向下一个节点,在判断下一个节点是否存在,
          若不存在要将尾节点置空,再把元素队列--,之后释放临时节点。
//出队
bool DeleteQueue(LinkQueue* LQ, DataType* data) {
 //创建一个临时节点
 QNode* tmp = NULL;
 //判断队列是否为空
 if (!LQ || EmptyQueue(LQ)) { 
  cout << "队列为空" << endl;
  return false; 
 }
 //如果指针数据为空 则出队失败
 if (!data) return false;
 //要删除的节点指向临时节点
 tmp = LQ->fron;
 //头节点指向下一个节点
 LQ->fron = tmp->next;
 //判断下一个节点是否存在,若不存在要将尾节点置空
 if (!LQ->fron) LQ->rear = NULL;
*data = tmp->data;
 LQ->length--;
 //释放临时节点
 delete tmp;
 return true;
}
3.0清空队列原理:
	      临时节点保存头节点的下一个节点,然后删除节点,
	      在指向下一个节点,一直删除,删除之后,
	      再将前节点与尾节点置为NULL
//清空队列
bool ClearQueue(LinkQueue* LQ) {
 if (!LQ) return false;
 while (LQ->fron) {
  //临时节点保存头节点的下一个节点
  QueuePtr tmp = LQ->fron->next;
  //删除节点
  delete LQ->fron;
  //指向下一个节点
  LQ->fron = tmp;
 }
 //再将前节点和尾节点置为NIULL
 LQ->fron = LQ->rear = 0;
 //将长度也置为NULL
 LQ->length = 0;
 return true;
}
3.1队列元素获取:
	      直接返回LQ->length
//获取队列中的个数
bool GetLength(LinkQueue* LQ) {
 if (!LQ) return false;
 //直接返回length
 return LQ->length;
}
元素输出:
//输出
void Print(LinkQueue* LQ) {
 QueuePtr tmp;
 if (!LQ) return;
 //将头节点赋值给tmp
 tmp = LQ->fron;
 while (tmp) {
  //打印数据
  cout << setw(4) << tmp->data;
  //打印后换下一个打印
  tmp = tmp->next;
 }
 cout << endl;
}
main:

int main(void) {
 LinkQueue* LQ = new LinkQueue;
 DataType data = -1;

//初始化
 InitQueue(LQ);

//入队 
 for(int i=0; i<7; i++){ 
  EnterQueue(LQ, i); 
 }

//打印队列中的元素
 cout << "队列中的元素<总共" << GetLength(LQ) << "个>" << endl;
 Print(LQ);
 cout << endl;

//出队
 for (int i = 0; i < 7; i++) {
  if (DeleteQueue(LQ, &data)) {
   cout << "出队的元素是:" << data << endl;
  }
  else {
   cout << "出队失败!" << endl;
  }
 }

//打印队列中的元素
 cout << "队列剩下元素:" << GetLength(LQ) << "个" << endl;
 Print(LQ);
 cout << endl;

if (ClearQueue(LQ)) {
  cout << "清空队列成功!" << endl;
 }
 else {
  cout << "清空队列失败" << endl;
 }
 Print(LQ);

//释放元素
delete LQ;

system("pause");
 return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45140193/article/details/107935782