我正在将哈希表写为链表的数组。目前我正在尝试使用一个简单的哈希表,其中键是数组的索引,值是用于实现链接的单链表。
这是我删除节点的代码:
基本结构:
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,但它仍然在链表中说。在第二次删除时,最后一个元素的值转到某些垃圾,因此在我的比较检查中永远不会删除该元素。有人可以说明我在这里可能做的事情吗?
答案 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)
我看到了几个问题:
mod operator %
需要括号。因此,请将iter=&hashtable[page-1%7];
更改为iter=&hashtable[(page-1)%7];
当您删除链接列表中的第一个元素时处理该案例。在这种情况下,prev
将与iter
相同,因此(*prev)->next=(*iter)->next;
不会有任何不同。您需要更新数组以存储下一个元素aka (*iter)->next
。