基于Codesys用ST语言实现循环队列FIFO数据结构详细说明+代码实例

请添加图片描述

一、 队列定义

队列是一种先入先出(FIFO——first in first out)线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。

二、队列实现

实现队列,我们可以使用动态数组以及指向队列头部的索引和指向队列尾部的索引
在这里插入图片描述
例如我们分配一个最长长度为6的数组,我们最多只能添加6个元素,在第6次元素22入队后,因为队列已满,队列不能接受更多的入队请求。
在这里插入图片描述
但是如果我们将一个元素出队后,应该可以再接受一个元素,这就要考虑循环队列,可以重用被浪费的空间。

三、 循环队列设计

循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

C 语言实现

功能如下

  • Create(k):构造器,动态创建K大小的数组
  • Push(value) : 向循环队列中插入一个元素,成功返回true
  • pop():从循环队列中删除一个元素,成功返回true
  • Front():从队列头部获取元素,如果队列是空,返回-1
  • Rear():从队列尾部获取元素,如果队列为空,返回-1
  • Empty(): 检测队列是否为空
  • Full() : 检测队列是否已满
  • Destroy:销毁队列
typedef struct {
    int *data;//数组指针
    int mTail;//尾部索引
    int mHead;//头部索引
    int mSize;//数组大小

} MyQueue;

bool Empty(MyQueue* obj);
bool Full(MyQueue* obj);

//构造器,动态创建K大小的数组
MyQueue* Create(int k)
{
 MyQueue *mMyQueue = ( MyQueue *)malloc(sizeof(MyQueue));
 mMyQueue->data    = (int*)malloc( sizeof(int)*(k));
 mMyQueue->mTail   = -1;
 mMyQueue->mHead   = -1;
 mMyQueue->mSize   =  k;
 return mMyQueue;
}
//向循环队列中插入一个元素,成功返回true
bool Push(MyQueue* obj, int value) {
    if(obj == 0 )
       return false;
    if(Full(obj))
       return false;
     if (Empty(obj))
        obj->mHead  = 0;
      
     obj->mTail = (obj->mTail + 1) % obj->mSize;
     obj->data[obj->mTail] = value;
     return true;
}
//从循环队列中删除一个元素,成功返回true
bool pop(MyQueue* obj) {
      if(obj == 0 )
        return false;
      if (Empty(obj))
         return false;
      if(obj->mHead == obj->mTail)
      {
          obj->mTail  = -1;
          obj->mHead  = -1;
           return true;
      }
      obj->mHead = (obj->mHead +1) % obj->mSize;
      return true;
}
//从队列头部获取元素,如果队列是空,返回-1
int Front(MyQueue* obj)
 {
    if(obj == 0 )
       return -1;
    if (Empty(obj))
       return -1;
    return obj->data[obj->mHead];
}
//从队列尾部获取元素,如果队列为空,返回-1
int Rear(MyQueue* obj)
 {
   if(obj == 0 )
       return -1;
   if (Empty(obj))
        return -1;
    return obj->data[obj->mTail];
}
//检测队列是否已空
bool Empty(MyQueue* obj)
 {
    if (obj==0) 
      return false;
    if ((obj->mHead == -1) &&(obj->mTail == -1)) 
      return true;
      
    return false;
}
//检测队列是否已满
bool Full(MyQueue* obj) {
   if (obj==0) 
      return false;

 
   if ((obj->mHead == ((obj->mTail +1)%obj->mSize)) && (obj->mHead != -1))
      return true;

    return false; 
}
//:销毁队列
void Destroy(MyQueue* obj) {
     if(obj==0) 
        return ;
    if (obj->data != 0) 
       free(obj->data);
    if (obj != 0) 
       free(obj);
}


Codesys 实现
  • 编程软件: Codesys V3.5 SP17
  • 运行设备:PC电脑
  • 编程语言: ST 掌握如何创建动态数组New的使用;以及指针的灵活使用

定义结构体

//队列操作的数据
TYPE QueueElement :
STRUCT
	pData : POINTER TO BaseElement;//数组指针
	mHead : INT;//头部索引
	mTail : INT;//尾部索引
	mSize : INT;//数组大小
END_STRUCT
END_TYPE

其中 BaseElement 是一个别名,其定义如下,这里BaseElement 是用户自定义数据(比如结构体),采用别名是方便替换。

TYPE BaseElement : INT; END_TYPE

定义功能块 CircularQueue,实现如下函数

  • Create(k):构造器,动态创建K大小的数组
  • Push(value) : 向循环队列中插入一个元素,成功返回true
  • Pop():从循环队列中删除一个元素,成功返回true
  • Front():从队列头部获取元素,如果队列是空,返回-1
  • Rear():从队列尾部获取元素,如果队列为空,返回-1
  • Empty(): 检测队列是否为空
  • Full() : 检测队列是否已满
  • Destroy:销毁队列
  • Size:获取队列数组大小

示例如下

PROGRAM PLC_PRG
VAR
	myCircularQueue : CircularQueue;
END_VAR

VAR
	bInit :BOOL:= FALSE;
	isize : INT;
	ivar1: ARRAY[0..10] OF BaseElement;
END_VAR
IF bInit = FALSE THEN 
bInit := TRUE;

myCircularQueue.Create(10);//动态创建数组 大小位10
isize := myCircularQueue.Size();//获得队列数组大小 为10

myCircularQueue.Push(11);//入队 ,返回TRUE
myCircularQueue.Push(22);//入队 ,返回TRUE
myCircularQueue.Push(33);//入队 ,返回TRUE
myCircularQueue.Push(44);//入队 ,返回TRUE

ivar1[0] := myCircularQueue.Front();//返回11

myCircularQueue.Pop();  //从循环队列中删除一个元素,成功返回true
ivar1[1] := myCircularQueue.Front();//返回22

END_IF

在这里插入图片描述

四、 Codesys代码下载

请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值