队列:先进先出操作受限制的线性表
队列实现方式-链表
1. 定义队列
链队定义在线性表上切记!切记!
- font和rear都是线性表所定义的指针,都有各自的地址指向
int Qlength;
typedef struct LinkNode{
//线性表
int data;
struct LinkNode *next;
}LinkNode;
typedef struct{
//用线性表定义出头尾的链队列
LinkNode *Front,*Rear;
}LinkQueue;
}
2. 队空判断
bool Qempty(LinkQueue q){
if(q.Front == q.Rear)
//同时为空
return true;
else
return false;
3. 初始化
q.Front->next 下一个要删除的节点,初始化要设为空,但是 q.Front是非空
void init(LinkQueue &q){
q.Front = q.Rear = (LinkNode *)malloc(sizeof(LinkNode));
q.Front->next = NULL;
//建立首尾节点,为头指空
Qlength = 0;
}
4. 进队
新数据进队与线性表不同处,在赋空,s->data = c;s->next =NULL;
之后便是正常尾部入队类似于尾插法
bool Qjoin(LinkQueue &q,int c){//带头节点的单链表
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
if(s ==NULL)
return false;
s->data = c;s->next =NULL;
//数据next为空,若采用next则为线性表,且建立了两种关系,
q.Rear->next = s;
q.Rear = s;
Qlength += 1;
return true;
}
5.出队
出队可能同时涉及到队头队尾
bool Qdelete(LinkQueue &q,int &c){
if(Qlength == 0)
return false;
LinkNode *s = q.Front->next;
//其实是在操作Front的next
c = s->data;
q.Front->next = s->next;
//头结点移动
if(q.Rear == s){
//删除最后一个需要处理尾节点,空状态
q.Front =q.Rear;
}
free(s);
Qlength -= 1;
return true;
}
6. 预览-查看
观察front、rear、->next的指向,理解更清晰
void view(LinkQueue q){
LinkNode *p = q.Front->next;
LinkQueue s = q;
for(int i=0 ;i <Qlength;i++){
cout<<"i="<<i<<",data="<<p->data<<endl;
p = p->next;
}
cout<<"尾指针:"<<s.Rear<<" ,尾指针的next操作域:"<<s.Rear<<endl;
cout<<"头指针:"<<s.Front<<" ,头指针的next操作域:"<<s.Front->next<<endl;
cout<<"队列元素个数:"<<Qlength<<endl;
}
7. 测试
out << "Hello world!2021-7-10" << endl;
LinkQueue lq;
init(lq);
cout<<Qempty(lq)<<endl;
view(lq);
Qjoin(lq,45);
Qjoin(lq,5);
Qjoin(lq,4);
view(lq);
{
cout<<"进队:"<<endl;
int a;
cin>>a;
for(int i=a;i >0;i--){
int t = (i+1)*2;
cout<<"返回值:"<<Qjoin(lq,t)<<",进队数:"<<t<<endl;;
}
view(lq);
}
{
cout<<"出队:"<<endl;
int a;
cin>>a;
for(int i=a;i >0;i--){
int t=0;bool flag = Qdelete(lq,t);
cout<<"返回值:"<<flag<<",出队数:"<<t<<endl;;
}
view(lq);
}
{
cout<<"再次进队:"<<endl;
int a;
cin>>a;
for(int i=a;i>0;i--){
int t =(i+1)*2;
cout<<"返回值:"<<Qjoin(lq,t)<<",进队数:"<<t<<endl;;
}
view(lq);
}
{
cout<<"再次出队:"<<endl;
int a;
cin>>a;
for(int i=a;i>0;i--){
int t=0;bool flag = Qdelete(lq,t);
cout<<"返回值:"<<flag<<",出队数:"<<t<<endl;;
}
view(lq);
}
8. 结果分析
- 初始化申请空间130,rear->next指向130
- 进队3元素,
rear,rear->next同步变化,指向下个插入位置
- 进队3元素,```front不变,front->next改变``
- 进入4元素,返回状态,正常,尾部插入,正常,队列元素个数7,正常
- 出队5次,
front不变,front->next改变
- 再次进队,再次出队
front始终不变,front->next在数据区进行删除,指向的是要删数据的地址
- 表中只剩最后一项数据,此时front->next指向等于rear,证实6
2021,冲 冲 冲!!!