数据结构基础:队列的表示和操作实现

队列

只允许在一端进行插入操作,在另一端(队头)进行删除操作的线性表。不含任何数据元素的队列为空队列

  • 特性:先进先出
  • 两种储存表示:顺序表示和链式表示。

数据结构基础:队列的表示和操作实现_第1张图片

基本操作

  • 构造空队列
  • 销毁队列结构
  • 队列清空
  • 判空
  • 求队列长
  • 遍历队列
  • 求队头元素
  • 入队
  • 出队

一、链队列的表示和基本操作实现

采用链式储存结构,带有队头队尾指针,有头结点。

数据结构基础:队列的表示和操作实现_第2张图片
操作代码实现

#include 

using namespace std;

//1.队列链式存储结构

typedef struct QNode
{
    int data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct
{
    QueuePtr front;    //队头指针
    QueuePtr rear;     //队尾指针
}LinkQueue;           //链队列


//2.构造空队列
void InitQueue(LinkQueue &Q)
{//构造一个空队列
    Q.front=Q.rear=new QNode;
    Q.front->next=NULL;
    cout<<"队列初始化成功\n\n"<<endl;
}

//3.销毁队列
void DestoryQueu(LinkQueue &Q)
{
    while(Q.front)
    {
        Q.rear=Q.front->next;
        delete Q.front;           //低依次循环先删除头结点,然后在循环删除下一个元素结点
        Q.front =Q.rear;

    }
    cout<<"队列销毁成功"<<endl;
}


//4.判空
void QueueEmpty(LinkQueue Q)
{
    if(Q.front==Q.rear)
    {
        cout<<"该队列为空"<<endl;
    }
    else
    {
        cout<<"队列非空"<<endl;
    }
}


//5.求链队列的队头元素
void GetHead(LinkQueue Q)
{
    int e;
    if(Q.front==Q.rear)
    {
        cout<<"队列为空没有队头元素"<<endl;
    }
    else
    {
        e=Q.front->next->data;
        cout<<"队头元素为:"<<e<<endl;
    }
}


//6.入队
void EnQueue(LinkQueue &Q,int e)
{//插入元素e到队列尾部

 //1.申请一个新结点
 //2.把数据赋给新结点
 //3.把新结点的next域置为空
 //4.把原来尾部的next域指向新增的尾部
 //5.把尾部指针指向新尾部

    QueuePtr p;
    p =new QNode;
    p->data=e;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;

    cout<<"新数据元素e入队成功"<<endl;


}


//7.出队操作
void DeQueue(LinkQueue &Q)
{
    //1.判断头尾指针是否相同判断出队列是否为空
    //2.队列不为空,则设置一个新指针作为过渡,首先让它指向要出队的数据元素的结点
    //3.设置一个e让它存储出队数据元素,用来显示
    //4.把头指针指向要出队元素的下一个元素,这样就把要出队的元素的结点从链上截下来
    //5.删除结点之前,要判断出队元素是否为最后一个元素(即是否队列里就一个元素),判断依据为尾指针是否在要删除结点上
    //如果为真,则让尾指针等于头指针此时队列为空,如果队列里不止一个数据元素,则这一步不进行
    //6.删除p结点释放空间
    QueuePtr p;
    int e;
    if(Q.front==Q.rear)
    {
        cout<<"空队列"<<endl;
    }
    else
    {
        p=Q.front->next;
        e=p->data;                  //获得被删除元素
        Q.front->next=p->next;      //修改头结点指针

        if(Q.rear ==p)
        {
            Q.rear=Q.front;
        }

            delete p;
            cout<<"出队成功,且出队元素为:"<<e<<endl;
    }

}


//8.求队长
void QueuLength(LinkQueue Q)
{
    //1.设置一个变量用来记录队长
    //2.设置一个移动指针来遍历整个队列
    //3.遍历指针移动,每移动一次变量n记录一次,当遍历指针等于队尾指针则说明队长测量完毕
    int n=0;
    QueuePtr p=Q.front;

    while(p!=Q.rear)
    {
        n++;
        p=p->next;
    }
    cout<<"队列长度为"<<n<<endl;
}


//9.遍历显示队列
void ShowQueue(LinkQueue Q)
{
    int i=0;
    QueuePtr p;
    p=Q.front->next;

    if(Q.front==Q.rear)
    {
         cout<<"队列为空"<<endl;
    }
    else
    {
         while(p)
        {
           i++;
           cout<<"队列第"<<i<<"个元素为"<<p->data<<endl;
           p=p->next;
        }
    }

}


//10.清空队列
void ClearQueue(LinkQueue &Q)
{
    QueuePtr p;
    p=Q.front->next;
    while(p)
    {
        Q.front->next=p->next;
        delete p;
        p=Q.front->next;
    }

    Q.rear=Q.front;
    cout<<"队列已经清空"<<endl;
}

void show_help()
{
    cout<<"******* Data Structure ******"<<endl;
    cout<<"1----判空"<<endl;
    cout<<"2----求队列长度"<<endl;
    cout<<"3----入队"<<endl;
    cout<<"4----出队"<<endl;
    cout<<"5----求队列头元素"<<endl;
    cout<<"6----显示队列"<<endl;
    cout<<"7----清空队列"<<endl;
    cout<<"     退出,输入0"<<endl;

}
int main()
{
    int operate_code;
    show_help();
    //定义队列

    LinkQueue Q;

    //初始化
    InitQueue(Q);
    while(1)
    {
        cout<<"";
        cin>>operate_code;
        if(operate_code==1)
        {
            QueueEmpty(Q);

        }
        else if (operate_code==2)
        {
            QueuLength(Q);
        }
        else if (operate_code==3)
        {
            int e;
            cout<<"请输出您所要入队的数据元素e"<<endl;
            cin >>e;
            EnQueue(Q,e);
        }
        else if (operate_code==4)
        {
            DeQueue(Q);
        }
        else if (operate_code==5)
        {
            GetHead(Q);
        }
        else if (operate_code==6)
        {
            ShowQueue(Q);
        }
        else if (operate_code==7)
        {
            ClearQueue(Q);
        }
        else if (operate_code=='0')
        {
            break;
        }

        else
        {
            cout<<"\n操作码错误!!!"<<endl;
            show_help();
        }
    }
    //调用销毁队列
    DestoryQueu(Q);
    return 0;
}

二、循环队列的表示和实现

一组地址连续的存储单元存储

数据结构基础:队列的表示和操作实现_第3张图片

数据结构基础:队列的表示和操作实现_第4张图片

#include 

using namespace std;

//1.队列顺序存储结构(循环队列)

#define MAXQSIZE 100      //设置队列的储存最大长度
typedef struct
{
    int *base;          //储存空间的基地址
    int rear;           //头指针
    int front;          //尾指针
}SqQueue;



//2.构造空队列
void InitQueue(SqQueue &Q)
{
    Q.base =new int[MAXQSIZE];
    if(Q.base)
    {
        Q.front=Q.rear=0;
        cout<<"队列初始化成功"<<endl;
    }
    else
    {
        cout<<"队列初始化失败"<<endl;
    }
}


//3.判空
void QueueEmpty(SqQueue Q)
{
    if(Q.front == Q.rear)
    {
        cout<<"该队列为空"<<endl;
    }
    else
    {
        cout<<"该队列非空"<<endl;
    }
}


//4.求队列的队头元素
void GetHead(SqQueue Q)
{
    int e;
    if(Q.front==Q.rear)
    {
        cout<<"队列为空,无队头数据元素"<<endl;
    }
    else
    {
        e=Q.base[Q.front];
        cout<<"队头数据元素为:"<<e<<endl;
    }
}


//5.入队
void EnQueue(SqQueue &Q,int e)
{
    //1.首先判断队列是否为满,即尾指针循环加1与头指针相等则为满否则不满
    //2.不满则可以进行入队部分,原则是尾指针所指区域先获得入队元素尾指针再加一。
    //3.尾指针加一也要遵循循环取模的原则。
    if((Q.rear+1)%MAXQSIZE==Q.front)
    {
        cout<<"队列已满"<<endl;
    }
    else
    {
        Q.base[Q.rear]=e;
        Q.rear=(Q.rear+1)%MAXQSIZE;
        cout<<"数据元素"<<e<<"入队成功"<<endl;
    }
}


//6.出队
void DeQueue(SqQueue &Q)
{
    //1.首先判断该队列是否为空,条件就是头尾指针是否相同
    //2.不为空,则进行出队,首先获得出队元素e以便以后显示,
    //然后头指针需要加1指向下一个元素,但要遵循加1与最大域取模原则。
    //从这里看出出队的元素依然存在于储存空间,但下一次循环回来会进行覆盖。
    int e;
    if(Q.front==Q.rear)
    {
        cout<<"队列为空,无可出队数据元素"<<endl;
    }
    else
    {
        e=Q.front;
        Q.front=(Q.front+1)%MAXQSIZE;
        cout<<"数据元素:"<<e<<"出队成功"<<endl;
    }
}


//7.求队长
void QueueLength(SqQueue Q)
{
    int i;
    i=(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
    cout<<"队列长度为:"<<i<<endl;
}


//8.遍历显示队列
void ShowQueue(SqQueue Q)
{
   int i=Q.front;

   if(Q.front==Q.rear)
   {
       cout<<"队列为空"<<endl;
   }
   else
   {
       while(i!=Q.rear)
      {
          cout<<"队列第"<<i<<"个数据元素为"<<Q.base[i]<<endl;
          i =(i+1)%MAXQSIZE;
      }
   }

}


//9.清空队列
void ClearQueue(SqQueue &Q)
{


   if(Q.rear == Q.front)
   {
       cout<<"队列为空"<<endl;
   }
   else
   {
       Q.front = Q.rear =0;
       cout<<"队列已经清空"<<endl;
   }


}


void show_help()
{
    cout<<"******* Data Structure ******"<<endl;
    cout<<"1----判空"<<endl;
    cout<<"2----求队列长度"<<endl;
    cout<<"3----入队"<<endl;
    cout<<"4----出队"<<endl;
    cout<<"5----求队列头元素"<<endl;
    cout<<"6----显示队列"<<endl;
    cout<<"7----清空队列"<<endl;
    cout<<"     退出,输入0"<<endl;

}
int main()
{
    int operate_code;
    show_help();
    //定义队列

    SqQueue Q;

    //初始化
    InitQueue(Q);
    while(1)
    {
        cout<<"";
        cin>>operate_code;
        if(operate_code==1)
        {
           QueueEmpty(Q);
        }
        else if (operate_code==2)
        {
           QueueLength(Q);
        }
        else if (operate_code==3)
        {
            int e;
            cout<<"输入您所要入队的数据元素e: ";
            cin >>e;
            EnQueue(Q,e);
        }
        else if (operate_code==4)
        {
            DeQueue(Q);
        }
        else if (operate_code==5)
        {
            GetHead(Q);
        }
        else if (operate_code==6)
        {
            ShowQueue(Q);
        }
        else if (operate_code==7)
        {
            ClearQueue(Q);
        }
        else if (operate_code=='0')
        {
            break;
        }

        else
        {
            cout<<"\n操作码错误!!!"<<endl;
            show_help();
        }
    }
    //调用销毁队列

    return 0;
}

你可能感兴趣的:(数据结构)