我们来看看链表的接口定义:
清单 1. 链表的接口定义
#ifndef _ILIST_H #define _ILIST_H
// 定义链表中的节点结构 typedef struct node{ void *data; struct node *next; }Node;
// 定义链表结构 typedef struct list{ struct list *_this; Node *head; int size; void (*insert)(void *node);// 函数指针 void (*drop)(void *node); void (*clear)(); int (*getSize)(); void* (*get)(int index); void (*print)(); }List;
void insert(void *node); void drop(void *node); void clear(); int getSize(); void* get(int index); void print();
#endif /* _ILIST_H */
|
IList 接口中,可以清晰的看到,对于一个 list 实体 ( 也就是对象 ) 来说,可以在其上进行 insert, drop, clear, getSize, get(index) 以及 print 等操作。
接口的实现
清单 2. 构造方法
Node *node = NULL; List *list = NULL;
void insert(void *node); void drop(void *node); void clear(); int getSize(); void print(); void* get(int index);
List *ListConstruction(){ list = (List*)malloc(sizeof(List)); node = (Node*)malloc(sizeof(Node)); list->head = node; list->insert = insert;// 将 insert 函数实现注册在 list 实体上 list->drop = drop; list->clear = clear; list->size = 0; list->getSize = getSize; list->get = get; list->print = print; list->_this = list;// 用 _this 指针将 list 本身保存起来
return (List*)list; }
|
需要注意的是此处的 _this 指针,_this 指针可以保证外部对 list 的操作映射到对 _this 的操作上,从而使得代码得到简化。
清单 3. 插入及删除
// 将一个 node 插入到一个 list 对象上 void insert(void *node){ Node *current = (Node*)malloc(sizeof(Node));
current->data = node; current->next = list->_this->head->next; list->_this->head->next = current; (list->_this->size)++; }
// 删除一个指定的节点 node void drop(void *node){ Node *t = list->_this->head; Node *d = NULL; int i = 0; for(i;i < list->_this->size;i++){ d = list->_this->head->next; if(d->data == ((Node*)node)->data){ list->_this->head->next = d->next; free(d); (list->_this->size)--; break; }else{ list->_this->head = list->_this->head->next; } } list->_this->head = t; }
|
其他的实现代码可以参看下载部分,这里限于篇幅就不再意义列举出来。
测试
测试代码
好了,前面做的一切工作都是为了保证我们的暴露给使用者的 API 可以尽量的简洁,优美,现在到测试的时候了:
清单 4. 测试代码
int main(int argc, char** argv) { List *list = (List*)ListConstruction();// 构造一个新的链表
// 插入一些值做测试 list->insert("Apple"); list->insert("Borland"); list->insert("Cisco"); list->insert("Dell"); list->insert("Electrolux"); list->insert("FireFox"); list->insert("Google");
list->print();// 打印整个列表
printf("list size = %d\n",list->getSize());
Node node; node.data = "Electrolux"; node.next = NULL; list->drop(&node);// 删除一个节点
node.data = "Cisco"; node.next = NULL; list->drop(&node);// 删除另一个节点
list->print();// 再次打印 printf("list size = %d\n",list->getSize()); list->clear();// 清空列表
return 0; }
|
图 1. 运行结果