数据结构(二)----队列
队列介绍
队列是一种采用先进先出策略的抽象数据结构,它的想法来自于生活中排队的策略。顾客在付款结账的时候,按照到来的先后顺序排队结账,先来的顾客先结账,后来的顾客后结账。
队列的存储示意图
队列的存储结构
队列我们是从队尾进入,然后从头出去。也就是我们刚刚说的先入先出,与栈的刚刚好相反。
队列的一般操作
#include<iostream>
#include<malloc.h>
using namespace std;
typedef int datatype;
typedef struct qnode
{
datatype data;//储存数据
struct qnode *next;//指向下一节点的指针
} linklistq;
//定义头结点
typedef struct
{
// linklistq
linklistq *front,*rear;//front 头,rear 尾
}linkqueue;
linkqueue *initqueue()//初始队列
{
linkqueue *q;
linklistq *p;
q=(linkqueue *)malloc(sizeof(linkqueue));
p=(linklistq *)malloc(sizeof(linkqueue));
q->front=p;
q->rear=p;
return q;
}
int emptyqueue(linkqueue *q)//判断队列是否为空
{
if(q->front==q->rear)
return 1;
else
return 0;
}
inqueue(linkqueue *q,datatype x)
{
linklistq *p;
p = (linklistq *)malloc (sizeof(linklistq));
p->data=x;
p->next=NULL;
q->rear->next=p;
q->rear=p;
}
int dequeue(linkqueue *q,datatype *x)//出队操作
{
linklistq *p;
if(emptyqueue(q))
{
printf("队空不能输出元素!");
return 0;
}else{
p=q->front->next;
*x=p->data;
q->front->next=p->next;
if(p->next==NULL)
q->rear=q->front;
free(p);
return 1;
}
}
int getfront(linkqueue *q,datatype *x)
{
if(emptyqueue(q)){
printf("队空不能输出!!");
return 0 ;
}else{
*x=q->front->next->data;
return 1;
}
}
void showqueue(linkqueue *q)//显示操作
{
linklistq *p=q->front->next;
if(p==NULL)
printf("队空没有元素!!");
else{
printf("从队列元素起栈中的各元素为:");
while (p!=NULL)
{
printf("%3d",p->data);
p=p->next;
}
}
}
void menuqueue(){
printf("\n 队列的子系统");
printf("\n=======================================");
printf("\n 1--初始化操作队列");
printf("\n 2--入队操作");
printf("\n 3--出队操作");
printf("\n 4--求对头元素");
printf("\n 5--显示队中所有元素");
printf("\n 6--求队列长度");
printf("\n 7--清空队列");
printf("\n 0--返回");
printf("\n=======================================");
printf("\n请出入序号(0-7):");
}
void destoryqueue(linkqueue *q){
linklistq *p=q->front->next;
cout<<1;
if(p==NULL)
printf("队空没有元素!!");
else{
while(p!=NULL){
free(p);
p=p->next;
}
cout<<"队列清空";
free(q);
cout<<"头结点以清空";
}
}
int lenqueue(linkqueue *q){
linklistq *p=q->front->next;
int len =0;
while (p!=NULL)
{
len++;
p=p->next;
}
return len;
}
int main(){
int i ,n,flag;
int c =1;
int op,len;
linkqueue *q;
datatype x ;
while(c==1)
{
menuqueue();
scanf("%d",&op);
switch(op)
{
case 1:
q=initqueue();
printf("\n队的初始化完成!!");
break;
case 2:
printf("\n输入要入队的元素个数:");
scanf("%d",&n);
printf("\n请输入%d个整数",n);
for(i=0;i<n;i++){
scanf("%d",&x);
inqueue(q,x);
}
printf("\n操作完成已成功入栈!!!");
break;
case 3:
printf("\n请输入要出队的元素个数:");
scanf("%d",&n);
printf("\n出队的原素依次为:");
for(i=0;i<n;i++)
{
flag=dequeue(q,&x);
printf("%5d",x);
}
if(flag==1)
printf("\n出队操作成功");
else
printf("\n出队操作失败");
break;
case 4:
if(flag =getfront(q,&x))
printf("当前的对队元素为:%d",x);
break;
case 5:
showqueue(q);
break;
case 6:
len=lenqueue(q);
cout<<"当前队列长度为"<< len;
break;
case 7:
destoryqueue(q);
break;
case 0 :
c=2;
break;
}
}
}
特殊的队列———循环队列
循环队列示意图
循环队列来源
循环队列是我们为了解决一种叫假溢出的现象而引进的,那什么是假溢出?在顺序队列中,当队尾指针已经到数组的上界,不能再有入队操作,但其实数组中还有空位置,这就叫做“假溢出”,解决假溢出的途径---- 采用循环队列。
循环队列代码实现
#include <iostream>
using namespace std;
#define MAXSIZE 5 //最大队列长度
template<class T>
class RQueue
{
public:
RQueue()
:_base(NULL)
,_front(0)
,_rear(0)
{
_base = (T*) malloc (MAXSIZE*sizeof(T));
if(!_base)
{
cout<<"开辟空间失败"<<endl;
}
}
//返回队列元素个数
int Length()
{
return (_rear-_front+MAXSIZE)%MAXSIZE;
}
//插入元素
bool Insert(const T& x)
{
if((_rear+1)%MAXSIZE == _front)//队列满
{
cout<<"队列已满!"<<endl;
return false;
}
_base[_rear] = x;
_rear = (_rear+1)%MAXSIZE;
return true;
}
//删除元素
bool Delete()
{
if(_front == _rear)
{
cout<<"队列为空!"<<endl;
return false;
}
_front = (_front+1)%MAXSIZE;
return true;
}
private:
T* _base; //初始化的动态分配存储空间
int _front; //头指针,若队列不空,指向队列头元素
int _rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
};