一、队列及其顺序存储
也是一种受约束的线性表,与堆栈不同的是,队列允许从一端插入元素,从另一端删除元素。
ADT:
类型名称:队列(队列)
数据对象集:一个有0个或多个元素的有穷线性表
操作集:长度为Maxsize的队列,初始化,判断是否已满及是否为空,插入和删除
队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成。
#define MaxSize <存储数据元素的最大个数>
struct QNode{
ElementType Data[MaxSize];
int front;
int rear;
};
typedef struct QNode* Queue;
队列的顺序存储由于考虑到不浪费空间,因而形成了环形队列,如图所示,
#include<iostream>
using namespace std;
#define MaxSize
//为了更多的利用空间,队列的存储结构呈现头对尾环状存储
typedef struct QNode* Queue;
struct QNode
{
int arr[MaxSize];
int rear;
int front;
};
//入队列
void Add(Queue Ptrq,int item)
{
if(Ptrq->rear+1)%MaxSize == Ptrq->front)//取余操作是为了判断是否满,以及得到下一个元素的位置
{
cout << "队列已满"
}
}
二、队列及其链式存储
队列的链式存储结构可以用一个单链表进行,考虑到删除操作,插入应该放在链表尾,删除放在链表头(以下代码的队列不含头指针)
#include<iostream>
using namespace std;
//队列的链式存储代码更容易理解,因为不存在空间浪费的问题
typedef struct QNode* Queue;
struct Node
{
int data;
struct Node* Next;
};
struct QNode//队列的一般表示
{
struct Node* front;//第一个结点
struct Node* rear;//最后一个结点
};
//出队,从链表头开始删除
int Delete(Queue Ptrq)
{
struct Node* FrontCell;
int DeleteElem;
if(Ptrq->front==NULL)
{
cout << "队列已空";
return 0;
}
FrontCell = Ptrq->front;
if(Ptrq->front==Ptrq->rear)
Ptrq->front = Ptrq->rear =NULL;//若队列只有一个元素,删除后front和rear都要置空,此时是个空队列
else
Ptrq->front = Ptrq->front->Next;
DeleteElem = FrontCell->data;
free(FrontCell);
return DeleteElem;//返回删除的那个元素
}
//入队,从链表尾部加入
Queue Push(int x,Queue Ptrq)
{
struct Node* p = new struct Node;
if(Ptrq->front==NULL)//空队列时
{
Ptrq->front = Ptrq->rear = p;//空表中入队时front和rear都要变,此时只有一个结点
p->data = x;
p->Next = NULL;
return Ptrq;
}
else//非空队列时
{
p->Next = NULL;
p->data = x;
Ptrq->rear->Next = p;
Ptrq->rear = p;
return Ptrq;
}
}
//初始化队列
Queue MakeEmpty()
{
Queue Ptrq = new struct QNode;
Ptrq->front = Ptrq->rear =NULL;
return Ptrq;
}
void Ergodic(Queue Ptrq);//遍历队列
int main()
{
Queue Ptrq;
Ptrq = MakeEmpty();//初始化
Ptrq = Push(100,Ptrq);//依次插入3个元素
Ptrq = Push(45,Ptrq);
Ptrq = Push(129,Ptrq);
Ergodic(Ptrq);//遍历该队列,应该打印以上3个元素
cout << Ptrq->front->data<<endl;//打印第一个结点的数
cout << Ptrq->rear->data<<endl;//打印最后一个结点的数
cout << Delete(Ptrq)<<endl;//删除第一个结点,并打印
cout << Delete(Ptrq)<<endl;//删除第二个结点,并打印
}
void Ergodic(Queue Ptrq)//遍历队列
{
struct Node* p;
p = Ptrq->front;
while(p!=NULL)
{
cout << p->data <<endl;
p = p->Next;
}
}
结果: