我們來看看鏈表的接口定義:
清單 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. 運行結果