前言
上一篇博文记录了使用vector来实现容器,这篇将会介绍使用双向链表list来实现容器。
list
双向链表定义如下:
typedef struct _list_node list_node_t;
struct _list_node
{
/* 数据节点的data,要放在首段,否则会出现灾难性后果 */
type_value_t data;
list_node_t* prev;
list_node_t* next;
};
typedef struct _list
{
container_t container;
list_node_t _sentinel;
size_t _size;
} list_t;
- 列表中节点node,node中的第一个字段必须是type_value_t。否则迭代器器的iterator_dereference宏将会有错误的操作。如果不把type_value_t放在第一个字段,dereference操作会错误把其他字节的内存拷贝出来。
- 同样,container_t 接口必须放在list结构体的第一个字段。
- sentinel,标兵。用于head与tail的作用。
list接口实现
- list的一些宏
#define list_head(list) (&(((list_t*)list)->_sentinel))
#define list_tail(list) (&(((list_t*)list)->_sentinel))
#define list_first(list) (list_head(list)->next)
#define list_last(list) (list_tail(list)->prev)
- first
static iterator_t _list_first (container_t* plist)
{
return _get_iter(list_first(plist), plist);
}
- last
static iterator_t _list_last (container_t* plist)
{
return _get_iter(list_last(plist), plist);
}
- search
static iterator_t _list_search (container_t* container, iterator_t offset, type_value_t find, int(compare)(type_value_t data1, type_value_t data2))
{
iterator_t first = offset;
iterator_t tail = container_tail(container);
for(;!iterator_equal(first, tail); first = iterator_next(first)) {
if (compare(iterator_dereference(first), find) == 0) {
return first;
}
}
// 返回边界的指针
return first;
}
- insert
static int _list_insert(container_t* container, iterator_t pos, type_value_t data)
{
list_node_t *pnode = iterator_reference(pos);
list_node_t *pnew = allocate(container_pool(container), sizeof(list_node_t));
// 赋值 和 插入
pnew->data = data;
pnew->prev = pnode->prev;
pnew->next = pnode;
pnode->prev->next = pnew;
pnode->prev = pnew;
list_t *plist = container;
plist->_size++;
return 0;
}
- remove
static int _list_remove(container_t* container, iterator_t pos, type_value_t* rdata)
{
// 删除
// 边界的东西不能移除
if (!iterator_is_boundary(pos)){
list_t* list = container;
list_node_t* pnode = iterator_reference(pos);
pnode->prev->next = pnode->next;
pnode->next->prev = pnode->prev;
if (rdata) {
*rdata = iterator_dereference(pos);
}
// 回收
deallocate(container_pool(container), pnode);
list->_size--;
return 0;
}
- size
static size_t _list_size(container_t* container)
{
return ((list_t*)container)->_size;
}
- sort
static int _list_sort(container_t* container, int(*compare)(type_value_t, type_value_t))
{
return quick_sort(container_first(container), container_last(container), compare);
}
- 绑定容器接口
void init_list(list_t* list, pool_t* _pool) {
initialize_container(list, _list_first, _list_last, _list_search, _list_insert, _list_remove, _list_sort, _list_size, _pool);
list_first(list) = list_head(list);
list_last(list) = list_tail(list);
list->_size = 0;
list->_sentinel.data = int_type(-1);
return;
}
- 迭代器接口
static iterator_t _move(iterator_t it, int step)
{
list_node_t* pnode = iterator_reference(it);
for(int next = step; next; next = step > 0? --step:++step) {
if (next > 0) pnode = pnode->next;
else if (next < 0) pnode = pnode->prev;
}
return iterator_set_reference(it, pnode);
}
完
《第一篇,数据类型》
《第二篇,迭代器》
《第三篇,容器接口》
《第四篇,vector实现的容器》
《第五篇,list实现的容器》
《第六篇,排序》
项目地址