队列的基本概念详解,循环队列、链式队列的C++详细实现

简介: 一、队列是什么?二、循环队列1.知识点概述 2.动态分配 3.初始化4.入队 5.出队 6. 取对头元素7.取队列长度 8.总的代码三 、链式链表 1.链队列的结构 2.链队列入队

目录

一、队列是什么?

二、循环队列

1.知识点概述

2.动态分配

3.初始化

4.入队

5.出队

6. 取对头元素

7.取队列长度

8.总的代码

三 、链式链表

1.链队列的结构

2.链队列入队

 


一、队列是什么?

队列是只允许在一端进行的插入操作,而在另一端进行删除操作的线性表

image.png

二、循环队列

1.知识点概述

队列的顺序存储形式,可以用一段连续的空间存储数据元素,用两个整型变量记录队头和队尾元素的下标。

image.png

2.动态分配


image.png

3.初始化

image.png

//循环队列的初始化
bool InitQueue(SqQueue &Q)//注意使用引用参数,否则出了函数,其改变无效
{
  Q.base=new int[Maxsize];//分配空间
  if(!Q.base) return false;
  Q.front=Q.rear=0; //头指针和尾指针置为零,队列为空
  return true;
}

4.入队

由于对头进行删除,对尾进行增加持续的增加会导致数组的末尾没有空间,但是数组前面由于进行了删除操作会导致,前面有空余的位置,这种现象叫“假溢出”

image.png

可以进行以下操作

//循环队列的入队
bool EnQueue(SqQueue &Q,int e)//将元素e放入Q的队尾
{
  if((Q.rear+1)%Maxsize==Q.front) //尾指针后移一位等于头指针,表明队满
    return false;
  Q.base[Q.rear]=e; //新元素插入队尾
  Q.rear=(Q.rear+1)%Maxsize; //队尾指针加1
  return true;
}

5.出队

代码如下

//循环队列的出队
bool DeQueue(SqQueue &Q, int &e) //删除Q的队头元素,用e返回其值
{
  if (Q.front==Q.rear)
    return false; //队空
  e=Q.base[Q.front]; //保存队头元素
  Q.front=(Q.front+1)%Maxsize; //队头指针加1
  return true;
}

6. 取对头元素

代码如下

//取循环队列的队头元素
int GetHead(SqQueue Q)//返回Q的队头元素,不修改队头指针
{
  if (Q.front!=Q.rear) //队列非空
    return Q.base[Q.front];
    return -1;
}

7.取队列长度

代码如下

//循环队列的长度
int QueueLength(SqQueue Q)
{
  return (Q.rear-Q.front+Maxsize)%Maxsize;
}

8.总的代码

代码如下

#include <iostream>
using namespace std;
#define Maxsize 100
typedef  struct SqQueue{
  int *base; //基地址
  int front,rear; //头指针,尾指针
}SqQueue;
//循环队列的初始化
bool InitQueue(SqQueue &Q)//注意使用引用参数,否则出了函数,其改变无效
{
  Q.base=new int[Maxsize];//分配空间
  if(!Q.base) return false;
  Q.front=Q.rear=0; //头指针和尾指针置为零,队列为空
  return true;
}
//循环队列的入队
bool EnQueue(SqQueue &Q,int e)//将元素e放入Q的队尾
{
  if((Q.rear+1)%Maxsize==Q.front) //尾指针后移一位等于头指针,表明队满
    return false;
  Q.base[Q.rear]=e; //新元素插入队尾
  Q.rear=(Q.rear+1)%Maxsize; //队尾指针加1
  return true;
}
//循环队列的出队
bool DeQueue(SqQueue &Q, int &e) //删除Q的队头元素,用e返回其值
{
  if (Q.front==Q.rear)
    return false; //队空
  e=Q.base[Q.front]; //保存队头元素
  Q.front=(Q.front+1)%Maxsize; //队头指针加1
  return true;
}
//取循环队列的队头元素
int GetHead(SqQueue Q)//返回Q的队头元素,不修改队头指针
{
  if (Q.front!=Q.rear) //队列非空
    return Q.base[Q.front];
    return -1;
}
//循环队列的长度
int QueueLength(SqQueue Q)
{
  return (Q.rear-Q.front+Maxsize)%Maxsize;
}
int main()
{
  SqQueue Q;
  int n,x;
  InitQueue(Q);//初始化队列(一定要初始化,否则后面存储出错)
  cout <<"请输入元素个数n:" <<endl;
  cin>>n;
  cout <<"请依次输入n个整型数,依次入队:" <<endl;
    while(n--)
    {
        cin>>x;
    EnQueue(Q,x);//入队
    }
    cout<<endl;
    cout <<"队列内元素个数,即长度:"<<QueueLength(Q)<<endl;
    cout <<"队头元素:" <<GetHead(Q)<<endl;
  cout <<"元素依次出队:" <<endl;
  while(true)//如果栈不空,则依次出栈
    {
        if(DeQueue(Q,x))
            cout<<x<<"\t";//出队元素
        else
            break;
    }
    cout <<endl;
    cout <<"队列内元素个数,即长度:"<<QueueLength(Q)<<endl;
  return 0;
}

三 、链式链表

1.链队列的结构

typedef int ElemType;   //ElemType 根据实际情况而定,这里假定为int型   
typedef struct LinkNode{         //结点结构
  ElemType data;
  struct LinkNode *next;
}LinkNode;
typedef struct LinkQueue {       //队列的链式结构
  LinkNode *front, *rear;      //对头,对尾指针
}LinkQueue

2.链队列入队

image.png

void EnQueue(LinkQueue &Q, ElemType e) {
  LinkNode *s = (LinkNode*)malloc(sizeof(LinkNode));
  s->data = e;
  s->next = NULL;
  Q.rear->next = s;      //把拥有元素e新结点s赋值给原对尾结点的后继
  Q.rear = s;            //把当前s结点设为队尾结点,rear指向s
}


相关文章
|
2天前
|
程序员 C++ 开发者
C++入门教程:掌握函数重载、引用与内联函数的概念
通过上述介绍和实例,我们可以看到,函数重载提供了多态性;引用提高了函数调用的效率和便捷性;内联函数则在保证代码清晰的同时,提高了程序的运行效率。掌握这些概念,对于初学者来说是非常重要的,它们是提升C++编程技能的基石。
5 0
|
3月前
|
JSON Go C++
开发与运维C++问题之在iLogtail新架构中在C++主程序中新增插件的概念如何解决
开发与运维C++问题之在iLogtail新架构中在C++主程序中新增插件的概念如何解决
37 1
|
2月前
|
存储 设计模式 算法
【C++】deque以及优先级队列
【C++】deque以及优先级队列
|
3月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第4天】C++20引入了Concepts,提升模板编程的类型约束和可读性。概念定义了模板参数需遵循的规则。常见问题包括过度约束、约束不完整和重载决议复杂性。避免问题的关键在于适度约束、全面覆盖约束条件和理解重载决议。示例展示了如何用Concepts限制模板函数接受的类型。概念将增强模板的安全性和灵活性,但需谨慎使用以防止错误。随着C++的发展,Concepts将成为必备工具。
67 2
|
4月前
|
设计模式 存储 C++
【C++/STL】:stack/queue的使用及底层剖析&&双端队列&&容器适配器
【C++/STL】:stack/queue的使用及底层剖析&&双端队列&&容器适配器
59 2
|
4月前
|
C++
C++一分钟之-继承与多态概念
【6月更文挑战第21天】**C++的继承与多态概述:** - 继承允许类从基类复用代码,增强代码结构和重用性。 - 多态通过虚函数实现,使不同类对象能以同一类型处理。 - 关键点包括访问权限、构造/析构、菱形问题、虚函数与动态绑定。 - 示例代码展示如何创建派生类和调用虚函数。 - 注意构造函数初始化、空指针检查和避免切片问题。 - 应用这些概念能提升程序设计和维护效率。
34 2
|
4月前
|
存储 算法 程序员
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
44 4
|
3月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第6天】C++20引入了Concepts,提升模板编程的精确性和可读性。概念允许设定模板参数的编译时约束。常见问题包括过度约束、不完整约束及重载决议复杂性。要避免这些问题,需适度约束、全面覆盖约束条件并理解重载决议。示例展示了如何定义和使用`Incrementable`概念约束函数模板。概念是C++模板编程的强大力量,但也需谨慎使用以优化效率和代码质量。
72 0
|
3月前
|
存储 算法 C语言
【C++】详解STL的适配器容器之一:优先级队列 priority_queue
【C++】详解STL的适配器容器之一:优先级队列 priority_queue
|
4月前
|
算法 程序员 编译器
C++一分钟之概念(concepts):C++20的类型约束
【6月更文挑战第30天】C++20的Concepts革新了模板编程,允许更清晰地表达类型要求,提升代码可读性和编译错误反馈。本文探讨Concepts基础、应用场景、易错点及避免策略,展示如何通过概念定义如Iterable、Addable,创建更健壮的泛型代码,强调了理解和利用编译器错误信息的重要性,以及概念与类型别名的区别。Concepts现已成为现代C++程序员的关键技能。
55 0
下一篇
无影云桌面