队列的基本概念详解,循环队列、链式队列的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
}


相关文章
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
574 77
|
10月前
|
存储 编译器 C++
【c++】多态(多态的概念及实现、虚函数重写、纯虚函数和抽象类、虚函数表、多态的实现过程)
本文介绍了面向对象编程中的多态特性,涵盖其概念、实现条件及原理。多态指“一个接口,多种实现”,通过基类指针或引用来调用不同派生类的重写虚函数,实现运行时多态。文中详细解释了虚函数、虚函数表(vtable)、纯虚函数与抽象类的概念,并通过代码示例展示了多态的具体应用。此外,还讨论了动态绑定和静态绑定的区别,帮助读者深入理解多态机制。最后总结了多态在编程中的重要性和应用场景。 文章结构清晰,从基础到深入,适合初学者和有一定基础的开发者学习。如果你觉得内容有帮助,请点赞支持。 ❤❤❤
1263 0
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
473 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
11月前
|
存储 算法 C++
【c++丨STL】priority_queue(优先级队列)的使用与模拟实现
本文介绍了STL中的容器适配器`priority_queue`(优先级队列)。`priority_queue`根据严格的弱排序标准设计,确保其第一个元素始终是最大元素。它底层使用堆结构实现,支持大堆和小堆,默认为大堆。常用操作包括构造函数、`empty`、`size`、`top`、`push`、`pop`和`swap`等。我们还模拟实现了`priority_queue`,通过仿函数控制堆的类型,并调用封装容器的接口实现功能。最后,感谢大家的支持与关注。
700 1
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
264 9
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
284 7
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
967 7
|
消息中间件 存储 安全
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
204 0
|
程序员 C++ 开发者
C++入门教程:掌握函数重载、引用与内联函数的概念
通过上述介绍和实例,我们可以看到,函数重载提供了多态性;引用提高了函数调用的效率和便捷性;内联函数则在保证代码清晰的同时,提高了程序的运行效率。掌握这些概念,对于初学者来说是非常重要的,它们是提升C++编程技能的基石。
146 0