静态内存分配-链表管理(1)单向量表讲解

来源:互联网 发布:社团团徽设计软件 编辑:程序博客网 时间:2024/05/29 04:57

单向链表

单向量表有头节点 和节点组成,头节点主要是管理链表使用,节点组成数据。

数据结构

头节点结构
**last指向尾节点的Next指针,在节点尾部插入节点时,直接调整头节点的last内容的指向即可在尾部插入。first指针指向链表的首节点。
节点结构
value是数据,Next指向下一个节点。

链表操作

链表成员变量定义

成员变量主要有头结点和节点,头结点不是真正的有效数据,主要是利于链表的插入,遍历等,节点是链表中主要的数据。

代码

定义节点

#define SIMPLEQ_ENTRY(type)                     \struct {    \struct type *sqe_next;  /* next element */          \}

上述代码定义了节点中的Next指针域,type是链表的类型,例如链表节点定义如下:

struct items_type{SIMPLEQ_ENTRY(items_type) field; u8 value;};

上述代码定义了一个链表节点类型,可使用该类型定义一个节点。例如

struct items_type node0 = {.value = 0};struct items_type node1 = {.value = 1};struct items_type node2 = {.value = 2};struct items_type node3 = {.value = 3};

定义了三个节点。

#define SIMPLEQ_HEAD(name, type)                    \struct name {                               \struct type *sqh_first; /* first element */         \    struct type **sqh_last; /* addr of last next element */     \}

上述代码定义了链表的头节点。name为头结点的名字,type为节点的类型,例子

SIMPLEQ_HEAD(head, items_type) list_head;

上述代码定义了名为 list_head的头节点。

API

#define SIMPLEQ_ENTRY(type)

定义节点类型,类型名为type。

#define SIMPLEQ_HEAD(name, type)

定义头节点,name为头节点名,type为节点类型。

#define SIMPLEQ_HEAD_INITIALIZER(head)#define SIMPLEQ_INIT(head)

两个API作用相同,头节点初始化。

#define SIMPLEQ_INSERT_HEAD(head, elm, field)

在链表首部插入一个节点,head为头节点,elm为要插入的元素,filed为指针域,与节点类型有关,上面的例子中类型的指针域名为filed,以后的使用过程也必须用filed。

#define SIMPLEQ_INSERT_TAIL(head, elm, field)

在链表的尾部插入一个节点,head为头节点,lem为要插入的元素,filed见上述解释。

#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field)

在链表的listelm节点后插入elm节点。其他见上述解释。

#define SIMPLEQ_REMOVE_HEAD(head, field)

移除链表中的首节点。

#define SIMPLEQ_REMOVE(head, elm, type, field)SIMPLEQ_REMOVE(&list_head, &node1, items_type, field);

移除链表中的elm节点,type为节点的类型。

#define SIMPLEQ_FOREACH(var, head, field)SIMPLEQ_FOREACH(ptype, &list_head, field) {    printf("value = %4d,", ptype->value);}

遍历链表,例子如上。

#define SIMPLEQ_EMPTY(head)

链表是否为空。

#define SIMPLEQ_FIRST(head)

找出首节点。

#define SIMPLEQ_NEXT(elm, field)

找出链表中某个元素的下一个元素。

图形说明

单向链表插入说明
上图为单向链表说明
双向链表说明

测试代码

#include "queue.h"#include "types.h"#include "stdio.h"struct items_type{    SIMPLEQ_ENTRY(items_type) field;    u8 value;//Êý¾ÝÓò£¬´æ´¢Êý¾Ý};SIMPLEQ_HEAD(head, items_type) list_head;void List_Init(void){    SIMPLEQ_INIT(&list_head);}struct items_type node0 = {.value = 0};struct items_type node1 = {.value = 1};struct items_type node2 = {.value = 2};struct items_type node3 = {.value = 3};void List_Insert(void){    if (SIMPLEQ_EMPTY(&list_head)) {            SIMPLEQ_INSERT_HEAD(&list_head, &node0, field);             SIMPLEQ_INSERT_HEAD(&list_head, &node1, field);                            SIMPLEQ_INSERT_HEAD(&list_head, &node2, field);            SIMPLEQ_INSERT_AFTER(&list_head, &node2, &node3, field);            /*2310*/    } else {            SIMPLEQ_INSERT_TAIL(&list_head, &node0, field);            SIMPLEQ_INSERT_TAIL(&list_head, &node1, field);            SIMPLEQ_INSERT_TAIL(&list_head, &node2, field);    }}#if 0void List_Travel(void){    struct items_type * ptype = NULL;           do {            ptype = SIMPLEQ_FIRST(&list_head);            if (ptype == NULL) {                    break;            } else {                    printf("%d\r\n", ptype->value);                    //ÒƳýµÚÒ»¸ö½áµã                    SIMPLEQ_REMOVE_HEAD(&list_head, field);            }    }while(ptype != NULL);

}
#else

void List_Travel(void){    struct items_type  *ptype;    SIMPLEQ_FOREACH(ptype, &list_head, field) {            printf("value = %4d,", ptype->value);    }    printf("\r\n");}#endifvoid ListItems_Remove(void){        SIMPLEQ_REMOVE(&list_head, &node1, items_type, field);}void ListFirst(void){        struct items_type *type;        type = SIMPLEQ_FIRST(&list_head);        printf("%4d\r\n", type->value);}void SimpleQueue_Test(void){    List_Init();    List_Insert();    List_Travel();    ListItems_Remove();    List_Travel();    ListFirst();    while(1) {    }}
0 0