69,369
社区成员
发帖
与我相关
我的任务
分享
#ifndef _LIST_H
#define _LIST_H
typedef struct _node{
void * data;
struct _node *next;
}NODE;
typedef struct{
NODE *head;
NODE *last;
int length;
}LIST;
LIST * initList();
int insertList(LIST *l,void *data,int size);
NODE * findNodeByKey(LIST *l,void *key,int (*compare)(void *,void *));
NODE * findNode(LIST *l,void *key,int (*compare)(void *,void *),NODE **pre);
int deleteList(LIST *l,void *key,int (*compare)(void *,void *));
#endif
#include"list.h"
#include<stdio.h>
NODE * findNode(LIST *l,void *key,int (*compare)(void *,void *),NODE **pre){
NODE *p = NULL;
int s = 0;
if(l == NULL || key == NULL || compare == NULL || pre == NULL){
return NULL;
}
p=l->head;
pre = NULL;
while(p){
if(compare(p->data,key) == 1){
printf("findNode-->find!");
return p;
}
//报错
*pre = p;
p = p->next;
}
return NULL;
}
int deleteList(LIST *l,void *key,int (*compare)(void *,void *)){
NODE *q=NULL,*p=NULL;
/*这是一个很巧妙的编码方式
1.p指向findNode的返回值,也就是查找到的目标节点
2.q指向目标节点的前一个节点,是一个指向指针的指针
3.通过对p的非空判断可以知道是否存在目标节点
4.通过对q的非空判断可以知道目标节点是否是第一个节点
这是一个很灵活的编码方式!
*/
p = findNode(l,key,compare,&q);
if(p == NULL){
//说明目标节点在链表中不存在
return 0;
}
if(q == NULL){
//说明目标节点是第一个节点,前面就是头结点
l->head = p->next;
}else{
//目标节点不是第一个节点,把指针越过删除的节点
q->next = p->next;
}
//如果目标节点是最后一个节点呢
if(p == l->last){
l->last = q;
}
//先释放p的数据域,再释放p
free(p->data);
free(p);
l->length --;
return 1;
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"list.h"
struct STU{
char sno[5];
char sname[10];
int age;
int scroe;
}stu[3]={
{"100","avin",12,299},
{"101","tgip",52,239},
{"102","inca",23,439},
};
//专门比较姓名的函数
int compareByName(void *info,void *key){
//强制类型转换
struct STU *stu = (struct STU *)info;
char *name = (char *)key;
return strcmp(stu->sname,name) == 0 ? 1 : 0;
}
//专门比较学号的函数
int compareBySno(void *info,void *key){
//强制类型转换
struct STU *stu = (struct STU *)info;
char *no = (char *)key;
return strcmp(stu->sno,no) == 0 ? 1 : 0;
}
void main(){
NODE *res = NULL;//查找时候的返回结果
char name[] = "inca";
char no[]="101";
LIST *list = initList();
int i=0;
for(;i<3;i++){
insertList(list,&stu[i],sizeof(stu[i]));
}
res = findNodeByKey(list,name,compareByName);//注意,这里compareByName的名字就代表该函数的地址
if(res == NULL){
printf("not found!\n");
}else{
//强制类型转换
struct STU *st = (struct STU *)res->data;
printf("found! %d\n",st->scroe );
}
/*注意这里的compareBySno
如果携程compareBySno()就表示是方法调用,将会以该方法的返回值传递进入deleteList中。
compareBySno表示将该函数的地址传递进去。
*/
//这里开始删除函数的调用
if(deleteList(list,no,compareBySno) == 1){
printf("delete Success!\n");
}else{
printf("delete failed!\n");
}
}