?
一、緣起
很早寫了一個帶頭尾指針的list,該list支持從尾部插入元素,在任意位置刪除元素,最近用這個list時發現一個bug,修正了,并加了幾個接口函數。貼出來,希望對C的初學者有用。
二、基本說明
2.1、數據結構
l???????? listnode
?
typedef struct listnode { ? ? int data;?????????? //you can add any type data here ? ? int id; ? ? struct listnode* next; } *listnode, _listnode; |
?
其中data、id用于測試程序,可換成任意數據類型。
l???????? list
?
typedef struct list { ??? struct listnode* head; ??? struct listnode* tail; ??? int count;?????????? //0 --empty ??? int current_id; } *list, _list; |
?
head、tail均指向實際元素,list為空時,指向NULL,current_id用于測試程序,可去。
2.2、函數說明
l???????? void list_init(list)
初始化list
l???????? void list_insert(list, listnode)
list的尾部插入元素
l???????? int list_delete(list, listnode)
從list上刪除指定元素,刪除成功返回1,刪除失敗返回0
l???????? void list_poll(list myroot)
遍歷整個pool,測試用
l???????? listnode new_listnode(const int id, int data)
構建新的元素,并為其分配內存
l???????? void delete_listnode(listnode mylistnode)
刪除指定元素,并釋放其內存
l???????? listnode find_node_by_data(list myroot, const int data)
根據data在list上查找匹配的元素
l???????? listnode find_node_by_id(list myroot, const int id)
根據id在list上查找匹配的元素
三、代碼
3.1、list.h:
?
/* list.h ** Copyright 2004 Coon Xu. ** Author: Coon Xu ** Date: 02 Feb 2005 */ ? #ifndef LIST_H #define LIST_H #include <stdio.h> #include <stdlib.h> ? typedef struct listnode { ? ? int data;?????????? //you can add any type data here ? ? int id; ? ? struct listnode* next; } *listnode, _listnode; ? typedef struct list { ??? struct listnode* head; ??? struct listnode* tail; ??? int count;?????????? //0 --empty ??? int current_id; } *list, _list; ? void list_init(list); void list_insert(list, listnode); int list_delete(list, listnode); void list_poll(list myroot); listnode new_listnode(const int id, int data); void delete_listnode(listnode mylistnode); listnode find_node_by_data(list myroot, const int data); listnode find_node_by_id(list myroot, const int id); ? #endif |
?
3.2、list.c:
?
/* list.c ** Copyright 2004 Coon Xu. ** Author: Coon Xu ** Date: 02 Feb 2005 */ #include "list.h" ? void list_init(list myroot) { ??? myroot->count = 0; ??? myroot->head = NULL; ??? myroot->tail = NULL; ??? myroot->current_id = 1; } ? void list_poll(list myroot) { ??? printf("-------------------------------------------------------/n"); ??? listnode p_listnode = myroot->head; ??? while(p_listnode != NULL) ??? { ??????? printf("id: %d/t data: %d/n", p_listnode->id, p_listnode->data); ??????????? ??????? p_listnode = p_listnode->next; ??? } } ? ? //insert node at the tail void list_insert(list myroot, listnode mylistnode) { ??? myroot->count++; ??? ??? mylistnode->next = NULL; ??? if(myroot->head == NULL) ??? { ??????? myroot->head = mylistnode; ??????? myroot->tail = mylistnode; ??? } ??? else ??? { ??????? myroot->tail->next = mylistnode; ??????? myroot->tail = mylistnode; ??? }??? ??? printf("[insert]:/tlist.cout:/t%d/n", myroot->count); } ? int list_delete(list myroot, listnode mylistnode) { ??? struct listnode* p_listnode = myroot->head; ??? struct listnode* pre_listnode; ??? ??? //myroot is empty ??? if(p_listnode == NULL) ??? { ??????? return 0; ??? } ? ??? //delete head node??? ??? if(p_listnode == mylistnode) ??? { ??????? myroot->count--; ??????? //myroot has only one node ??????? if(myroot->tail == mylistnode) ??????? { ??????????? myroot->head = NULL; ??????????? myroot->tail = NULL; ??????? } ??????? else ??????? { ??????????? myroot->head = p_listnode->next; ??????? } ??????? printf("[delete]:/tlist.cout:/t%d/n", myroot->count); ??????? return 1; ??? } ? ??? while(p_listnode != NULL) ??? { ??????? if(p_listnode == mylistnode) ??????? { ??????????? break; ??????? } ??????? pre_listnode = p_listnode; ??????? p_listnode = p_listnode->next; ??? } ??? if(p_listnode == NULL) ??? { ??????? printf("can not find the node.../n"); ??????? return 0; ??? } ??? else ??? { ??????? pre_listnode->next = p_listnode->next; ??????? if(myroot->tail == p_listnode) ??????? { ??????????? myroot->tail = pre_listnode; ??????? } ??????? myroot->count--; ??????? printf("[delete]:/tlist.cout:/t%d/n", myroot->count); ??????? return 1; ??? }? } ? listnode new_listnode(const int id, int data) { ??? listnode p_listnode = malloc(sizeof(_listnode)); ??? p_listnode->id = id; ??? p_listnode->data = data; ??? ??? return p_listnode; } ? void delete_listnode(listnode mylistnode) { ??? mylistnode->next = NULL; ??? free(mylistnode); ??? mylistnode = NULL; } ? listnode find_node_by_data(list myroot, const int data) { ??? listnode p_listnode = myroot->head; ??? while(p_listnode != NULL) ??? { ??????? if( p_listnode->data == data ) ??????? { ??????????? printf("find the node for data: %d/n", data); ??????????? break; ??????? } ??????? p_listnode = p_listnode->next; ??? } ??? ??? return p_listnode; } ? listnode find_node_by_id(list myroot, const int id) { ??? listnode p_listnode = myroot->head; ??? while(p_listnode != NULL) ??? { ??????? if( p_listnode->id == id ) ??????? { ??????????? printf("find the node for id: %d/n", id); ??????????? break; ??????? } ??????? p_listnode = p_listnode->next; ??? } ??? ??? return p_listnode; } ? |
?
3.3、附一個測試的主程序
main.c:
?
#include <stdio.h> #include <stdlib.h> #include "list.h" ? int main(int argc, char *argv[]) { ??? list mylist = malloc(sizeof(_list)); ??? list_init(mylist); ??? int ix = 0; ??? for(ix = 0; ix < 10; ix++) ??? { ??????? listnode my_listnode = new_listnode( (mylist->current_id)++, ix); ??????? list_insert(mylist, my_listnode); ??? } ??? ??? list_poll(mylist); ??? ??? //delete head node and test ??? listnode my_listnode = find_node_by_id(mylist, 1); ??? list_delete(mylist, my_listnode); ??? delete_listnode(my_listnode); ??? list_poll(mylist); ? ??? //insert a node and test ??? my_listnode = new_listnode( (mylist->current_id)++, 100); ??? list_insert(mylist, my_listnode); ??? list_poll(mylist); ? ?? ??? //delete tail node and test ??? my_listnode = find_node_by_id(mylist, 10); ??? list_delete(mylist, my_listnode); ??? delete_listnode(my_listnode); ??? list_poll(mylist); ? ??? //insert a node and test ??? my_listnode = new_listnode( (mylist->current_id)++, 200); ??? list_insert(mylist, my_listnode); ??? list_poll(mylist); ? ??? //delete a normal node and test??? ??? my_listnode = find_node_by_data(mylist, 6); ??? list_delete(mylist, my_listnode); ??? delete_listnode(my_listnode); ??? list_poll(mylist); ? ??? //insert a node and test ??? my_listnode = new_listnode( (mylist->current_id)++, 300); ??? list_insert(mylist, my_listnode); ??? list_poll(mylist); ? ??? //delete head node again and test??? ??? my_listnode = find_node_by_id(mylist, 2); ??? list_delete(mylist, my_listnode); ??? delete_listnode(my_listnode); ??? list_poll(mylist); ? ??? //insert a node and test? ??? my_listnode = new_listnode( (mylist->current_id)++, 400); ??? list_insert(mylist, my_listnode); ??? list_poll(mylist); ??? ? system("PAUSE");? ? return 0; } |
?
?