简单的链表存储和搜索例子(完整的增删查改)

#include "stdio.h" #include "stdlib.h" #include "string.h"//链表结点 typedef struct Item ListItem; struct Item { char *epc, *name; ListItem *next; }; ListItem* creatList(); ListItem* createItem(char* epc, char* name); int insert(ListItem *listHead, ListItem *newItem); void removeAll(ListItem *listHead); int removeItem(ListItem *listHead, ListItem *item); int search(ListItem *list, char tools[], void (*callback)(ListItem *list, ListItem *item)); void readList(ListItem *list); //搜索到之后的回调事件实现: void callbackForSearch(ListItem *list, ListItem *item) { printf("找到了epc为%s的name:%s\n", item->epc, item->name); }//搜索到对应条目就干掉的回调实现 void callbackForDel(ListItem *list, ListItem *item) { removeItem(list, item); }//搜索并修改的回调实现 void callbackForModify(ListItem *list, ListItem *item) { printf("找到了epc为%s的name:%s,需要修改为:\n", item->epc, item->name); { int choice = 0; printf("1为修改该条目的epc,0为修改该条目的name:"); scanf("%d", &choice); if(choice == 1) { printf("请输入对应该name的新epc:"); free(item->epc); scanf("%s",item->epc); printf("修改完毕\n"); }else if(choice == 0) { printf("请输入对应该epc的新name:"); free(item->name); scanf("%s",item->name); printf("修改完毕\n"); }else { printf("功能选择错误\n"); } } }int main() { int i; //创建链表 ListItem *list = creatList(); //创造一些例子数据,你按着步骤加结点就可以了 for(i=0; i<9; i++) { //这里只是用来方便我做循环,你可以直接对字符指针赋值的 char *epc = (char*)malloc(sizeof(char) * 3); char *name = (char*)malloc(sizeof(char) * 3); epc[0] = '0' + i; epc[1] = '1' + i; epc[2] = '\0'; name[0] = 't'; name[1] = 'o'; name[2] = '0' + i; name[3] = '1' + i; name[4] = '\0'; insert(list, createItem(epc, name)); } printf("\n全部读取一次:\n"); readList(list); printf("\n修改条目\n"); search(list, "56", callbackForModify); printf("\n全部再读取一次:\n"); readList(list); printf("\n读取对应条目:\n"); search(list, "2301568710100101", callbackForSearch); printf("\n删除对应条目:\n"); search(list, "2301568710100101", callbackForDel); printf("\n全部再读取一次:\n"); readList(list); printf("\n删除全部:\n"); removeAll(list); return 0; }//建表函数 //返回 表头地址 ListItem* creatList() { ListItem *head; head = (ListItem*)malloc(sizeof(ListItem)); head->epc = NULL; head->name = NULL; head->next = NULL; return head; }//创建内存空间存放条目的函数 //返回 条目在内存里面的地址 ListItem* createItem(char* epc, char* name) { ListItem* item = (ListItem*)malloc(sizeof(ListItem)); //记得创建完结点之后要设置next为空,否则影响insert函数算法的运作 item->epc = epc; item->name = name; item->next = NULL; return item; }//插入条目到指定表中函数 int insert(ListItem *listHead, ListItem *newItem) { //利用static int做第一次读表判断 static int firstIn = 1; ListItem *temp = listHead; if(temp == NULL) return -1; while(temp->next != NULL) temp = temp->next; //如果表被清空了就重新设置为第一次进入 if(temp->epc == NULL && temp->name == NULL && temp->next == NULL && temp == listHead) firstIn = 1; //如果是表头而且第一次读,就直接读结点赋值 if(temp == listHead && firstIn) { //赋值newItem的内容地址进已经有内存空间但没内容的表头结点,免得浪费该结点 temp->epc = newItem->epc; temp->name = newItem->name; //对firstIn取反,下一次就不会进入这个分支(static变量声明周期和程序周期相同,要记得函数执行完毕firstIn值还保留的) firstIn = !firstIn; //newItem利用完了,销毁掉 free(newItem); } //不是表头就添加进表未的下一个的位置 else temp->next = newItem; //师弟你要记住这里不能继续free掉newItem。因为上面的那个分支是结点已经保存好了newItem结构体地址里面的内容的地址 //但这里是newItem的地址赋值给temp的下一个指针,你一旦free掉,那么想读这个内存地址的数据的时候,数据杰不存在了 //会产生非法访问内存错误,所以这里不能free也没必要free } //遍历并读出整个表的函数 void readList(ListItem *list) { if(list == NULL) return ; printf("结点数据epc: %s,name:%s\n", list->epc, list->name); readList(list->next); }//清空整个表,包括表头,请重新使用createList来得到一个新表,使用原表头指针保存的内存地址将引发内存访问权限错误 void removeAll(ListItem *listHead) { if(listHead == NULL) return; ListItem *next = listHead->next; printf("预备删除节点的内存地址: address:%d\n", listHead); free(listHead->epc); free(listHead->name); //memset(listHead, NULL, sizeof(ListItem)); //将这块内存填0 free(listHead); removeAll(next); }//按内存地址删除某一个条目 int removeItem(ListItem *listHead, ListItem *item) { ListItem *before = listHead, *cursor = listHead; printf("将要删除的结点数据epc: %s,name:%s\n", item->epc, item->name); //如果是头结点 if(listHead == item) { //复制第二个节点的数据到第一个节点,并且free掉第二个结点,一三节点相连 ListItem *copySecNext = item->next->next; free(item->epc); free(item->name); item->epc = item->next->epc; item->name = item->next->name; free(item->next); item->next = copySecNext; return ; } //其他结点: while(cursor != NULL) { if(cursor == item) { before->next = item->next; free(item); break; } before = cursor; cursor = cursor->next; } }//搜索对应epc的条目 int search(ListItem *list, char tools[], void (*callback)(ListItem *list, ListItem *item)) { ListItem *temp = list; int i, j, toolsLength = strlen(tools); printf("\n你想搜索的epc组合为(两个字节为一个搜索项):%s\ntools数组长度%d\n", tools, toolsLength); while(temp->next != NULL) { for(i=0,j=1; i < toolsLength,j < toolsLength; i+=2,j+=2) { if(temp->epc[0] == tools[i] && temp->epc[1] == tools[j]) { callback(list, temp); } } temp = temp->next; } return 0; }



简单的链表存储和搜索例子(完整的增删查改)
文章图片




【简单的链表存储和搜索例子(完整的增删查改)】简单的链表存储和搜索例子(完整的增删查改)
文章图片


    推荐阅读