ADT——First In First Out(FIFO)
1)插入必须从队尾进行;
2)删除必须从队头进行。
操作:
1)入队;enqueue(x) or push(x)
2)出队,同时返回删除的那个值;dequeue() or pop()
3)返回队列头部元素;front() or peek()
4)检测队列是否为空;IsEmpty()
5)如果一个队列有大小,检测该队列是否已满。IsFull()
以上操作均为时间常数,即O(1)
void Enqueue(int x); //入队
int Dequeue(); //出队,返回删除的那个值
队列,即为两端开口的管子:
![](https://i-blog.csdnimg.cn/blog_migrate/6e89ec47ab51742fc3f28c47a08cdb18.png)
如何实现?
通过数组实现队列
循环数组:
当前:i
next = (i+1)%N //N为数组的元素总个数,即 数组大小(注意:数组在开辟时即被分配空间)
previous = (i+N-1)%N = (i-1)%N
![](https://i-blog.csdnimg.cn/blog_migrate/9fbfdad04dc8aa6c96d81d93439cbc55.png)
通过链表实现队列
![](https://i-blog.csdnimg.cn/blog_migrate/7d9a29d36924b7f3645fc78d004dc423.png)
理论上用链表实现,enqueue()所需的时间为O(n)。那么不妨设置两个变量,用于存储<头>和<尾>的地址
![](https://i-blog.csdnimg.cn/blog_migrate/b494f5a3d7a7f1b1026dce28d29f04ac.png)
#include <iostream>
#include <iostream>
using namespace std;
struct Node
{
int data;
struct Node* next;
};
Node* front = NULL; //声明节点指针
Node* rear = NULL; //声明节点指针
//在队尾插入
void Enqueue(int x)
{
Node* temp = new Node; //temp作为一个局部变量,在该函数调用完成后会自动从栈上清除
temp->data = x;
temp->next = NULL;
//队列为空
if (front == NULL && rear == NULL)
{
rear = temp;
front = temp;
}
//队列不为空
else
{
rear->next = temp;
rear = temp;
}
}
//在队头删除
void Dequeue()
{
Node* temp = front; //创建temp是为了保存front地址,为了释放front
//空队列
if (front ==NULL && rear==NULL) //为空时,front rear 均为NULL
{
cout << "Error";
}
//一个
else if(front==rear)
{
front = NULL;
rear = NULL;
}
else
{
front = front->next;
}
delete temp; //其实是在释放front
}
int Front()
{
if (front == NULL) cout << "the queue is empty"<<endl;
return front->data;
}
bool Isempty()
{
if (front == NULL) return true;
return false;
}
void print()
{
Node* temp=front;
if (front != NULL)
{
cout << "the queue is:";
while (temp != NULL)
{
cout << temp->data<<' ';
temp = temp->next;
}
cout << endl;
}
else
cout << "the queue is empty"<<endl;
}
int main()
{
Enqueue(2); print();
Enqueue(4); print();
Enqueue(6); print();
Dequeue(); print();
Enqueue(8); print();
}