您的位置:首页 > 编程语言 > C语言/C++

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

2017-11-23 18:46 399 查看
#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;
}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息