关于队列
队列,顾名思义,也就是一条队伍,进入队伍的时候,只能从队尾排队,离开队伍的时候,只能从队首离开。队列也有数组实现和链式实现。
队列的数组实现
用一般数组实现队列的时候,入队,则在队尾插入一个元素,出队,则将队首的元素出队。那么,由于数组的长度是固定的,入队只能从队尾入队,因此经常性的出队会使得队首越来越靠近队尾,队首前面的数组空间不能被利用,导致大量的数组空间被浪费,显然这不是优秀的数据结构。
因此习惯上用循环数组实现数组实现的队列。
判断队列为空和队列未满可以有两种策略。
第一种:在队列的数据结构增加计数器counter属性
第二种:将数组中一块空间禁用。
在第一种方法下:队列的数组实现基本操作如下:
#include<iostream>
using namespace std;
#define SIZE 10
typedef struct QueueNode
{//用循环数组实现队列,用计数器counter判断队空和队满
int arr[SIZE];
int front;
int rear;
int counter;
}*ArrayQueue;
ArrayQueue CreateQueue()
{
QueueNode* Node = (QueueNode*)malloc(sizeof(QueueNode));
Node->front = 0;
Node->rear = -1;
Node->counter = 0;
return Node;
}
bool IsFull(ArrayQueue q)
{
return (q->counter == SIZE);
}
bool IsEmpty(ArrayQueue q)
{
return (q->counter = 0);
}
void EnQueue(ArrayQueue q, int val)
{
if (!IsFull(q))
{
q->rear = (q->rear + 1) % SIZE;
q->arr[q->rear] = val;
q->counter++;
}
}
void DeQueue(ArrayQueue q)
{
if (!IsEmpty(q))
{
q->front = (q->front + 1) % SIZE;
q->counter--;
}
}
int Front(ArrayQueue q)
{
int val = -1;
if (!IsEmpty(q))
{
val = q->arr[q->front];
}
return val;
}
在第二种方法下,队列的数组实现基本操作如下:
#include<iostream>
using namespace std;
#define SIZE 10
typedef struct QueueNode2
{
int arr[SIZE];
int front;
int rear;
}*ArrayQueue2;
ArrayQueue2 CreateQueue2()
{
QueueNode2* Node = (QueueNode2*)malloc(sizeof(QueueNode));
Node->front = 0;
Node->rear = -1;
return Node;
}
bool IsFull2(ArrayQueue2 q)
{
return ((q->rear+2) % SIZE ==q->front);
}
bool IsEmpty2(ArrayQueue2 q)
{
return ((q->front+1) % SIZE == q->rear);
}
void EnQueue2(ArrayQueue2 q, int val)
{
if (!IsFull2(q))
{
q->rear = (q->rear + 1) % SIZE;
q->arr[q->rear] = val;
}
}
void DeQueue2(ArrayQueue2 q)
{
if (!IsEmpty2(q))
{
q->front = (q->front + 1) % SIZE;
}
}
int Front2(ArrayQueue2 q)
{
int val = -1;
if (!IsEmpty2(q))
{
val = q->arr[q->front];
}
return val;
}
队列的链式实现
链式实现的时候,永远不用忘记,链式数据结构习惯上有一个头结点,这个头结点的数据域部分一般不用,也可以用于存储重要的信息,而头结点后面那个元素才是第一个元素。
#include<iostream>
using namespace std;
typedef struct LinkedQueueNode
{//定义结点数据结构,用于串联结点
int value;
struct LinkedQueueNode* next;
};
typedef struct LinkedQueue
{//定义队列数据结构,用于指向链式队列中的队首和队尾
LinkedQueueNode* front;
LinkedQueueNode* rear;
};
bool IsEmpty(LinkedQueue* q)
{
return (q->front == q->rear);
}
LinkedQueueNode* CreateNode()
{
LinkedQueueNode* Node = (LinkedQueueNode*)malloc(sizeof(LinkedQueueNode));
if (Node != NULL)
{
Node->value = 0;
Node->next = NULL;
}
else
{
cout << "Node applys for memory failed " << endl;
}
return Node;
}
LinkedQueue* CreateQueue()
{
LinkedQueue* Queue = (LinkedQueue*)malloc(sizeof(LinkedQueue));
LinkedQueueNode* Node = CreateNode();
if (Queue != NULL && Node != NULL)
{
Queue->front = Node;
Queue->rear = Node;
}
else
{
cout << "Queue applys for memory failed" << endl;
}
return Queue;
}
void EnQueue(LinkedQueue* q,int val)
{
LinkedQueueNode* Node = CreateNode();
if (Node != NULL)
{
Node->value = val;
q->rear->next = Node; //将队尾的下一个元素指向新元素
q->rear = q->rear->next;//将新元素的地址赋值给队尾
}
else
{
cout << "apply for memory failed" << endl;
}
}
bool UpdateNode(LinkedQueue* q,int preVal,int aftVal)
{
bool flag = false;
for (LinkedQueueNode* Node = q->front->next;q->front != q->rear; Node = Node->next)
{
if (Node->value==preVal)
{
Node->value = aftVal;
flag = true;
return flag;
}
}
return flag;
}
void DeQueue(LinkedQueue* q)
{
if (!IsEmpty(q))
{
LinkedQueueNode* Node = q->front->next;//Node是头结点的下一个元素,即第一个元素
q->front->next = Node->next;//使头结点的下一个元素指向第二个元素
if (q->rear == Node)
{//如果第一个元素是队尾,就是队列除了头结点只有一个元素
q->rear = q->front;//使队尾指向对头,这个操作由判空条件决定的
}
free(Node);
}
else
{
cout << "LinkedQueue is empty" << endl;
}
}
int Front(LinkedQueue* q)
{
if (!IsEmpty(q))
{
return (q->front->next->value);
}
else
{
cout << "LinkedQueue is empty" << endl;
return -1;
}
}
void main()
{
LinkedQueue* Queue = CreateQueue();
EnQueue(Queue, 100);
EnQueue(Queue, 200);
EnQueue(Queue, 300);
EnQueue(Queue, 400);
EnQueue(Queue, 500);
UpdateNode(Queue,300,1000);
cout << "Front : " << Front(Queue)<< endl;
DeQueue(Queue);
cout << "After Dequeue Front is : " << Front(Queue) << endl;
DeQueue(Queue);
cout << "After Dequeue Front is : " << Front(Queue) << endl;
DeQueue(Queue);
cout << "After Dequeue Front is : " << Front(Queue) << endl;
DeQueue(Queue);
cout << "After Dequeue Front is : " << Front(Queue) << endl;
DeQueue(Queue);
cout << "After Dequeue Front is : " << Front(Queue) << endl;
}
版权声明:本文为qq_31729917原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。