我们来看看链表的接口定义:


清单 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. 运行结果