首页 > 其他分享 >几种常用数据结构的C语言实现

几种常用数据结构的C语言实现

时间:2024-04-12 15:57:10浏览次数:22  
标签:handle C语言 rIndex 几种 item pHandle return 数据结构 size

队列

/**
  ******************************************************************************
  * @file           : myfifo.c
  * @brief          : 先入先出队列实现
  * @author         : huanglidi
  ******************************************************************************
  */
#include "myfifo.h"
#include "rtthread.h"

typedef struct
{
    void * queue;
    uint8_t fifo_size;
    uint8_t item_size;

    int16_t wIndex;
    int16_t rIndex;
}myfifo_t;

void InitFifo(myfifo_t* handle, uint8_t size, uint8_t item_size)
{
    if (!handle) return;

    handle->fifo_size = size;
    handle->item_size = item_size;
    handle->wIndex = 0;
    handle->rIndex = 0;
    handle->isFull = 0;
    handle->isEmpty = 1;
    handle->queue = rt_malloc(size * item_size);
}

void ReleaseFifo(myfifo_t* handle)
{
    if (!handle) return;
    rt_free(handle->queue);
    handle->queue = NULL;
    handle->wIndex = 0;
    handle->rIndex = -1;
    handle->fifo_size = 0;
    handle->item_size = 0;
}

bool FifoPush(myfifo_t* handle, void* data)
{
    uint8_t size        = handle->fifo_size;
    uint8_t item_size   = handle->item_size;

    if (!handle) return false;
    if (handle->wIndex == handle->rIndex){  //队列满
        retrun false;
    }

    int offset = item_size*handle->wIndex;
    memcpy(handle->queue+offset, data, item_size);
    handle->wIndex = (handle->wIndex+1)%size;

}

bool FifoPop(myfifo_t* handle, void* data)
{
   uint8_t size        = handle->fifo_size;
   uint8_t item_size   = handle->item_size;

   if (!handle) return false;

   if (-1 == handle->rIndex){
      handle->rIndex = 0;
   }

   if (handle->rIndex == handle->wIndex){
       return false;
   }

   int offset = item_size*handle->rIndex;
   memcpy(data, handle->queue+offset, item_size);
   handle->rIndex = (handle->rIndex+1)%size;;
}

uint8_t GetQueueRealSize(myfifo_t* handle)
{
    if (handle->wIndex >= handle->rIndex) {
        return (handle->wIndex - handle->rIndex);
    }
    else if(handle->wIndex < handle->rIndex){
        retrun (handle->fifo_size - handle->rIndex + 1 + handle->rIndex);
    }

}

bool IsFull()
{
    return (handle->wIndex == handle->rIndex);
}

bool IsEmpty()
{
    return ((handle->rIndex+1)%size == handle->wIndex);
}

内存池

typedef struct {
    DevMsg_List_t** m_arrMsgList;
    uint8_t* m_freeFlag;
    uint16_t m_poorUseSize;
    uint16_t m_poorMaxSize;
    uint16_t m_poorIndex;
}Mem_PoorHandle_t;

/*******消息队列内存池 add by: huanglidi*******/
bool GetNodeFlag(Mem_PoorHandle_t *pHandle, uint16_t index)
{
    if (NULL == pHandle || NULL == pHandle->m_freeFlag)
    {
        return false;
    }
    if (index < 0 || index > pHandle->m_poorMaxSize)
    {
        return false;
    }

    return pHandle->m_freeFlag[index/8] & (1 << (index%8));
}

void SetNodeFlag(Mem_PoorHandle_t *pHandle, uint16_t index, bool set)
{
    if (NULL == pHandle || NULL == pHandle->m_freeFlag)
    {
        return;
    }
    if (index < 0 || index > pHandle->m_poorMaxSize)
    {
        return;
    }

    if (set)
    {
        pHandle->m_freeFlag[index/8] |= (1 << (index%8));
        if (pHandle->m_poorUseSize < pHandle->m_poorMaxSize)
            pHandle->m_poorUseSize++;
    }
    else
    {
        pHandle->m_freeFlag[index/8] &= ~(1 << (index%8));
        if (pHandle->m_poorUseSize > 0)
            pHandle->m_poorUseSize--;
    }
}

void RealeseMsgNodePoor(Mem_PoorHandle_t* pHandle);

//初始化内存池
void InitMsgNodePoor(Mem_PoorHandle_t *pHandle, uint16_t size)
{
    if (!pHandle)
    {
        return;
    }

    if (NULL != pHandle->m_arrMsgList || NULL != pHandle->m_freeFlag)
    {
        RealeseMsgNodePoor(pHandle);
    }

    pHandle->m_poorUseSize   = 0;
    pHandle->m_poorIndex     = 0;
    pHandle->m_poorMaxSize   = size;

    //
    pHandle->m_arrMsgList = rt_malloc(size*sizeof(DevMsg_List_t *));
    for(int i = 0; i < size; i++)
    {
        pHandle->m_arrMsgList[i] = rt_malloc(sizeof(DevMsg_List_t));
    }
    pHandle->m_freeFlag = rt_malloc(size/8+1);

    memset(pHandle->m_freeFlag, 0, size/8+1);
}

//释放内存池
void RealeseMsgNodePoor(Mem_PoorHandle_t* pHandle)
{
   if (!pHandle) return;

   for(int i = 0; i < pHandle->m_poorMaxSize; i++)
   {
       rt_free(pHandle->m_arrMsgList[i]);
   }
   rt_free(pHandle->m_arrMsgList);
   rt_free(pHandle->m_freeFlag);

   pHandle->m_arrMsgList     = NULL;
   pHandle->m_freeFlag       = NULL;
   pHandle->m_poorUseSize    = 0;
   pHandle->m_poorMaxSize    = 0;
   pHandle->m_poorIndex      = 0;

}
//从内存池获取一个节点
DevMsg_List_t* GetOneFreeNode(Mem_PoorHandle_t *pHandle)
{
    if (!pHandle || pHandle->m_poorUseSize >= pHandle->m_poorMaxSize)    //已经没有空闲节点了
    {
        return NULL;
    }
    uint16_t last = pHandle->m_poorIndex;

    do{
        if (!GetNodeFlag(pHandle, pHandle->m_poorIndex))
        {
            SetNodeFlag(pHandle, pHandle->m_poorIndex, true);   //设置使用标志
            return pHandle->m_arrMsgList[pHandle->m_poorIndex];
        }
        pHandle->m_poorIndex = (pHandle->m_poorIndex+1)%pHandle->m_poorMaxSize;
    }while(pHandle->m_poorIndex != last);

    return NULL;
}

//释放一个内存池节点, 以便其他人继续继续使用, 注意: 节点内存不会释放
void FreePoorNode(Mem_PoorHandle_t *pHandle, DevMsg_List_t* node)
{
    if (NULL == pHandle || NULL == pHandle->m_arrMsgList) return;
    for(int i = 0; i < pHandle->m_poorMaxSize; i++)
    {
       if (pHandle->m_arrMsgList[i] && pHandle->m_arrMsgList[i] == node)
       {
           SetNodeFlag(pHandle, i, false);
           break;
       }
    }
}
/**********************内存池**************************/

这里是项目中用到的一些常用数据结构,后面会继续补充!

负数补码形式

正数,本身就是补码。负数,就用它的正数,减一取反,即可得到补码。如,已知:+9 的二进制是:0000 1001。下面求-9 补码:先减一:0000 1001 - 1 = 0000 1000;再取反:1111 0111。

标签:handle,C语言,rIndex,几种,item,pHandle,return,数据结构,size
From: https://www.cnblogs.com/HuangLiDi/p/18131483

相关文章

  • 27.C语言顺序循环结构结构练习题整理
    参考:https://www.qingsuyun.com/lib/d/600120380038000300010041/6、【单选题】语句while(!e);中的条件!e等价于()。[2分] ***AA、e==0B、e!=1C、e!=0D、~e9、【单选题】以下叙述正确的是()。[2分] ****BA、continue语句的作用是结束整个循环的执行......
  • 实验2 C语言分支与循环基础应用编程
    //task1.c#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5intmain(){intnumber;inti;srand(time(0));//以当前系统时间作为随机种子for(i=0;i<N;++i){number=rand()%65+1; printf("20238331%04d\n&......
  • C语言09-指针(指针数组、数组指针、字符指针),值传递和引用传递,指针和函数,注释写法
    第12章指针pointer12.3指针和数组①数组名可以把数组名当做是存储了首元素地址的常量。//arr的类型表示为int[5]intarr[5]={10,20,30,40,50};②指针数组指针数组(PointerArray)是一个数组,其中的每个元素都是指针。intnum1=10,num2=20,num3=30;//ptr_......
  • Java中Array.sort()的几种用法简明教程 (需要初始化要排序的对象)对 一个数组的所有元素
    Java中Array.sort()的几种用法简明教程(需要初始化要排序的对象)对一个数组的所有元素进行排序,并且是按从小到大的顺序Java中Array.sort()的几种用法简明教程(需要初始化要排序的对象)======================================================1、Arrays.sort(int[]a)......
  • c语言通过cgi做网站
    效果图:       主代码如下:#include<stdlib.h>#include<stdio.h>#include"hiredis/hiredis.h"#include"mysql/mysql.h"#pragmacomment(lib,"libmysql")#include<libmemcached/memcached.h>#include<......
  • C语言程序设计(第四版)第五章主要内容
    本章主要讲述<选择控制结构>一、关系运算符与表达式1.既不能在<=、>=、==、!=的符号中间插入空格,也不能将!=、<=、>=的两个符号写反,更不能以相应的数学运算符相混淆。2.不要将==误写为=。3.用非0值表示"真",用0值表示"假"。二、用于单分支控制的条件语句if(表达式p) 语......
  • C语言 位域
    C语言的位域(bit-field)是一种特殊的结构体成员,允许我们按位对成员进行定义,指定其占用的位数。如果程序的结构中包含多个开关的变量,即变量值为TRUE/FALSE,如下:struct{unsignedintwidthValidated;unsignedintheightValidated;}status;这种结构需要8字节的......
  • 从零开始学习C语言 第一篇如何学习C语言
    想必大家和我一样,都是在B站上大学,或者报一些网课,我自己学习下来发现“鹏哥C语言”(B站上搜鹏哥C语言)是一个很不错的网课,里面有专属于你的问答群,四五个老师服务你一个人,并且有问必答,除了编程方面的,学习、生活方面的问题都可以和他们沟通,他们会像长者一样毫无保留地为你传道授业解......
  • 数据结构之顺序表(java语言版)
    顺序表是最简单的线性表,也就是数组。很多语言都把把它当做内置的基本数据类型,这里的数组没有对应数据结构的操作。数组是顺序存储的结构,连续分配一段内存用于存储数据。在逻辑结构和物理结构上都是连续的。顺序表建立在java内置的数组上建立顺序表。publicclassArray{ pri......
  • 数据结构之栈(java语言版)
    栈(stack):在逻辑上是一种线性存储结构,它有以下几个特点:1、栈中数据是按照"后进先出(LIFO,LastInFirstOut)"方式进出栈的。2、向栈中添加/删除数据时,只能从栈顶进行操作。栈通常包括的三种操作:push、peek、pop。push--向栈中添加元素。peek--返回栈顶元素。pop--返......