队列的基本操作

链式存储
typedef int QElemType;
typedef int Status;//具体数据类型具体定义
typedef struct QNode//队列结点结构体
{
    QElemType data;
    QNode *next;
} QNode, *Queueptr;

typedef struct   // 链队列类型
{
    Queueptr  front;  // 队头指针(结构体类型的指针)等价于 QNode *front;
    Queueptr  rear;   // 队尾指针
} LinkQueue;

Status InitQueue (LinkQueue &Q) // 构造一个空队列Q
{
    Q.front = Q.rear = (Queueptr)malloc(sizeof(QNode));
    if (!Q.front) exit (0); //存储分配失败
    Q.front->next = NULL;
    return 1;
}

Status EnQueue (LinkQueue &Q, QElemType e)// 插入元素e为Q的新的队尾元素
{
    p = (Queueptr) malloc (sizeof (QNode));
    if (!p)  exit (0);   //存储分配失败
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;//类似于顺序建立链表的过程
    return 1;
}

Status DeQueue (LinkQueue &Q,   QElemType &e)//若队列不空,则删除Q的队头元素,用 e 返回其值
{
    if (Q.front == Q.rear)  //若队空
        return 0;
    p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;//删除操作
    if (Q.rear == p)//如果是最后一个元素
        Q.rear = Q.front;//删除即队空
    free (p);
    return 1;
}

Status GetHead(LinkQueue Q,QElemType &e)// 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
{
    Queueptr p;
    if(Q.front==Q.rear)//队空
        return 0;
    p=Q.front->next;//取队首元素
    e=p->data;
    return 1;
}


Status QueueEmpty(LinkQueue Q)  // 若Q为空队列,则返回1,否则返回0
{
    if(Q.front==Q.rear)
        return 1;
    else
        return 0;
}


void ClearQueue(LinkQueue &Q) // 将Q清为空队列
{
    Queueptr p, q;
    Q.rear=Q.front;
    p=Q.front->next;
    Q.front->next=NULL;//只留下头结点
    while(p)//依次清空所有元素
    {
        q=p;
        p=p->next;
        free(q);
    }
}

Status DestroyQueue(LinkQueue  &Q)//销毁队列
{
    while(Q.front)
    {
        Q.rear=Q.front->next;//Q.rear指向当前删除结点下一结点
        free(Q.front);
        Q.front=Q.rear; //Q.front指向当前删除结点(队头元素)
        //释放一块内存要做两点:1.释放指向它的指针。2.将该指针指向空
    }
    return 1;
}

int QueueLength(LinkQueue Q)  // 求队列的长度
{
    int i=0;
    Queueptr p;
    p=Q.front;
    while(p!=Q.rear)
    {
        i++;
        p=p->next;
    }
    return i;
}

 

顺序存储(循环队列--解决假溢出问题)

1. 头指针指向队首元素,尾指针指向队尾的下一个位置。(这里的指针可认为是数组下标)
 
2. 为了区分队满与队空,则定义一个存储空间为MAXQSIZE大小的队列只允许存放(MAXQSIZE-1)个数据。
 
3. 判空条件为:if(Q.front == Q.rear) return true;
 
   判满条件为:if((Q.rear+1) % MAXQSIZE==Q.front) return true;
 
4. 循环队列的长度为:(Q.read-Q.front + MAXQSIZE) % MAXQSIZE
 
5. 当删除对头元素或者在对尾插入元素时指针均需向后移动:
   
    (1). Q.rear=(Q.rear+1) % MAXQSIZE;
    (2). Q.front=(Q.front+1) % MAXQSIZE;
   

InitQueue(&Q)//构造一个空队列Q
GetHead(Q, &e)//获取队头元素
EnQueue(&Q, e)//插入队尾元素
DeQueue(&Q, &e)//删除队头元素
DestroyQueue(&Q)//销毁队列
ClearQueue(&Q)//清空队列
QueueEmpty(Q)//判断队列是否为空
QueueLength(Q)//求当前队列长度

 

#define MAXQSIZE  100  //最大队列长度
typedef int QElemType;
typedef int Status;//具体数据类型具体定义
typedef struct
{
    QElemType  *base;  // 初始化的动态分配存储空间
    int  front;  // 头指针,若队列不空,指向队列头元素
    int  rear;  // 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;

Status InitQueue (SqQueue &Q) // 构造一个空队列Q
{
    Q.base = (ElemType *) malloc (MAXQSIZE *sizeof (ElemType));
    if (!Q.base) exit (0);// 存储分配失败
    Q.front = Q.rear = 0;
    return 1;
}


Status EnQueue(SqQueue &Q, ElemType e)// 插入元素e为Q的新的队尾元素
{
    if ((Q.rear+1) % MAXQSIZE == Q.front)//队列满
        return 0;
    Q.base[Q.rear] = e;//插入队尾元素
    Q.rear = (Q.rear+1) % MAXQSIZE;//尾指针向后移动
    return 1;
}

Status DeQueue (SqQueue &Q, ElemType &e)  // 若队列不空,则删除Q的队头元素,用e返回其值
{
    if (Q.front == Q.rear)  return 0;
    e = Q.base[Q.front];//队首元素
    Q.front = (Q.front+1) % MAXQSIZE;//头指针向后移动
    return 1;
}

Status GetHead (SqQueue &Q, ElemType &e)//取队首元素
{
    if (Q.front == Q.rear)  return 0;
    e = Q.base[Q.front];//队首元素
    return 1;
}
Status QueueEmpty (SqQueue &Q)//判断队是否为空
{
    if (Q.front == Q.rear)
        return 1;
    else
        return 0;
}

void ClearQueue(SqQueue &Q)// 将Q清为空队列
{
    Q.front=Q.rear=0;
}

void DestroyQueue(SqQueue &Q)// 销毁队列Q,Q不再存在
{
    if(Q.base)
        free(Q.base);
    Q.base=NULL;
    Q.front=Q.rear=0;
}

int QueueLength(SqQueue Q)  // 返回Q的元素个数,即队列的长度
{
    return(Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++阻塞队列

基于C11的阻塞队列简单实现 转载请说明出处:http://blog.csdn.net/cywosp/article/details/9157379 在多线程编程中阻塞队列(Blocking Queue)是一种常用于实现生产者和消费者模型的数据结构。其与普通的队列区别在于,当队列为空时,从队列获取…

java中ArrayList类的操作

ArrayList类是Java集合框架出现之后用来取代Vector类的: 二者底层原理都是基于数组的算法,一模一样. 区别: Vector: 所有的方法都使用了synchronized修饰符. 线程安全但是性能较低. 适用于多线程环境. ArrayList:所有的方法都没有使用synchronized修饰符. 线程不安全但是性…

Elasticsearch Painless Script详解

文章目录1. Painless 简介Painless 的用途2. 参数3. 首选参数4. 简短脚本形式5. 通过 Painless 脚本访问字段6. 示例6.1 案例 1:Script Processsor6.2 案例 2:文档更新计数6.3 案例 3:搜索时的 Script 字段6.4 Script :Inline v.s Stored6.5 …

算术表达式的转换

题目描述 小明在学习了数据结构之后,突然想起了以前没有解决的算术表达式转化成后缀式的问题,今天他想解决一下。因为有了数据结构的基础小明很快就解出了这个问题,但是他突然想到怎么求出算术表达式的前缀式和中缀式呢?小明很困惑…

Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程

内容目录: Reactor实现架构对比面向对象的Reactor方案设计函数式编程的Reactor设计示例对比两者的时序图对比结论 Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明; Reactor实现架构对…

ElasticSearch 快照 备份、恢复数据

文章目录ElasticSearch 设置备份文件地址注册快照存储库查看快照存储库保存结果创建快照异步创建指定索引进行快照查看全部快照在服务器查看备份的数据恢复数据本机恢复其他服务器恢复常见问题报错 doesnt match any of the locations specified by path.repo because this set…

java中LinkedList类的操作

LinkedList类是双向链表,单向队列,双向队列,栈的实现类: LinkedList类实现单向队列和双向队列的接口,自身提高了栈操作的方法,链表操作的方法. 在LinkedList类中存在很多方法,但是功能都是相同的.LinkedList表示了多种数据结构的实现,每一种数据结构的操作名字不同. 面试题:编…

数据结构实验之栈七:出栈序列判定

题目描述 给一个初始的入栈序列,其次序即为元素的入栈次序,栈顶元素可以随时出栈,每个元素只能入栈依次。输入一个入栈序列,后面依次输入多个序列,请判断这些序列是否为所给入栈序列合法的出栈序列。 例如序列1&#x…

FileBeat + Pipeline 解析日志 保存至ElasticSearch(实战)

文章目录FileBeat Pipeline 解析日志 保存至ElasticSearch(实战)下载地址目的日志数据模拟Pipeline创建pipeline查看Pipeline是否创建成功创建FileBeat配置文件 filebeat.yml创建自定义字段 FileBeat fields.yml执行 FileBeatfilebeat 启动命令说明测试…

网络编程中的关键问题总结

内容目录: 连接建立连接断开消息到达发送消息消息发送完毕其它问题参考 网络编程中的关键问题总结 总结下网络编程中关键的细节问题,包含连接建立、连接断开、消息到达、发送消息等等; 连接建立 包括服务端接受 (accept) 新连接和客户端成功发…

List实现类性能和特点分析

面向接口编程: 接口类型 变量 new 实现类(); List list new ArrayList(); List实现类特点和性能分析: 三者共同的特点(共同遵循的规范): 1):允许元素重复. 2):记录元素的先后添加顺序. Vector类: 底层才有数组结构算法,方法都使用了synchronized修饰,线程安全,但是性能…

数据结构实验之栈八:栈的基本操作

题目描述 堆栈是一种基本的数据结构。堆栈具有两种基本操作方式&#xff0c;push 和 pop。push一个值会将其压入栈顶&#xff0c;而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。 输入 首先输入整数t&#xff08;1 < t < 10&#xff09;&#xff0c;代表测…

F5 BIGip 负载均衡 IP算法解密工具

BIGip是对负载均衡的实现&#xff0c;主要通过Virtual Server、iRules、Pool、Node、Monitor和Persistent&#xff08;会话保持&#xff09;实现。BIGip在实现会话保持机制时会在用户首次发起请求时&#xff0c;会为用户设置一个cookie&#xff0c;即服务端会添加set-cookie响应…

Java集合框架-重构设计

根据Vector类,ArrayList类,LinkedList类所有具有的存储特点以及拥有的方法入手,发现共性就往上抽取. 共同的特点: 1):允许元素重复的. 2):会记录先后添加的顺序. 共同的方法: 如下图. 根据他们的特点,我就可以指定规范: 遵循该规范的实现类,无论底层算法如何,都必须保证允…

回文串判定

题目描述 输入一串字符&#xff08;长度小于100&#xff09;&#xff0c;判断该串字符是否是回文串&#xff08;正序读与逆序读内容相同&#xff09;。 输入 输入一串字符&#xff08;长度小于100&#xff09;。 输出 若该串字符是回文串输出“yes"&#xff0c;否则输出”…

Canal Mysql binlog 同步至 Hbase ES

文章目录一、Canal介绍工作原理canal 工作原理二、下载三、安装使用Mysql准备canal 安装解压缩 canal-deployer配置修改启动查看server日志查看instance日志服务停止canal-client使用Canal Adapter数据同步Hbase数据同步ElasticSearch一、Canal介绍 早期阿里巴巴因为杭州和美国…

java中集合的迭代操作

集合的迭代操作: 把集合做的元素一个一个的遍历取出来. 迭代器对象: Iterator: 迭代器对象,只能从上往下迭代. boolean hasNext(); 判断当前指针后是否有下一个元素 Object next():获取指针的下一个元素,并且移动指针. ListIterator: 是Iterator接口的子接口,支持双向迭代…

Canal同步ES报错,java.lang.ClassCastException: com.alibaba.druid.pool.DruidDataSource cannot be cast to c

Canal同步ES报错 提示类型转换失败 2021-09-20 13:10:54.094 [main] ERROR c.a.o.canal.adapter.launcher.loader.CanalAdapterLoader - Load canal adapter: es7 failed java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: com.alibab…

C语言实验——数组逆序

题目描述 有n个整数&#xff0c;使其最后m个数变成最前面的m个数&#xff0c;其他各数顺序向后移m&#xff08;m < n < 100)个位置。输入 输入数据有2行&#xff0c;第一行的第一个数为n&#xff0c;后面是n个整数&#xff0c;第二行整数m。输出 按先后顺序输出n个整数。…

用C++11的std::async代替线程的创建

转自&#xff1a;http://www.cnblogs.com/qicosmos/p/3534211.html c11中增加了线程&#xff0c;使得我们可以非常方便的创建线程&#xff0c;它的基本用法是这样的&#xff1a; void f(int n); std::thread t(f, n 1); t.join(); 但是线程毕竟是属于比较低层次的东西&#xf…