从链表a中找出与链表b相同的值并删除!

来源:互联网 发布:个人网络直播怎么赚钱 编辑:程序博客网 时间:2024/05/23 11:49

    算法:其实这和直接删除a链表中的某个节点类似,只是现在不是在删除一个节点,而是要与b链表先进行比较后再进行删除。首先先选取a中的第一个节点,从b中第一个开始找,找不到的话b就继续后移,b移到结尾还是未找到就说明b中任何一个没有与a中第一个节点相同,则a向后移动,以此类推。当有找到相同的节点时,情况1.此时a链表指向头结点,则只需要让头结点指向下一结点。情况2.不是头结点时只需要让a的前一个节点(pa2)的next指向pa1的next即可。情况3.如果是表尾,这个情况要考虑仔细了,假设现在b中找到了一个元素是与a中的最后一个节点相同,这时a中的指针情况应该是pa2指向倒数第二个节点(它始终是pa1的前驱,记录前一个走过的节点),而pa1指向末尾节点,则按照情况2的思路,有如下操作:pa2->next=pa1->next;而此时pa1->next为NULL(它是末尾么),所以还是满足情况2的,因此2,3情况可以合并,但是要注意循环的条件是while(pa1!=null),即pa1可以指向最后一个节点,但pa2不能指向最后一个节点,因为这时pa2的后继pa1就指向了下一个空节点了。

#include <stdio.h>#include <string.h>#define LA 5#define LB 4struct student {int num;char name[10];struct student *next;}a[LA],b[LB];void main(){struct student a[LA]={{101,"zhang"},{102,"li"},{103,"wang"},{104,"niu"},{105,"liu"}};struct student b[LB]={{103,"zhu"},{105,"huang"},{106,"zhao"},{107,"qian"}};struct student *heada,*headb,*pa1,*pa2,*pb1;int i;    heada=a;//指向a链表headb=b;//指向b链表//对链表a赋地址并且输出printf("a链表:\n");for (pa1=heada,i=1;i<=LA;i++){  if(i<LA)  pa1->next=a+i;elsepa1->next=NULL;printf("%4d%8s\n",pa1->num,pa1->name);if(i<LA)pa1=pa1->next;}//对链表b赋地址并且输出    printf("b链表:\n");for (pb1=headb,i=1;i<=LB;i++){if(i==LB)pb1->next=NULL;else pb1->next=b+i;printf("%4d%8s\n",pb1->num,pb1->name);if(i<LB)pb1=pb1->next;}//从a中找出与b相同的节点并且删除pa1=heada;//初始化指针while (pa1!=NULL)//只要链表a没有到结尾就执行{   pb1=headb;while((pa1->num != pb1->num) && (pb1->next!=NULL))//没有找到相等的值且b表没有到结尾{pb1=pb1->next;}//b表向后移动if (pa1->num==pb1->num)//找到了{if(pa1==heada)heada=pa1->next;//头结点直接指向下一结点else{pa2->next=pa1->next;//乍一看觉得pa2没有指向,但能进入这个else说明绝对有一次没有找到过,pa1=pa1->next;      //即pa1向后移动过,所以pa2是有所指的}}else{pa2=pa1;         pa1=pa1->next;} }    //输出新表printf("现在a链表如下:\n");pa1=heada;while(pa1!=NULL){printf("%4d%8s\n",pa1->num,pa1->name);pa1=pa1->next;}}