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

请添加图片描述

一、 队列定义

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

二、队列实现

实现队列,我们可以使用链表,链表中的每个结点不仅包含值,还包含链接到下一个结点的引用字段。通过这种方式,单链表将所有结点按顺序组织起来。蓝色箭头显示单个链接列表中的结点是如何组合在一起的
在这里插入图片描述
用链表实现队列相对数组实现队列的优点是能节约空间,没有浪费的空间节点。

三、 队列设计

我们分别采用c++和codesys中st语言进行实现链表队列

(1) C++ 语言实现

功能如下

  • Push(value) : 向队列中插入一个元素,成功返回true
  • pop():从队列中删除一个元素,成功返回true
  • Front():从队列头部获取元素,如果队列是空,返回false
  • Rear():从队列尾部获取元素,如果队列为空,返回false
  • Empty(): 检测队列是否为空,为空返回true
  • Size():获得队列节点个数,返回个数


typedef int DataElement;//用户自定义的数据

typedef struct QueueElement//队列元素
{
    DataElement  mdata;//用户自定义的数据
    QueueElement* next;//指向下一个节点
 }QueueElement;
 
//通过链表实现队列
class ListCircleQueue
{
public:
    ListCircleQueue() {};
    ~ListCircleQueue() {};
private:
    QueueElement* pHead = 0;//
    QueueElement* pTail = 0;//队尾指针
public:
bool push(DataElement _data) 
    {
     // 申请一个结点空间
        QueueElement* pTemp = (QueueElement*)malloc(sizeof(QueueElement));
         pTemp->mdata = _data;// 申请一个结点空间
         pTemp->next = 0;// 结点的next设为NULL
          if (Empty()) // 判断队头和队尾是否为空,用于第一次入队
          {
             pHead = pTemp; // 判断队头和队尾是否为空,用于第一次入队
             pTail = pTemp;
          }
          else
         {
          pTail->next = pTemp;// 让pTemp成为当前尾部的下一结
           pTail = pTemp;// 尾部指针指向pTemp
         }
         return true;
     }
     bool pop() 
    {
        if (Empty())
            return false;
        if (pHead->next == 0)// 判断队列是否就1个,如果只有一个 ,移除后队列为空 
        {
            pHead = 0;
            pTail = 0;  
        }
        else
        {
          QueueElement* pTemp = pHead;
          pHead = pHead->next;//移动头部指针
          delete(pTemp);//清除移除的内存空前
        }
        return true;
    };
     bool Front(DataElement &_data)
     {
       if (pHead != 0)
       {
          _data = pHead->mdata;//返回头部数据
          return true;
       }
       else
         return false;
     }
      bool Rear(DataElement& _data)
      {
        if (pTail != 0)
        {
           _data = pTail->mdata;//返回尾部数据
            return true;
        }
         else
            return false;
      }
     //返回节点个数
     int Size()
     {
         int iSize  = 0;
         QueueElement* pTemp = pHead;
         while (pTemp != 0)
          {
             iSize = iSize + 1;
             pTemp = pTemp->next;
          }
        return iSize;
     }
     //判断队列是否为空
     bool Empty()
     {
       if ((pHead == 0) && (pTail == 0))
          return true;
       else
         return false;
     }
}

示例如下
在这里插入图片描述

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

定义结构体

//队列操作的数据
TYPE ListQueueElement :
STRUCT
	mData : BaseElement;
	pNext : POINTER TO ListQueueElement;
END_STRUCT
END_TYPE

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

TYPE BaseElement : INT; END_TYPE

定义功能块(FUNCTION_BLOCK): ListQueue,实现如下函数

  • Push(value) : 向队列中插入一个元素,成功返回true
  • pop():从队列中删除一个元素,成功返回true
  • Front():从队列头部获取元素,如果队列是空,返回false
  • Rear():从队列尾部获取元素,如果队列为空,返回false
  • Empty(): 检测队列是否为空,为空返回true
  • Size():获得队列节点个数,返回个数

示例如下

PROGRAM PLC_PRG
VAR	
	t : ListQueue;
END_VAR

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

t.Push(11);//入队 ,返回TRUE
t.Push(22);//入队 ,返回TRUE
t.Push(33);//入队 ,返回TRUE
isize := t.Size();//返回3
t.Front(_data =>ivar1[0]);//返回11
t.Pop(); //从循环队列中删除一个元素,成功返回true
t.Front(_data =>ivar1[1]);//返回22

END_IF

在这里插入图片描述

四、 Codesys代码下载

请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值