tt99166 发表于 2023-4-12 22:14:17

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



一、 队列定义

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

实现队列,我们可以使用动态数组以及指向队列头部的索引和指向队列尾部的索引


例如我们分配一个最长长度为6的数组,我们最多只能添加6个元素,在第6次元素22入队后,因为队列已满,队列不能接受更多的入队请求。


但是如果我们将一个元素出队后,应该可以再接受一个元素,这就要考虑循环队列,可以重用被浪费的空间。
三、 循环队列设计

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

功能如下
Create(k):构造器,动态创建K大小的数组Push(value) : 向循环队列中插入一个元素,成功返回truepop():从循环队列中删除一个元素,成功返回trueFront():从队列头部获取元素,如果队列是空,返回-1Rear():从队列尾部获取元素,如果队列为空,返回-1Empty(): 检测队列是否为空Full() : 检测队列是否已满Destroy:销毁队列
typedefstruct{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= 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;}//从队列头部获取元素,如果队列是空,返回-1intFront(MyQueue* obj){if(obj ==0)return-1;if(Empty(obj))return-1;return obj->data;}//从队列尾部获取元素,如果队列为空,返回-1intRear(MyQueue* obj){if(obj ==0)return-1;if(Empty(obj))return-1;return obj->data;}//检测队列是否已空
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;}//:销毁队列voidDestroy(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) : 向循环队列中插入一个元素,成功返回truePop():从循环队列中删除一个元素,成功返回trueFront():从队列头部获取元素,如果队列是空,返回-1Rear():从队列尾部获取元素,如果队列为空,返回-1Empty(): 检测队列是否为空Full() : 检测队列是否已满Destroy:销毁队列Size:获取队列数组大小
示例如下
PROGRAM PLC_PRG
VAR
        myCircularQueue : CircularQueue;
END_VAR

VAR
        bInit :BOOL:= FALSE;
        isize : INT;
        ivar1: ARRAY OF BaseElement;
END_VARIF 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:= myCircularQueue.Front();//返回11

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

END_IF

四、 Codesys代码下载
页: [1]
查看完整版本: 基于Codesys用ST语言实现循环队列FIFO数据结构详细说明+代码实例