思路:
1. 找到该结点,并返回
2. 找到该结点的前一个结点
3. 通过参数NODE **pre(结点的指针的指针,即用来存放结点地址的指针)将待删除结点的前一个结点的指针域修改为待修改结点的下一个结点,即存储该结点的地址。
4.删除成功!
链表端的功能实现:
步骤1:查找待删除结点,并通过参数修改前一个结点的指针域指向
- NODE * FindNode(LIST *l,void *key,int (*compare)(void *,void *),NODE **pre) //函数指针
- {
- NODE *p=NULL;
- if(l==NULL||key==NULL||compare==NULL||pre==NULL)
- return NULL;
- p=l->head;
- *pre=NULL;
- while(p)
- {
- if(compare(p->data,key)==1)
- return p;
- *pre=p;
- p=p->next;
- }
- return NULL;
- }
步骤2:删除结点
- int DeleteListByKey(LIST *l,void *key,int (*compare)(void *,void *))
- {
- NODE *p=NULL,*q=NULL;
- 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;
- free(p->data);
- free(p);
- l->length--;
- return 1;
- }
应用层的调用:
首先定义根据什么条件删除以及要删除的元素。
- 定义删除条件
- --------------------------------------
- int CompareBySno(void *info,void *key)
- {
- struct STU *stu=(struct STU *)info;
- char *sno=(char *)key;
- return strcmp(stu->sno,sno)==0 ? 1:0;
- }
客户端的调用:
- void main()
- {
- int i;
- NODE *res=NULL; //定义临时的指针来存放返回的结果
- char name[]="wang wu",sno[]="S101";
- LIST *list=InitList();
- for(i=0;i<3;i++)
- InsertList(list,&s[i],sizeof(s[i]));
-
-
- res=FindNodeByKey(list,name,CompareByName); //函数名称就代表了这个函数的首地址
- if(res==NULL) //函数参数传递错误或者是没找到
- printf("Not Find!\n");
- else
- printf("Find!\n");
- if(DeleteListByKey(list,sno,CompareBySno))
- printf("delete success!\n");
- else
- printf("delete fail!\n");
-
- }
分析:(查看内存方式)
删除前:
删除后:
观察头指针和尾指针所指向的结点即可发现指定结点已经被删除掉了。
阅读(7541) | 评论(1) | 转发(0) |