Linux C 数据结构——队列

  还是先放这张图,以便对比和理解:

 

   队列是限制在两端进行插入操作和删除操作的线性表,允许进行存入操作的一端称为“队尾”,允许进行删除操作的一端称为“队头”。当线性表中没有元素时,称为“空队”。特点:先进先出(FIFO)。

一、顺序队列
       建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置,如图所示

     每次在队尾插入一个元素是,rear增1;每次哎队头删除一个元素时,front增1。随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。当front=rear时,队列中没有任何元素,称为空队列。当rear增加到指向分配的连续空间之外时,队列无法再插入新元素,但这时往往还有大量可用空间未被占用,这些空间是已经出队的队列元素曾经占用过得存储单元。

    在实际使用队列时,为了使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。自己真从N(MaxSize)增1变到0,可用取余运算rear%N和front%N来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列

    在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件时front=rear,而队列判满的条件时front=(rear+1)%MaxSize。

总结:

1、队头指针front,指向队头元素的位置的前一个位置。即指向预留的位置;

2、队尾指针rear,指向队尾元素的位置;

3、入队: rear = (rear + 1) % N (maxsize),然后元素放入队尾rear所指向的位置;

4、出队: front = (front + 1) % N,然后取出队头指针front所指向的元素;

5、队空: front == rear;

6、队满: (rear + 1) % N == front, N为数组的元素个数;

7、为了区别空队和满队,满队元素个数比数组元素个数少一个。

下面是顺序队列的运算:

   顺序队列也是顺序表的一种,具有顺序表同样的存储结构,由数组定义,配合使用数组下表表示的队头指针和队尾完成各种操作:

[cpp] view plaincopy
  1. #define N 64  //队列中数据元素的数据类型  
  2. typedef int data_t;  
  3. typedef struct  
  4. {  
  5.     data_t data[N]; //用数组作为队列的储存空间  
  6.     int front,rear; //指示队头位置和队尾位置的指针  
  7. }sequeue_t;  

1、创建空队列

[cpp] view plaincopy
  1. sequeue_t *CreateEmptySequeue()  
  2. {  
  3.     sequeue_t *queue;  
  4.     queue = (sequeue_t *)malloc(sizeof(sequeue_t));  
  5.     if (NULL == queue) return NULL;  
  6.       
  7.     queue->front = queue->rear = 0;  
  8.   
  9.     return queue;  
  10. }  

2、摧毁一个队列

[cpp] view plaincopy
  1. void DestroySequeue(sequeue_t *queue)  
  2. {  
  3.     if (NULL != queue)   
  4.     {  
  5.         free(queue);  
  6.     }  
  7. }  

3、判断一个队列是否为空

[cpp] view plaincopy
  1. int EmptySequeue(sequeue_t *queue)  
  2. {  
  3.     if (NULL == queue)   
  4.         return -1;  
  5.   
  6.     return (queue->front == queue->rear ? 1 : 0);  
  7. }  

4、判断一个队列是否为满

[cpp] view plaincopy
  1. int FullSequeue(sequeue_t *queue)  
  2. {  
  3.     if (NULL == queue) return -1;  
  4.   
  5.     return ((queue->rear + 1) % N == queue->front ? 1 : 0);  
  6. }  

5、清空一个队列

[cpp] view plaincopy
  1. void ClearSequeue(sequeue_t *queue)  
  2. {  
  3.     if (NULL == queue) return;  
  4.       
  5.     queue->front = queue->rear = 0;  
  6.   
  7.     return;  
  8. }  

6、入队

[cpp] view plaincopy
  1. int EnQueue(sequeue_t *queue, data_t x)  
  2. {  
  3.     if (NULL == queue) return - 1;  
  4.   
  5.     if (1 == FullSequeue(queue)) return -1; /* full */  
  6.   
  7.     queue->rear = (queue->rear + 1) % N;  
  8.     queue->data[queue->rear] = x;  
  9.   
  10.     return 0;  
  11. }  

7、出队

[cpp] view plaincopy
  1. int DeQueue(sequeue_t *queue, data_t *x)  
  2. {  
  3.     if (NULL == queue) return -1;  
  4.   
  5.     if (1 == EmptySequeue(queue)) return -1; /* empty */  
  6.   
  7.     queue->front = (queue->front + 1) % N;  
  8.   
  9.     if (NULL != x) {  
  10.         *x = queue->data[queue->front];  
  11.     }  
  12.   
  13.     return 0;  
  14. }  


二、链式队列

      用链表表示的队列简称为链队列,如下图所示


一个链队列显然需要两个分别指示队头和队尾的指针(分别成为头指针和尾指针)才能唯一确定。这里,和线性表的单链表一样,为了操作方便起见,我们也给队列添加一个头结点,并令头指针指向头节点。由此,空的链队列的判决条件为头指针和尾指针均指向头结点,如下图所示:

 

链队列的操作记为单链表的插入和删除操作的特殊情况,插入操作在队尾进行,删除操作在队头进行,由队头指针和队尾指针控制队列的操作:

[cpp] view plaincopy
  1. typedef int data_t;  
  2. typedef struct node_t  
  3. {  
  4.     data_t data;  
  5.     struct node_t *next;  
  6. }linknode_t,*linklist_t;  
  7. typedef struct  
  8. {  
  9.     linklist_t front,rear;  
  10. }linkqueue_t;  

1、创建空队列

[cpp] view plaincopy
  1. linkqueue_t *CreateEmptyLinkqueue()  
  2. {  
  3.     linkqueue_t *lp = (linkqueue_t *)malloc(sizeof(linkqueue_t));  
  4.     if(lp == NULL)  
  5.         return;  
  6.   
  7.     lp->front = lp->rear = (linknode_t *)malloc(sizeof(linknode_t));  
  8.     if(lp->front == NULL)  
  9.         return;   
  10.   
  11.     lp->front->next = NULL;  
  12.   
  13.     return lp;  
  14. }  

2、摧毁一个链队列

[cpp] view plaincopy
  1. void DestroyLinkqueue(linkqueue_t *queue)  
  2. {  
  3.     if(queue != NULL)  
  4.     {  
  5.         ClearLinkqueue(queue);  
  6.         free(queue);  
  7.     }  
  8. }  

3、清空一个链队列

[cpp] view plaincopy
  1. void ClearLinkqueue(linkqueue_t *queue)  
  2. {  
  3.     linknode_t *qnode;  
  4.   
  5.     while(q->front)  
  6.     {  
  7.         qnode = queue->front;  
  8.         queue->front= qnode->next;  
  9.         free(qnode);  
  10.     }  
  11.     queue->rear = NULL;}  

4、判断链队列为空

[cpp] view plaincopy
  1. int EmptyLinkqueue(linkqueue_t *queue)  
  2. {  
  3.     if(queue == NULL)  
  4.     return -1;  
  5.       
  6.     return(queue->front == queue->rear ? 1 : 0);  
  7. }  

5、入队

[cpp] view plaincopy
  1. int EnQueue(linkqueue_t *queue,data_t x)  
  2. {  
  3.     linknode_t *node_new;  
  4.     if(queue == NULL)  
  5.         return -1;  
  6.   
  7.     node_new = (linknode_t *)malloc(sizeof(linknode_t));  
  8.     if(node_new == NULL)  
  9.         return -1;  
  10.   
  11.     node_new->data = x;  
  12.     node_new->next = NULL;  
  13.   
  14.     if(queue->front->next == NULL)  
  15.     {  
  16.         queue->front->next = queue->rear = node_new;  
  17.     }  
  18.     else  
  19.     {  
  20.         queue->rear->next = node_new;  
  21.         queue->rear = node_new;  
  22.     }  
  23.     return 0;     
  24. }  

6、出队

[cpp] view plaincopy
  1. int DeQueue(linkqueue_t *queue,data_t *x)  
  2. {  
  3.     linknode_t *node_remove;  
  4.   
  5.     if(queue == NULL || queue->front->next == NULL)  
  6.         return -1;  
  7.   
  8.     node_remove = queue->front->next;  
  9.     queue->front->next = node_remove->next;  
  10.   
  11.     if(x != NULL)  
  12.         *x = node_remove->data;  
  13.   
  14.     free(node_remove);  
  15.   
  16.     return 0;  
  17. }  

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

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

相关文章

MySQL视图查询报错:Prepared statement needs to be re-prepared

From: https://www.ywnds.com/?p12609 今天公司的项目视图查询报错,报错如:ERROR 1615 (HY000): Prepared statement needs to be re-prepared 网上找了一圈,都说调整以下值就好了: mysql> set global table_open_cache163…

如何使用FF的Firebug组件中的net工具查看页面元素加载消耗时间

1.安装FF的Firebug组件:点击FF的Tools的Add-ons菜单,输入Firebug关键字,并选择合适的版本Install。 2.安装完毕后地址栏右边会出现一个小虫图标,右边还有一个下拉箭头。如下图: 3.点击下拉箭头,选择“on fo…

Linux C 数据结构——二叉树

先放这张图: 可以看出,树是非线性结构; 一、树的概念 树(tree)是n(n>0)个节点的有限集合T,它满足两个条件: 1)有且仅有一个特定的称为根(root)的节点&…

antd 表单域验证规则 - 只能输入数字字符,去除前导0

<Form {...formItemLayout}><Form.Item label用户Id>{getFieldDecorator(uid, {initialValue: undefined,rules: [{ required: true, message: 请输入用户id, pattern: new RegExp(/^[1-9]\d*$/, g) }],getValueFromEvent: e > e.target.value.replace(/\D/g, )…

2013 822 划分子网

子网的划分是为了节省我们的网络的ip地址的分配,如我们有200台电脑需要一个子网段,我在这个192.168.0.1网段我们有254个地址,我们可以将我们的计算机划分成不同的子网,来进行使用,这样的话就是节省了大量的IP地址.补充下上次忘记总结的东西,就是如192.168.10.101/24 24表示我们…

BZOJ 3224: Tyvj 1728 普通平衡树

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9629 Solved: 4091[Submit][Status][Discuss]Description 您需要写一种数据结构&#xff08;可参考题目标题&#xff09;&#xff0c;来维护一些数&#xff0c;其中需要提供以下操作&#xff1a;…

springboot中配置mybatis数据源,使用阿里的 Druid 数据库连接池

参考了很多文章&#xff0c;记录下自己的学习过程&#xff01; 参考&#xff1a;https://blog.csdn.net/weixin_40776321/article/details/99633110 1. 在pom.xml中添加依赖&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>dr…

Linux C 算法——查找

所谓“查找”记为在一个含有众多的数据元素&#xff08;或记录&#xff09;的查找表中找出某个“特定的”数据&#xff0c;即在给定信息集上寻找特定信息元素的过程。 为了便于讨论&#xff0c;必须给出这个“特定的”词的确切含义。首先&#xff0c;引入一个“关键字”的概念&…

SharePoint项目中新建类库的错误处理及项目建设中遇到的问题总结

第一次SP项目总监遇到各种问题&#xff0c;以下是总结&#xff1a;问题1.创建SP项目的时候“场解决方案”跟“沙盒解决方案”是有区别的&#xff0c;具体可以看MSDN官方文档&#xff0c;这里简单摘抄如下&#xff1a;1&#xff09;场解决方案&#xff1a;承载与W3WP.exe中&…

ECharts学习(1)--简单图表的绘制

1.获取ECharts 官网 下载&#xff1a;http://echarts.baidu.com/download.html 2.在html页面中引入ECharts文件 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>ECharts练习</title><script type"text/javas…

php配置xdebug断点调试

环境&#xff1a;mac 10.15.4 zcmzcmdeMacBook-Pro 20190902 % php -v PHP 7.4.9 (cli) (built: Aug 7 2020 19:23:06) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologieswith Xdebug v2.9.6, Copyright (c) 2002-2020, by Derick R…

Linux C 算法——排序

排序(Sort)是将无序的记录序列&#xff08;或称文件&#xff09;调整成有序的序列。 为了方便讨论&#xff0c;在此首先要对排序下一个确切的定义&#xff1a; 假设含有n个记录的序列为 { R1、R2、&#xff0c;。。。Rn } 其相应的关键字序列为 {K1、K2&#xff0c;。。。。Kn}…

HTTP错误代码

服务器错误代码大全 400 - 错误的请求。 401 - 访问被拒绝。IIS 定义了许多不同的 401 错误&#xff0c;它们指明更为具体的错误原因。这些具体的错误代码在浏览器中显示&#xff0c;但不在 IIS 日志中显示&#xff1a; 401.1 - 登录失败。 401.2 - 服务器配置导致登录失败。 4…

UIKit封装的系统动画

简介 在UIKit中&#xff0c;对UIView封装了很多类方法来进行简单的动画实现&#xff0c;在动画过程中&#xff0c;通过对属性值的修改来完成一系列的效果。 在IOS4以前&#xff0c;主要通过 beginAnimation setAnimationDuration:设置动画时长 setAnimationDelay:设置延迟时…

MS SQL Server2008大数、小数转varchar

HTJE在表中的字段类型为float(53) 试了下str, cast和convert&#xff0c;发现对于小数或大数&#xff0c;多少都存在一些问题&#xff0c;最后经过尝试终于找到一种满意的答案&#xff1a; select cast(HTJE as decimal(20,2)) from T_HTGL where ID 1002993 对于金额部分&…

oracle那些基本知识

Oracle创建表空间、创建用户以及授权 、查看权限 rownum 分页查询 它是oracle系统顺序分配为从查询返回的行的编号&#xff0c;返回的第一行分配的是1&#xff0c;第二行是2&#xff0c;依此类推&#xff0c;这个伪字段可以用于限制查询返回的总行数&#xff0c;而且rownum不能…

JSON.parse 解析json字符串时,遇换行符报错

Json字符串转换成Json对象时候&#xff0c;有两种方式&#xff1a; 假设d是json字符串&#xff1a; 1&#xff0c;eval(( d ))。 2&#xff0c;JSON.parse(d)&#xff1b; 但是以上方式有隐患&#xff0c;如果Json字符串有换行的话&#xff0c;这样转换就会报错。 假如有…

jqueryui dialog asp.net服务端控件失效问题解决

最近使用jQuery Dialog做添加功能&#xff0c;发现服务端控件全部失效。 查资料是因为Dialog层被appendto 到了 body里&#xff0c;不在form里。 但网上给的解决方案我都不满意&#xff0c;觉得jQueryUI不会忽略这个问题&#xff0c;就查了API。 发现这个属性appendTo $( "…

用ASP生成RSS

<% Response.Clear Response.CharSet"gb2312" 数据集 Response.ContentType"text/xml" 数据流格式定义 Response.Write "<?xml version""1.0"" encoding""gb2312""?>"&vbNewLinesRssHea…