[英]Removing node from singly linked list
我需要从单链列表中删除一个节点。 我知道这很简单,但是我的想法是空白,我既搜索了Google,也搜索了Stackoverflow,但是我真的没有找到任何可以帮助我的东西。
节点列表基本上包含在存储桶中; 像这样:
struct node{
unsigned char id[20];
struct node *next;
};
struct bucket{
unsigned char id;
struct node *nodes;
};
我有一个功能
struct bucket *dht_bucketfind(unsigned char *id); // return bucket with id[20]
找到正确的桶。 因此,我知道如何找到正确的存储桶,但我不知道如何删除给定的节点。 我想通过nodeid删除节点(我想,我还没有真正编写调用remove函数的代码;),但是我认为我可以根据需要修改代码)。 我认为这就是解决此问题所需的一切。 提前致谢。
如果您知道要删除的项目,则必须做两件事:
next
成员。 这将是前一项的next
指针,或列表bucket.nodes
的头部。 一旦了解了自己在做什么,用于处理链表的代码就不会那么棘手。
您的节点除了id之外没有其他任何有效负载,因此,根据节点的数据有效负载,实际上可能不需要以标准方式迭代列表。 如果删除者仅知道他们要删除的节点的地址,这将很有用。
如果您的有效载荷是指向其他数据的指针:
struct _node {
void *data;
unsigned char id[20];
struct _node *next
}
然后,您可以通过窃取下一个节点的有效负载,然后断开下一个节点的链接来“删除”一个节点:
int delete (struct _node *node)
{
struct _node *temp;
memcpy(node->id, node->next->id, 20);
free_function(node->data);
node->data = node->next->data;
temp = node->next;
node->next = node->next->next);
free(temp);
return 0;
}
public void Remove(T data)
{
if (this.Head.Data.Equals(data))
{
this.Head = this.Head.Next;
this.Count = this.Count - 1;
}
else
{
LinkedListNode<T> node = this.Head;
bool found = false;
while (node.Next != null && !found)
{
if (node.Next.Data.Equals(data))
{
found = true;
node.Next = node.Next.Next;
this.Count = Count - 1;
}
else
{
node = node.Next;
}
}
}
}
/* define your two pointers, prev and cur */
prev=NULL;
cur=head;
/* traverse the list until you find your target */
while (cur != NULL && cur->id != search_id) {
prev=cur;
cur=cur->next;
}
/* if a result is found */
if (cur != NULL) {
/* check for the head of the list */
if (prev == NULL)
head=cur->next;
else
prev->next=cur->next;
/* release the old memory structure */
free(cur);
}
typedef struct node
{
int id;
struct node* next;
}Node;
void delete_element(void)
{
int i;
Node* current=head;
Node* brev=NULL;
if(i==head->id){
head=current->next;
free(current);}
else{
while(NULL!=current->next)
{
if(i==current->next->id){
brev=current;
current=current->next;
break;}
else
current=current->next;
}
if(i==current->id)
{
if(NULL==head->next){
head=NULL;
free(current);}
else
brev->next=current->next;
free(current);
}
else
printf("this id does not exist\n");
}
}
自从我使用C以来已经很久了,但这应该可以编译干净。
基本上,在迭代链接列表时,您需要跟踪上一个指针。 找到要删除的节点时,只需更改前一个指针即可跳过删除节点。
此函数删除所有ID为(find)的节点。 如果只想删除第一次出现的内容,则在free语句之后放一个return。
void delete(struct bucket *thisBucket, unsigned char find[20]) {
struct node *prev = null;
struct node *curr = thisBucket->nodes;
while (curr != null) {
if (!strcmp(curr->id, find)) { // found the node?
if (prev == null) { // going to delete the first node (header)?
thisBucket->nodes = curr->next; // set the new header to the second node
} else {
prev->next = curr->next;
}
free(curr);
// if deleted the first node, then current is now the new header,
// else jump to the next
curr = prev == null? thisBucket->nodes : prev->next;
} else { // not found, keep going
prev = curr;
curr = curr->next;
}
}
}
以下内容不包含任何错误检查,仅从列表中删除当前节点...
pPrev->next = pCurrent->next;
您的首选项可能会有所不同,但是我倾向于将链接列表节点放在结构的开头(如果可行)。
struct node{
struct node *next;
unsigned char id[20];
};
struct bucket{
struct node *nodes;
unsigned char id;
};
我发现这通常有助于简化指针算法,并在需要时允许进行简单的类型转换。
给定节点地址,这将删除该节点; 您可以修改它以删除具有给定ID的节点,但是您尚未指定ID的形式-它是NUL终止的字符串,还是20个字节?
// remove node from bucket and return true
// or return false if node isn't in bucket
int dht_rmnode(struct bucket* bucket, struct node* node)
{
struct node** ppnode = &bucket->nodes;
for( ;; ){
struct node* pnode = *ppnode;
if( pnode == NULL ) return 0;
if( pnode == node ){
*ppnode = pnode->next;
return 1;
}
ppnode = &pnode->next;
}
}
或者,更紧凑地说,
// remove node from bucket and return true
// or return false if node isn't in bucket
int dht_rmnode(struct bucket* bucket, struct node* node)
{
struct node** ppnode = &bucket->nodes;
struct node* pnode;
for( ; (pnode = *ppnode); ppnode = &pnode->next )
if( pnode == node ){
*ppnode = pnode->next;
return 1;
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.