您的位置:首页 > 其它

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

2016-07-30 12:16 141 查看

单向链表

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

数据结构



**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 0
void 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");

}

#endif

void 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) {

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: