基本概念
1.先进先出
2.两大基本操作:入队(队尾插入元素),出队(队头删除元素)
3.三大属性:first(队头位置),last(队尾位置),total(队列中的数据个数)
应用
1.交给打印机的作业存放在一个队列中
2.图论中的一些算法使用队列提高运行效率(还未知)
3.操作系统中用得比较多
4.不同的硬件设备传输信息时
代码实现
(1)数组实现
1.数组实现使用的是环形队列
//queue.h
#pragma once
#include "includes.h"
#define N 550
class queue
{
public:
queue(void);
bool En_queue(string add,string num,string t);
bool Del_queue();
bool Read_file(string filename);
void Print_queue();
~queue(void);
int q_first;
int q_last;
int q_total;
string q_table[N][3];
};
2.入队,需要判断是否满队,插入即将last后移一个单位,并放入数据
/**
*@name En_queue:在队列尾部插入数据
*@param1 add:插入数据——地址
*@param2 num:插入数据——序号
*@param3 t:插入数据——时间
*@ret:是否插入成功
**/
bool queue::En_queue(string add,string num,string t)
{
if(q_total==N)
{
//此时队列已满
cout<<"the queue is full"<<endl;
return false;
}
else
{
//环形队列,故尾部加1后取余,将头尾串起来
q_last=(q_last+1)%N;
q_table[q_last][0]=add;
q_table[q_last][1]=num;
q_table[q_last][2]=t;
//队列中的数据加1
q_total++;
return true;
}
}
3.出队,需要判断是否空队,删除即将first后移一个单位
/**
*@name Del_queue:删除队列首部数据
*@ret 是否删除成功
**/
bool queue::Del_queue()
{
if(q_total==0)
{
cout<<"no data can be delete"<<endl;
return false;
}
else
{
//将头部后移一个单位
q_first=(q_first+1)%N;
//队列中的数据减1
q_total--;
return true;
}
}
4.构造函数初始化,打印函数打印队列中所有数据,读取文件函数将数据从文件中读取后存入队列。
/**
*@name queue:构造函数,初始化first和last以及total
**/
queue::queue(void)
{
q_first=0;
q_last=N-1;
q_total=0;
}
/**
*@name Print_queue:打印队列所有数据
*@ret None
**/
void queue::Print_queue()
{
int i,j;
if(q_total>0)
{
i=q_first;
//首先打印队列中数据数量
cout<<"the number of queue is "<<q_total<<endl;
//利用队列中数据数量来控制遍历次数
for(j=q_total;j>0;j--)
{
for(int k=0;k<3;k++)
{
//分别打印每一个队列的数据
cout<<q_table[i][k]<<" ";
}
cout<<endl;
//i从first开始遍历队列
i=(i+1)%N;
}
}
else
{
cout<<"full queue"<<endl;
}
}
/**
*@name Read_file:从文件中读取数据插入队列,共500个数据
*@param1 filename:文件名
**/
bool queue::Read_file(string filename)
{
ifstream in(filename,ios::in);
int i,j;
//从文件流中读取数据存入中间变量
string temp_add;
string temp_num;
string temp_t;
if(!in.is_open())
{
cout<<"error"<<endl;
}
else
{
for(i=0;i<500;i++)
{
in>>temp_add;
in>>temp_num;
in>>temp_t;
if(!En_queue(temp_add,temp_num,temp_t))
{
return false;
}
}
}
in.close();
return true;
}
(2)链表实现
1.链表实现就不需要环形结构了
//queue_list.h
#pragma once
#include "includes.h"
class queue_list
{
public:
queue_list(void);
~queue_list(void);
bool En_queue_list(string add, string num,string t);
bool Del_queue_list();
void Print_queue_list();
bool Read_file(string filename);
node* ql_first;
node* ql_last;
int ql_total;
};
2.入队,新建新的节点,并分别考虑队列中无节点和多个节点的情况
/**
*@name En_queue:在队列尾部插入新的数据节点
*@param1 add:插入数据节点——地址
*@param2 num:插入数据节点——序号
*@param3 t:插入数据节点——时间
*@ret:是否插入成功
**/
bool queue_list::En_queue_list(string add, string num,string t)
{
node *temp=new node;
temp->address=add;
temp->number=num;
temp->time=t;
if(ql_first==NULL)
{
//队列中还没有节点存在时,将first和last同时指向创建的节点
ql_first=temp;
ql_last=temp;
ql_total++;
}
else
{
//将尾节点指向新节点,同时last指向新节点
ql_last->next=temp;
ql_last=temp;
ql_total++;
}
return true;
}
3.出队,考虑无节点、、一个节点和多个节点的情况。
/**
*@name Del_queue:删除队列首部节点
*@ret 是否删除成功
**/
bool queue_list::Del_queue_list()
{
if(ql_first==NULL)
{
cout<<"have no data to delete"<<endl;
return false;
}
else if(ql_first==ql_last)
{
//只有一个节点时,直接将first和last都指向NULL
ql_first==NULL;
ql_last=NULL;
ql_total--;
return true;
}
else
{
//存在多个节点时,将first向后移一个节点
ql_first=ql_first->next;
ql_total--;
return true;
}
}
4.初始化、打印中的迭代方法有些差异、读取文件数据
/**
*@name queue:构造函数,初始化first和last以及total
**/
queue_list::queue_list(void)
{
//初始化链表 first和last都为空指针
ql_first=NULL;
ql_last=NULL;
ql_total=0;
}
/**
*@name Print_queue:打印队列所有数据
*@ret None
**/
void queue_list::Print_queue_list()
{
node* i=ql_first;
cout<<"the number of queue_list is "<<ql_total<<endl;
for (int j=ql_total;j>0;j--)
{
//输出节点数据并移到下一个节点
cout<<i->address<<" "<<i->number<<" "<<i->time<<endl;
i=i->next;
}
}
/**
*@name Read_file:从文件中读取数据插入队列,共500个数据
*@param1 filename:文件名
**/
bool queue_list::Read_file(string filename)
{
ifstream in(filename,ios::in);
//从文件流中读取数据存入中间变量
string temp_add;
string temp_num;
string temp_t;
for(int i=0;i<500;i++)
{
in>>temp_add;
in>>temp_num;
in>>temp_t;
if(!En_queue_list(temp_add, temp_num,temp_t))
return false;
}
return true;
}