Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是否从链表数组中删除节点?_C_Linked List_Hashtable - Fatal编程技术网

C 是否从链表数组中删除节点?

C 是否从链表数组中删除节点?,c,linked-list,hashtable,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)

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

这是我删除节点的代码:

基本结构:

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;
}
插入请看这里

删除节点时,该节点的值将更改为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,但它仍然在链表中显示。在第二次删除中,最后一个元素的值会变成一些垃圾,因此在比较检查中该元素永远不会被删除。有人能告诉我在这里可能做什么吗?

我发现了几个问题:

  • mod运算符
    %
    需要括号。所以改变
    iter=&hashtable[page-1%7]
    iter=&hashtable[(第1页)%7]

  • 处理删除链表中第一个元素的情况。在这种情况下,
    prev
    将与
    iter
    so
    (*prev)->next=(*iter)->next相同不会产生任何不同。您需要更新数组以存储下一个元素aka
    (*iter)->next


  • 如果您使用的哈希表有七个元素宽(即索引为0..6),并且从AddNode代码来看,它似乎是,那么您使用的算法对于初始迭代器查找是可疑的

    iter=&hashtable[page-1%7];
    
    可能是:

    struct Node** iter = hashtable + (page % 7);
    
    这将在页面位置7给出哈希表中元素的地址,即[0..6]

    此外,从哈希表头节点进行的删除不会清除表元素本身。您可能需要(a)将其设置为null,或(b)在下一个ptr中设置为chain。也要这样做。由于哈希表和初始节点指针都可用,因此您可以使用

    编辑:OP要求提供样品。这只是如何做到这一点的简要说明。我相信有很多更好的方法,甚至可能是编译的方法。这假设页面和框架必须完全匹配,节点才能被视为可删除

    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;
            }
        }
    }
    

    eh,足够接近=p

    OT,如果您有机会通过C++编译器推它,“DELATE”是一个保留字,因此SeaRangeDeleTe()的第三个参数可能需要不同的名称。与您的问题无关,但可能会在以后为您节省大量时间。是否必须考虑清除表,删除整个链接列表是否足够?是的,这是必要的。哈希表应由最初为空的节点指针组成。每个页面的第一个应该从它所属的哈希表槽中的页面列表开始。每个(包括头部)都是动态分配的,因此也需要同样地释放。如果你需要一个简单的例子,我会在答案中加入一个。请这样做,我会很感激这个例子并在我的编辑中加上注释。@gizgok没问题,正如我所说的,顺便说一句,请仔细检查计算哈希表槽的模。希望代码有帮助。(累了,如果不是星光灿烂的话,那就太累了)。