c中的指针:函数,删除链表中的每一个元素
我想写一个函数,它获取一个指向链表头的指针,并每隔一秒从链表中删除一个成员。该列表是一个链接元素,类型为元素: 我对所有这些指针算法都是新手,所以我不确定我写的是否正确:c中的指针:函数,删除链表中的每一个元素,c,pointers,linked-list,C,Pointers,Linked List,我想写一个函数,它获取一个指向链表头的指针,并每隔一秒从链表中删除一个成员。该列表是一个链接元素,类型为元素: 我对所有这些指针算法都是新手,所以我不确定我写的是否正确: void deletdscnds(element* head) { element* curr; head=head->next; //Skipping the dummy head// while (head!=NULL) { if (head->next==NULL)
void deletdscnds(element* head) {
element* curr;
head=head->next; //Skipping the dummy head//
while (head!=NULL) {
if (head->next==NULL)
return;
else {
curr=head;
head=head->next->next; //worst case I'll reach NULL and not a next of a null//
curr->next=head;
}
}
}
我不断地修改它,因为我不断地发现错误。您能指出任何可能的错误吗?如果您从节点对的角度考虑链表,算法会简单得多。循环的每次迭代都应处理两个节点-
head
和head->next
,并在退出时使head
等于head->next->next
。同样重要的是,如果要从列表中删除中间节点,不要忘记删除它,否则会出现内存泄漏
while (head && head->next) {
// Store a pointer to the item we're about to cut out
element *tmp = head->next;
// Skip the item we're cutting out
head->next = head->next->next;
// Prepare the head for the next iteration
head = head->next;
// Free the item that's no longer in the list
free(tmp);
}
用递归的术语来形象化这个问题可能是最直接的,比如:
// outside code calls this function; the other functions are considered private
void deletdscnds(element* head) {
delete_odd(head);
}
// for odd-numbered nodes; this won't delete the current node
void delete_odd(element* node) {
if (node == NULL)
return; // stop at the end of the list
// point this node to the node two after, if such a node exists
node->next = delete_even(node->next);
}
// for even-numbered nodes; this WILL delete the current node
void delete_even(element* node) {
if (node == NULL)
return NULL; // stop at the end of the list
// get the next node before you free the current one, so you avoid
// accessing memory that has already been freed
element* next = node->next;
// free the current node, that it's not needed anymore
free(node);
// repeat the process beginning with the next node
delete_odd(next);
// since the current node is now deleted, the previous node needs
// to know what the next node is so it can link up with it
return next;
}
至少对我来说,这有助于澄清每一步需要做什么
我不建议实际使用这种方法,因为在C语言中,递归算法可能会占用大量RAM,并导致编译器无法优化堆栈溢出。相反,dasblinkenlight的答案包含了您应该实际使用的代码。Yikes!在你这样做一段时间后,你将站在膝盖深的泄漏记忆!您没有删除任何内容…您刚刚丢失了它。我应该在释放它之前使用“free”功能吗?您必须在删除curr之前获取curr->next的值。
// outside code calls this function; the other functions are considered private
void deletdscnds(element* head) {
delete_odd(head);
}
// for odd-numbered nodes; this won't delete the current node
void delete_odd(element* node) {
if (node == NULL)
return; // stop at the end of the list
// point this node to the node two after, if such a node exists
node->next = delete_even(node->next);
}
// for even-numbered nodes; this WILL delete the current node
void delete_even(element* node) {
if (node == NULL)
return NULL; // stop at the end of the list
// get the next node before you free the current one, so you avoid
// accessing memory that has already been freed
element* next = node->next;
// free the current node, that it's not needed anymore
free(node);
// repeat the process beginning with the next node
delete_odd(next);
// since the current node is now deleted, the previous node needs
// to know what the next node is so it can link up with it
return next;
}