静态内存分配-链表管理(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) { } }
相关文章推荐
- 静态内存分配-链表管理(2)实现
- SQL服务器内存有两种基本管理方法:动态分配和静态分配
- SQL服务器内存有两种基本管理方法:动态分配和静态分配
- SQL服务器内存有两种基本管理方法:动态分配和静态分配
- SQL服务器内存有两种基本管理方法:动态分配和静态分配
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- 单链表的顺序实现例程[静态分配存储空间]
- 一个Win32 C++ 动态连接库的模板 --- 调用方可管理DLL分配的内存
- 字符内存动态分配管理类(CAutoMem)
- 全面介绍Windows内存管理机制及C++内存分配实例(五):堆
- 程序运行时的内存分配--静态的,栈式的,和堆式的
- LCC编译器的源程序分析(68)内存分配链表
- 全面介绍Windows内存管理机制及C++内存分配实例(一):进程空间
- 全面介绍Windows内存管理机制及C++内存分配实例(二):内存状态查询
- 全面介绍Windows内存管理机制及C++内存分配实例(三):虚拟内存
- LCC编译器的源程序分析(68)内存分配链表
- c++内存分配和管理
- 好久没来了,都去163写记事本了。关于Delphi的内存分配管理的几句话
- LCC编译器的源程序分析(68)内存分配链表