曾品闲的数据结构复习之三:队列(Queue)

数据结构复习——队列

一.基本概念(个人理解)

队列也是一种特殊的线性表,其限定在于只能在表的一端(尾)入队,即加入新元素,而在另一端(首)进行出队,删除操作。与栈相反,队列的特点在于“先进先出”(FIFO)。个人认为队列还是非常形象的,银行,检票口排队,行李放在传送带上接受检查的过程等等,都是队列的具体案例。

二.基本操作

对队列的基本操作有:
1.初始化队列
2.入队操作(将元素从尾部加入队列)
3.出队操作(从头部删除元素)
4.判断是否为空队列
5.清除,销毁操作
6.遍历输出整个队列的内容

三.实现分析(c++,链式)

个人认为队列用链表来实现非常舒服。队列的出队入队是较为频繁的,之前做过很多基于BFS的迷宫题,用stl库的队列时就看得出来。链式队列不用考虑队列的长度限制,添加删除都是动态的,出错的可能性也更小。而且一个单链表就能够实现,只是需要头尾指针,思路也较为清晰。

(一)数据结构设计分析

按惯例,先来节点的定义,与其他链式结构定义没有什么差别

节点用结构体来实现,包含:
存放的数据 T data
下一个节点的地址 *pnext

然后是队列My_Queue的定义,包含:

public:
 构造函数
 析构函数
 初始化队列函数init
 入队append
 出队out
 遍历traversing
 清除整个队列
 判断是否为空队列
 得到队列元素个数的函数
private:
头节点指针
尾节点指针
队列长度

(二)相关定义及声明

节点定义

template<typename T>
class Queue_Node{
public:
T data;
Queue_Node<T> *pnext;
}; 

队列定义

class My_Queue{
public:
My_Queue();
~My_Queue();
void Init_Queue();
void AppendItem(T inpdata);
T OutItem();
void Traversing();
void Queue_Clear();
bool JudgeEmpty();
int Queue_Size() const{return length;}
private:
Queue_Node<T> *head;
Queue_Node<T> *tail;
int length;
};

(三)函数实现代码

#include<iostream>
#include<string>
using std::string;
template<typename T>
class Queue_Node{
public:
T data;
Queue_Node<T> *pnext;
}; 
template<typename T>
class My_Queue{
public:
My_Queue();
~My_Queue();
void Init_Queue();
void AppendItem(T inpdata);
T OutItem();
void Traversing();
void Queue_Clear();
bool JudgeEmpty();
int Queue_Size() const{return length;}
private:
Queue_Node<T> *head;
Queue_Node<T> *tail;
int length;
};
template<typename T>
My_Queue<T>::My_Queue()
{
Init_Queue();
}
template<typename T>
My_Queue<T>::~My_Queue()
{
Queue_Clear();
std::cout<<"destruction complete"<<std::endl;
}
template<typename T>
void My_Queue<T>::Init_Queue()
{
head=NULL;
tail=NULL;
length=0;
}
template<typename T>
void My_Queue<T>::AppendItem(T inpdata)
{
Queue_Node<T> *next=new Queue_Node<T>;
next->data=inpdata;
next->pnext=NULL;
if(length==0)
{
 head=next;
 tail=next;
}
else
{
 tail->pnext=next;
 tail=tail->pnext;
}
length++;
}
template<typename T>
T My_Queue<T>::OutItem()
{
Queue_Node<T> *next_ptr;
T temp=head->data;
if(head==NULL)
{
 std::cout<<"the queue is empty"<<std::endl;
}
else if(head&&head->pnext==NULL)
{
 delete head;
 length--;
}
else
{
 next_ptr=head;
 next_ptr=next_ptr->pnext;
 delete head;
 head=next_ptr;
 length--;
}
return temp;
}
template<typename T>
void My_Queue<T>::Traversing()
{
Queue_Node<T> *trav_ptr=head;
std::cout<<"head->";
while(trav_ptr!=NULL)
{
 std::cout<<trav_ptr->data<<"|";
 trav_ptr=trav_ptr->pnext;
}
std::cout<<"->tail";
std::cout<<"\n";
}
template<typename T>
void My_Queue<T>::Queue_Clear()
{
Queue_Node<T> *next_ptr=head;
while(next_ptr!=NULL)
{
 next_ptr=next_ptr->pnext;
 delete head;
 head=next_ptr;
}
}
template<typename T>
bool My_Queue<T>::JudgeEmpty()
{
if(length>0)return false;
else return true;
}

这回就比较简洁了,边写边优化代码

(四)测试一下

int main()
{
 My_Queue<int> q1;
 int i=0;
 q1.AppendItem(1);
 q1.AppendItem(2);
 q1.AppendItem(3);
 q1.AppendItem(4);
 q1.AppendItem(5);
 q1.Traversing();
 i=q1.OutItem();
 i=q1.OutItem();
 q1.Traversing();
 return 0;
}

结果:
在这里插入图片描述
没问题,这回编译终于一遍过了,感觉写代码还是熟能生巧

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值