#ifndef LIST_H_
#define LIST_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FAILURE (-1)
#define SUCCESS (0)
#define RETURN_VALUE_IF_FAILED(expr, val) do { if (!(expr)) { return val; }} while (0)
#define MALLOC(n, type) ( (type*)malloc( (n)*sizeof(type) ) )
/* 链表节点封装 */
typedef struct node{
void *datap;
struct node *prev;
struct node *next;
} node_t;
/* 链表类型封装 */
typedef struct list {
int n; ///< 链表中节点的个数
int size; ///< 链表节点中存放数据的空间大小
node_t head; ///< 链表的头节点
} list_t;
/* 回调函数类型定义 */
typedef int compare_t(void *data1, void *data2);
/* 初始化链表 */
list_t *init_list(int size);
/* 新建一个节点 */
// node_t *create_node(int size);
/* 插入节点 */
void insert_node(node_t *prev_node, node_t *next_node, node_t *new_node);
/* 头部插入节点 */
int append_node_top(list_t *list, void *data);
/* 尾部插入节点 */
int append_node_tail(list_t *list, void *data);
/* 排序插入节点 */
int sort_insert(list_t *list, compare_t *func, void *data);
/* 条件查找节点,匹配第一个 */
void *search_node_by_item(list_t *list, compare_t *func, void *item);
/* 条件查找节点,匹配所有 */
list_t *search_nodes_by_item(list_t *list, compare_t *func, void *item);
/* 删除符合条件的第一个节点 */
int delete_node_by_item(list_t *list, compare_t *func, void *item);
/* 删除符合条件的所有节点 */
int delete_nodes_by_item(list_t *list, compare_t *func, void *item);
/* 链表排序 */
void sort_list(list_t *list, compare_t *func);
/* 前向遍历链表 */
void traverse_list_forward(list_t *list, void (*func)(void *data));
/* 后向遍历链表 */
void traverse_list_backward(list_t *list, void (*func)(void *data));
/* 判断链表是否为空 */
int is_list_empty(list_t *list);
/* 销毁链表 */
void destory_list(list_t *list);
#endif // !LIST_H_
#include "slist.h"
/* 初始化链表 */
list_t *init_list(int size) {
list_t *temp;
/* 分配链表空间 */
temp = (list_t *)malloc(sizeof(list_t));
RETURN_VALUE_IF_FAILED(NULL != temp, NULL);
/* 初始化链表 */
temp->size = size;
temp->n = 0;
temp->head.next = &temp->head;
temp->head.prev = &temp->head;
return temp;
}
/* 新建一个节点 */
static node_t *create_node(int size) {
node_t *new_node = MALLOC(sizeof(node_t), node_t);
RETURN_VALUE_IF_FAILED(NULL != new_node, NULL);
new_node->datap = MALLOC(size, void);
RETURN_VALUE_IF_FAILED(NULL != new_node->datap, NULL);
return new_node;
}
/* 插入节点 */
void insert_node(node_t *prev_node, node_t *next_node, node_t *new_node) {
new_node->next = next_node;
new_node->prev = prev_node;
prev_node->next = new_node;
next_node->prev = new_node;
}
/* 头部插入节点 */
int append_node_top(list_t *list, void *data) {
node_t *new_node = create_node(list->size);
RETURN_VALUE_IF_FAILED(NULL != new_node, FAILURE);
memmove(new_node->datap, data, list->size);
insert_node(&list->head, list->head.next, new_node);
list->n += 1;
return SUCCESS;
}
/* 尾部插入节点 */
int append_node_tail(list_t *list, void *data) {
node_t *new_node = create_node(list->size);
RETURN_VALUE_IF_FAILED(NULL != new_node, FAILURE);
memmove(new_node->datap, data, list->size);
insert_node(list->head.prev, &list->head, new_node);
list->n += 1;
return SUCCESS;
}
/* 排序插入节点 */
int sort_insert(list_t *list, compare_t *func, void *data) {
node_t *new_node = create_node(list->size);
RETURN_VALUE_IF_FAILED(NULL != new_node, FAILURE);
memmove(new_node->datap, data, list->size);
node_t *i;
for (i = list->head.next; i != &list->head; i = i->next) {
if (func(i->datap, data) >= 0) {
break;
}
}
insert_node(i->prev, i, new_node);
list->n += 1;
return SUCCESS;
}
/* 条件查找节点,匹配第一个 */
void *search_node_by_item(list_t *list, compare_t *func, void *item) {
node_t *i;
i = list->head.next;
while (i != &list->head) {
if (func(i->datap, item) == 1) {
return i->datap;
}
i = i->next;
}
return NULL;
}
/* 条件查找节点,匹配所有 */
list_t *search_nodes_by_item(list_t *list, compare_t *func, void *item) {
list_t *result;
node_t *i;
result = init_list(list->size);
RETURN_VALUE_IF_FAILED(NULL != result, NULL);
i = list->head.next;
while (i != &list->head) {
if (func(i->datap, item) == 1) {
append_node_tail(result, i->datap);
}
i = i->next;
}
return result;
}
/* 删除符合条件的第一个节点 */
int delete_node_by_item(list_t *list, compare_t *func, void *item) {
node_t *i = list->head.next;
while (i != &list->head) {
if (func(i->datap, item) == 1) {
i->next->prev = i->prev;
i->prev->next = i->next;
free(i->datap);
free(i);
list->n -= 1;
return 0;
}
i = i->next;
}
return FAILURE;
}
/* 删除符合条件的所有节点 */
int delete_nodes_by_item(list_t *list, compare_t *func, void *item) {
int count = 0;
node_t *i, *next;
i = list->head.next;
while (i != &list->head) {
if (func(i->datap, item) == 1) {
next = i->next;
i->next->prev = i->prev;
i->prev->next = i->next;
free(i->datap);
free(i);
list->n -= 1;
count++;
i = next;
continue;
}
i = i->next;
}
return count;
}
/* 链表排序 */
void sort_list(list_t *list, compare_t *func) {
node_t *i, *j;
void *temp;
for (i = list->head.next; i != &list->head; i = i->next) {
for (j = i->next; j != &list->head; j = j->next) {
if (func(i->datap, j->datap) == 1) {
temp = i->datap;
i->datap = j->datap;
j->datap = temp;
}
}
}
}
/* 前向遍历链表 */
void traverse_list_forward(list_t *list, void (*func)(void *data)) {
node_t *i;
for (i = list->head.next; i != &list->head; i = i->next) {
func(i->datap);
}
}
/* 后向遍历链表 */
void traverse_list_backward(list_t *list, void (*func)(void *data)) {
node_t *i;
for (i = list->head.prev; i != &list->head; i = i->prev) {
func(i->datap);
}
}
/* 判断链表是否为空 */
int is_list_empty(list_t *list) {
return list->head.next == &list->head && list->head.prev == &list->head;
}
/* 销毁链表 */
void destory_list(list_t *list) {
node_t *i, *next;
i = list->head.next;
while (i != &list->head) {
next = i->next;
free(i->datap);
free(i);
i = next;
}
free(list);
}
#ifndef DIMENSION_H_
#define DIMENSION_H_
#include "slist.h"
/* 量纲类型 */
typedef struct {
char name[32];
unsigned int conversion;
// unsigned int value;
}dimension_t;
/* 实例,继承量纲信息 */
typedef struct {
dimension_t unit_info;
unsigned int value;
}dim_inst_t;
typedef struct {
dimension_t unit_info;
list_t* unit_list;
// unit_register_fun unit_register;
}dim_init_table_t;
/* 构造一个度量单位列表 */
list_t *struct_a_unit_list(void);
int register_unit(char *name, unsigned int conversion, list_t *unit_list);
int register_dim_init_table(dim_init_table_t *dim_init_table, int size);
void printf_dimension(dimension_t *datap);
#endif // !DIMENSION_H_
#include "dimension.h"
list_t *struct_a_unit_list(void) {
list_t *temp = init_list(sizeof(dimension_t));
return temp;
}
void printf_dimension(dimension_t *datap) {
printf("name :%s\n", datap->name);
printf("conversion:%d\n", datap->conversion);
// printf("value :%d\n", datap->value);
}
static dimension_t *struct_a_unit(char *name, unsigned int conversion) {
dimension_t *temp = MALLOC(sizeof(dimension_t), dimension_t);
RETURN_VALUE_IF_FAILED(NULL != temp, NULL);
RETURN_VALUE_IF_FAILED(NULL != name, NULL);
memcpy(temp->name, name, sizeof(temp->name));
temp->conversion = conversion;
return temp;
}
int register_unit(char *name, unsigned int conversion, list_t *unit_list) {
dimension_t *temp = struct_a_unit(name, conversion);
if (NULL == temp || SUCCESS != append_node_tail(unit_list, temp)) {
return FAILURE;
}
return SUCCESS;
}
int register_dim_init_table(dim_init_table_t *dim_init_table, int size) {
int i;
RETURN_VALUE_IF_FAILED(NULL != dim_init_table, FAILURE);
RETURN_VALUE_IF_FAILED(0 < size, FAILURE);
printf("size:%d\n", size);
for (i = 0; i < size; i++) {
register_unit(
dim_init_table[i].unit_info.name,
dim_init_table[i].unit_info.conversion,
dim_init_table[i].unit_list);
}
return SUCCESS;
}
#include "dimension.h"
#include "slist.h"
int main(void) {
/* 创建一个保存单位类型的链表并初始化*/
list_t *len_unit_list = struct_a_unit_list();
RETURN_VALUE_IF_FAILED(NULL != len_unit_list, FAILURE);
list_t *vol_unit_list = struct_a_unit_list();
RETURN_VALUE_IF_FAILED(NULL != vol_unit_list, FAILURE);
dim_init_table_t dim_init_table[] = {
/* 长度系统度量类型 */
{{"Base", 1}, len_unit_list},
{{"Inch", 1}, len_unit_list},
{{"Feet", 12}, len_unit_list},
{{"Yard", 12*3}, len_unit_list},
{{"Mile", 1760*12*3}, len_unit_list},
/* 体积系统度量类型 */
{{"Base", 1}, vol_unit_list},
{{"TSP", 1}, vol_unit_list},
{{"TBSP", 12}, vol_unit_list},
{{"OZ", 12*3}, vol_unit_list},
};
/* 注册以上度量单位 */
RETURN_VALUE_IF_FAILED(
FAILURE != register_dim_init_table(dim_init_table, sizeof(dim_init_table)/sizeof(dim_init_table_t)),
FAILURE);
/* 遍历打印链表 */
traverse_list_backward(len_unit_list, printf_dimension);
traverse_list_backward(vol_unit_list, printf_dimension);
destory_list(len_unit_list);
destory_list(vol_unit_list);
}