从链表列表中删除节点?

时间:2012-10-09 05:26:32

标签: c linked-list hashtable

我正在将哈希表写为链表的数组。目前我正在尝试使用一个简单的哈希表,其中键是数组的索引,值是用于实现链接的单链表。

这是我删除节点的代码:

基本结构:

struct Node
{
 int value;
 int page;   
 struct Node *next; 
};

int searchAndDelete(int frame,int page,int delete)
{
   struct Node** iter;
   iter=&hashtable[(page-1)%7];
   struct Node** prev=iter;

   for(;*iter;iter=&(*iter)->next)
   {
      if(page==((*iter)->page))
      {
         if(frame==((*iter)->value))
         {
            if(delete)
            {
               (*prev)->next=(*iter)->next;
               free(*iter);
            }
            return 1;
         }
      }
      prev=iter;
   }
   return 0;
}

如需插入,请点击此处AddNode

当我删除某个节点时,其值变为0.当我搜索该节点时,它会返回该节点未预设为0,作为该函数的输出。

我的代码中是否有任何我没有想过的错误?我是否留下任何内存泄漏或任何其他问题?

修改 将这段代码添加到删除功能:

  int searchAndDelete(int frame,int page,int delete)
  {
   struct Node** iter;
   iter=&hashtable[(page-1)%7];
   struct Node** prev=iter;
   struct Node** curr=iter;

   for(;*curr;curr=&(*curr)->next)
   {

     if(page==((*curr)->page))
     {
        if(frame==((*curr)->value))
        {
            if(delete)
            {
                if(curr==iter)
                {

                    iter=(*curr)->next;
                    free(*curr);

                }
                else
                {

                (*prev)->next=(*curr)->next;
                free(*curr);
                }

            }

            return 1;
        }

    }
    prev=curr;

  }
    return 0;



}

问题我看到的是,当我第一次删除时,元素没有被释放,它的值被设置为0,但它仍然在链表中说。在第二次删除时,最后一个元素的值转到某些垃圾,因此在我的比较检查中永远不会删除该元素。有人可以说明我在这里可能做的事情吗?

2 个答案:

答案 0 :(得分:2)

如果你正在使用的哈希表是七个元素宽(即索引为0..6),并且从你的AddNode代码中看起来是,那么你正在使用的算法怀疑初始迭代器查找

iter=&hashtable[page-1%7];

应该是:

struct Node** iter = hashtable + (page % 7);

这将为您提供页面位置模数7的哈希表中元素的地址,即[0..6]。

此外,从哈希表头节点删除不会考虑清除表元素本身。您可能需要(a)将其设置为null,或者(b)在下一个ptr中链接。也这样做。您有能力,因为哈希表和初始节点指针都可用。

编辑:OP要求提供样品。这只是一个如何做到这一点的快速记录。我确信有很多更好的方法,甚至可以编译。这假设页面AND帧必须完全匹配才能将节点视为可删除。

void searchAndDelete(int frame, int page, int del)
{
    struct Node** head = hashtable + (page % hashtable_size);
    struct Node* curr = *head;
    struct Node* prev = NULL;

    while (curr)
    {
        // if they match, setup for delete.
        if ((curr->page == page) && (curr->value == frame) && del)
        {
            // so long as the header pointer is the active node prev
            //  will be NULL. move head along if this is the case
            if (prev == NULL)
                *head = curr->next;

            // otherwise, the previous pointer needs it next set to
            //  reference the next of our vicitm node (curr)
            else
                prev->next = curr->next;

            // victim is safe to delete now.
            free(curr);

            // set to the new head node if we just deleted the
            //  old one, otherwise the one following prev.
            curr = (prev == NULL) ? *head : prev->next;
        }
        else
        {   // no match. remember prev from here on out.
            prev = curr;
            curr = curr->next;
        }
    }
}

呃,足够接近= P

答案 1 :(得分:1)

我看到了几个问题:

  1. mod operator %需要括号。因此,请将iter=&hashtable[page-1%7];更改为iter=&hashtable[(page-1)%7];

  2. 当您删除链接列表中的第一个元素时处理该案例。在这种情况下,prev将与iter相同,因此(*prev)->next=(*iter)->next;不会有任何不同。您需要更新数组以存储下一个元素aka (*iter)->next