如何理解二级指针删除单向链表

  利用二级指针删除单向链表的代码如下:
 
   1 void remove_if(node ** head, remove_fn rm)
 
   2 {
 
   3 for (node** curr = head; *curr; )
 
   4 {
 
   5 node * entry = *curr;
 
   6 if (rm(entry))
 
   7 {
 
   8 *curr = entry->next;
 
   9 free(entry);
 
   10 }
 
   11 else
 
   12 curr = &entry->next;
 
   13 }
 
   14 }
 
   顺便看了这篇文章的评论,每个人都提出了自己对这段代码的理解,但我还是觉得没有说到点上。如不嫌弃,不妨试试跟我的思路来理解一下:
 
   首先,我们做这样两个假设:
 
   1. 操作系统为链表分配内存的时候,链表中的各项恰好是紧挨着的;
 
   2. 除非链表被完全删除,否则,链表中的各项所在的内存不会被占用,我们仍然可以安全的访问到它们;
 
   那么上面的代码等价于这样:
 
   void remove_if(node **arr, remove_fn rm)
 
   {
 
   node **curr = arr;
 
   for (int i = 0; i < 10; i++)
 
   {
 
   node *entry = cur[i];
 
   if (entry == NULL)
 
   {
 
   continue
 
   }
 
   if (rm(entry))
 
   {
 
   free(entry);
 
   entry = NULL;
 
   }
 
   }}
 
   大致解释一下上面的实现:由于假设1,访问链表中的下一个元素可以不再通过next指针,而是“表头+偏移量”的方式,由于假设2,我们总是能安全的访问已删除表项的内存。
 
   通过上面的例子,利用二级指针删除单向链表的节点就很好理解了:其实就是从一个指针数组中删除指定的项目,只不过,这个数组是匿名的,引入的二级指针正好充当了这个数组的名称;另外,这个数组在内存中并不是连续的,所以我们在每个节点处需要维护一个指向下一个数组项的next指针。当这个指针是NULL的时候,表示这是数组的最后一项了,我们可以改变这个NULL为非NULL,这是后就是添加了一个新的链表节点,然后重新设置数组的长度,也就是把新的节点的next域设置为NULL托福答案 www.tfjy386.com 
 
 

posted on 2014-03-04 10:21  程序点滴  阅读(373)  评论(0编辑  收藏  举报

全讯网   全讯网