穷究链表(七)

这篇会实现3个函数,包括删除一个节点,查找节点,以及合并两个链表。
删除一个节点:
还是对5种情况来进行画图分析
1. 空表,这种情况下直接返回即可
2. 链表只有一个节点的情况,则删除这个节点
3. 链表有两个或多个节点,删除尾巴上面的节点
4. 链表有两个或多个节点,删除中间的节点
5. 链表有两个或多个节点,删除第一个节点
通过分析,发现25所需做的处理相同,34所需做的处理相同,1直接返回即可,无需进行删除工作。
当删除时,我们就另外还需要一个辅助节点,用来定位在删除之后的,(pos+1)位置的节点。
当我们要删除某个节点时,指定位置为pos,我们需要删除位置为pos的节点,我们就需要定位到位置(pos-1),然后再进行下面的动作。

最后实现: 

片段1

完整的测试代码为:

片段2


然后是findNode的实现。
findNode功能是寻找特定节点,基本原理也是和遍历差不多,只是当定位到需要的节点时,将节点的指针返回,如果定位不到,则返回一个空(NULL)。
一开始实现的时候,考虑没考虑好,实现出现了问题。
问题代码

 1listnode* findNode(linkedlist llist, int pos)
 2{
 3    listnode *tmp=llist;
 4    int cnt=0;
 5    while(cnt<pos && tmp)
 6    {
 7        tmp = tmp->next;
 8        cnt++;
 9    }

10    return tmp;
11}

12

修改之后的代码为

 1listnode* findNode(linkedlist llist, int pos)
 2{
 3    listnode *tmp=llist;
 4    int cnt=0;
 5    while(cnt<pos && tmp->next)
 6    {
 7    tmp = tmp->next;
 8    cnt++;
 9    }

10    return tmp;
11}

12

大家可以考虑一下为什么。

下面是mergelist的实现。
      mergelist的功能是要将两个链表合成为一个,但是合成的规则不同,合成可以是有序的链表,也可以是两个链表就是单独的连接起来。
      当然,只是连接起来就很容易实现了。这里为了偷懒,就只实现了这个。
      
对于空表和非空表的情况,要进行一下判断。

片段5

      其实,这里还有一个问题,这还是之后使用C++的时候暴露出来的,可以算是bug,也可以不算,就是根据具体的需求和实现而不同,不算的我们可以称其为feature。:)
      在两个链表merge之后,llist2就被归并到llist中,这样在之后,删除链表llist之后,其实llist2中的节点也就被清空了,而此时llist2就成为野指针了。所以最好是将llist2处理一下。

还有一个反转链表,会专门开一篇来写。

posted on 2009-10-08 21:38  cnyao  阅读(390)  评论(1编辑  收藏  举报