OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3715|回复: 9

最近处理一些大数据,用到链表,写了几个函数,分享给大家。

[复制链接]

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1822
金钱
1822
注册时间
2014-6-27
在线时间
978 小时
发表于 2016-11-4 14:09:50 | 显示全部楼层 |阅读模式

typedef struct Node
{
        u8 host_id;
        u8 road_id;
        u8 dev_id;
        u8 event_type:4;
        u8 month  :4;
        u16 day                 :5;
        u16 hour   :5;
        u16 min    :6;
        struct Node *next;
}Chain_Node;



Chain_Node *Print_Str_Head=0,*Print_Str_Tail=0;
Chain_Node *Event_Info_Head[5],*Event_Info_Tail[5];



/*
事件信息节点添加,区分添加的信息类别,把新来的信息添加到
链表的头,新的节点更新为链表的头
*/
Chain_Node* Creat_One_Event_Info_Node(u8 *buf,u8 type)//把新信息加到链表的头
{
       
          Chain_Node *p_new,*p_head;
    p_new=(Chain_Node*)malloc(sizeof(Chain_Node));
    if(p_new==NULL)return p_new;
    p_new->host_id=buf[0];       
    p_new->road_id=buf[1];p_new->dev_id=buf[2];
    p_new->event_type=buf[7]%9;       
    p_new->month=buf[3]%13;p_new->day=buf[4]%32;p_new->hour=buf[5]%24;p_new->min=buf[6]%60;               
    if(Event_Info_Head[type]==NULL)
                {
                Event_Info_Head[type]=p_new;
                                                                Event_Info_Tail[type]=p_new;
                                                                Event_Info_Tail[type]->next=NULL;
                }
     else
                 {
                                                                p_head=Event_Info_Head[type];
                                                                Event_Info_Head[type]=p_new;
                                                                Event_Info_Head[type]->next=p_head;
                 }
     return  Event_Info_Head[type];  
}
/*
删除一个事件信息,事件恢复一个释放一个
*/
Chain_Node* Delete_One_Event_Info_Node(u8 *buf,u8 type)
{
    Chain_Node *p=Event_Info_Head[type],*p1,*p2,*tmp;       
    while(p)
    {
                        if((p->host_id==buf[0])&&(p->road_id==buf[1])&&(p->dev_id==buf[2]))
                        {
                                               
                                                if(p==Event_Info_Head[typ)//释放的是头节点
                                                {
                                                                        tmp=p;//保存头节点先,好释放
                                                                        p=p->next;//往下走一个
                                                                        Event_Info_Head[type]=p;//更新头节点
                                                                        free(tmp);
                                                                        break;//释放后可以继续查找也可以跳出
                                                }
                                                else
                                                {
                                                                        p1->next=p2;//释放的不是头节点,当前节点的前一个链到当前节点的后一个
                                                                        free(p);//释放当前节点
                                                                        p=p2;//原来当前节点的后一个更新为当前节点
                                                                        break;//释放后可以继续查找也可以跳出
                                                }
                        }
                        else//释放的信息不是当前节点
                        {
                                                p1=p;//保持当前节点地址
                                                p=p->next;//当前地址下移一个
                                                if(p)//没有到尾巴,保存当前节点的下一个节点地址
                                                p2=p->next;
                                                else p2=p;//到尾巴了,给NULL
                        }
                       
               
    }
    return Event_Info_Head[type];
}
/*
得到链表节点的数量
*/
u16 Get_Even_Info_Node_Num(u8 type)
{
                        u16 cnt=0;
                        Chain_Node *p;
                        p=Event_Info_Head[type];
                        while(p)
                        {
                                        cnt++;
                                        p=p->next;
                        }
                        return cnt;
}

/*

定位一个节点,得到这个节点的地址
*/
Chain_Node* Find_One_Event_Info_Node(u16 offset,u8 type)
{
    Chain_Node *p=Event_Info_Head[type];       
                u16 x=0;
                while(p)
                {
                                        if(x==offset)break;
                                        x++;
                                        p=p->next;
                }       
                return p;       
}


/*

软件复位系统需要调用此函数释放所有的开辟的动态内存
否则有死机的风险
*/
void Free_All_Event_Info_Nodes(u8 type)
{
                        Chain_Node *p,*p_head;
                        p=Event_Info_Head[type];
                        Event_Info_Tail[type]=NULL;
                        if(p==NULL)return;
                        Event_Info_Head[type]=NULL;
            while(p)
                        {
                                        p_head=p;
                                  p=p->next;
                                        free(p_head);
                        }
                       
       
       
}

/*
建立打印信息链表,来一条打印信息就添加一个节点到尾巴

*/
void Creat_Print_One_Node(u8 *buf)//把新信息加到链表的尾
{
    Chain_Node *p_new=NULL;//*p_tail=NULL,*p_head=NULL;
    p_new=(Chain_Node*)malloc(sizeof(Chain_Node));
    if(p_new==NULL)return;
    p_new->host_id=buf[0];       
    p_new->road_id=buf[1];p_new->dev_id=buf[2];
    p_new->event_type=buf[7]%9;       
            p_new->month=buf[3]%13;p_new->day=buf[4]%32;p_new->hour=buf[5]%25;p_new->min=buf[6]%60;               
    if(Print_Str_Head==NULL)
                Print_Str_Head=p_new;
        else
                Print_Str_Tail->next=p_new;

        Print_Str_Tail=p_new;
        Print_Str_Tail->next=NULL;       

}
/*
删除一个打印节点,先来先打印,每次打印的是头,所以每次删除一个头节点,
返回一个新的头节点

*/
Chain_Node* Delete_One_Print_Node(Chain_Node *p_head)
{
    Chain_Node *p_tmp=NULL;               
    if(p_head)
    {
            p_tmp=p_head;
            p_head=p_head->next;
            free(p_tmp);
    }
    return p_head;
}

void Printf_Display_Str(Chain_Node *p_head)
{
        char type_p[][9] = { {"火警"},{"启动"},{"反馈"},{"故障"},{"屏蔽"},{"停止"},{"反馈恢复"},{"故障恢复"},{"总线故障"},{"总线恢复"},{"开机"},{"关机"},{"登记"},{"刷新"},{"下载"},{"同步"},{"通讯"},{"未知"}};
       
        char print_msg[40];char print_date[40],flag=0;
        char print_location[40];
        if(p_head->dev_id==250)
        {
                sprintf(print_msg,"%02d机%d路开路故障 %d-%d-%d %d:%02d",p_head->host_id,p_head->road_id,YEAR,p_head->month,p_head->day,p_head->hour,p_head->min);
        }
        else if(p_head->dev_id==251)
        {
                sprintf(print_msg,"%02d机%d路短路故障 %d-%d-%d %d:%02d",p_head->host_id,p_head->road_id,YEAR,p_head->month,p_head->day,p_head->hour,p_head->min);
        }
        else if(p_head->road_id==105)
        {
                                if(p_head->dev_id<=1)sprintf(print_msg,"%02d机主电故障 %d-%d-%d %d:%02d",p_head->host_id,YEAR,p_head->month,p_head->day,p_head->hour,p_head->min);
                          else sprintf(print_msg,"%02d机备电故障 %d-%d-%d %d:%02d",p_head->host_id,YEAR,p_head->month,p_head->day,p_head->hour,p_head->min);
        }
        else
        {
                sprintf(print_msg,"%02d机%d路%d号   %s",p_head->host_id,p_head->road_id,p_head->dev_id,type_p[p_head->event_type]);
                Rd_complex_flash(p_head->road_id,p_head->dev_id);
                Location_find();
                sprintf(print_date,"%d年%d月%d日 %d时%02d分 %s",YEAR,p_head->month,p_head->day,p_head->hour,p_head->min,&Dev_Type_Tab[Rd_flash[0]][0]);
          sprintf(print_location,"位置: %s",&Rd_dc_location_msg[0]);
                flag=1;
}
        if(flag)
        {
                PrintString(print_location);
                PrintChar(0x0d);
                PrintString(print_date);
                PrintChar(0x0d);
        }
        PrintString(print_msg);
        PrintChar(0x0d);
        Print_Str_Head=Delete_One_Print_Node(p_head);//打印完一个,删除一个
       
}


void main()
{
while(1)
{
                if(v_print_flag)// 开启打印
                {      
                                if(Print_Str_Head)//有打印信息
                                {
                                        Printf_Display_Str(Print_Str_Head);       
                                }
                }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

16

主题

197

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
457
金钱
457
注册时间
2012-4-20
在线时间
91 小时
发表于 2016-11-4 14:30:55 | 显示全部楼层
感谢楼主分享!记号!日后学习!
回复 支持 反对

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-11-5 11:33:16 | 显示全部楼层
[mw_shl_code=applescript,true]u8 event_type:4;
        u8 month  :4;
        u16 day                 :5;
        u16 hour   :5;
        u16 min    :6;[/mw_shl_code]
后边的  :4  :5是什么意思,不明觉厉!
我有故事,你有酒吗
回复 支持 反对

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-11-5 11:40:21 | 显示全部楼层
来俩不甜的 发表于 2016-11-5 11:33
[mw_shl_code=applescript,true]u8 event_type:4;
        u8 month  :4;
        u16 day               ...

位段,代表长度为4bit,不过具体占据空间还与编译器有关
回复 支持 反对

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-11-5 11:42:54 | 显示全部楼层
yyx112358 发表于 2016-11-5 11:40
位段,代表长度为4bit,不过具体占据空间还与编译器有关

这不科学啊,都没超过8位,那为何后边的day hour min都定义成u16了。搞不懂,按说代码发出来秀不应该有这种bug
我有故事,你有酒吗
回复 支持 反对

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-11-5 11:46:37 | 显示全部楼层
来俩不甜的 发表于 2016-11-5 11:42
这不科学啊,都没超过8位,那为何后边的day hour min都定义成u16了。搞不懂,按说代码发出来秀不应该有这 ...

没有用过,不过我想应该意思是把一个u16拆成5,5,6这样3个位段,具体的还是问楼主吧
回复 支持 反对

使用道具 举报

58

主题

359

帖子

0

精华

高级会员

Rank: 4

积分
987
金钱
987
注册时间
2014-9-29
在线时间
261 小时
发表于 2016-11-5 13:33:03 | 显示全部楼层
来俩不甜的 发表于 2016-11-5 11:42
这不科学啊,都没超过8位,那为何后边的day hour min都定义成u16了。搞不懂,按说代码发出来秀不应该有这 ...

神回复,666
回复 支持 反对

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1822
金钱
1822
注册时间
2014-6-27
在线时间
978 小时
 楼主| 发表于 2016-11-5 17:57:23 | 显示全部楼层
来俩不甜的 发表于 2016-11-5 11:42
这不科学啊,都没超过8位,那为何后边的day hour min都定义成u16了。搞不懂,按说代码发出来秀不应该有这 ...

还有什么问题都提出来,我一一帮你解答。
回复 支持 反对

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2016-11-5 21:04:15 | 显示全部楼层
多谢楼主分享,给大数据点个赞先。好像这几年是比较流行hadoop什么的。

另外既然都用位段了,为什么不把指针成员放前面呢?
回复 支持 反对

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1822
金钱
1822
注册时间
2014-6-27
在线时间
978 小时
 楼主| 发表于 2016-11-5 21:35:31 | 显示全部楼层
xianshasaman 发表于 2016-11-5 21:04
多谢楼主分享,给大数据点个赞先。好像这几年是比较流行hadoop什么的。

另外既然都用位段了,为什么不把 ...

还要考虑内存对齐的问题,保证每个节点所占内存空间最小,指针成员放在前面也是可以的,但是其他成员也要调整下才能保证最优。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 00:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表