大家好,我知道要删除链接列表中有多个元素的节点,请从当前节点中删除要删除的前一个节点,并将其指向current->next
,然后{{ 1}}当前节点。
但是我的问题是,当我在一个链表中只有一个元素时,当我尝试删除该节点时,似乎出现了分段错误(核心转储),我认为这是因为在这种情况下,{{1 }}指向free()
(我在这里可能是错误的)。还可以说我有一个存储值为5的节点,我遇到的一个常见问题是不是删除该节点,而是将其值更改为0。
问题: 我没有要求任何人修复我的代码,这就是为什么我决定不发布代码,但是我的问题是,当该节点是链表中的唯一元素时,我将如何处理该节点?与删除多个元素时,如何删除链表中只有一个元素的节点不同。
非常感谢您的帮助,如果事情不清楚,我们深表歉意,但是我真的想在提出问题之前先给出具体背景。
答案 0 :(得分:0)
在链表中,可以用不同的方法删除节点。
算法:
Step1: temp = head
Step2: temp = temp->next
Step3: free(temp)
Step4: head = NULL
算法
Step1: p = head
Step2: while p->next->next != NULL
p = p->next
Step3: temp = p->next
Step4: p->next = NULL
Step5: free(temp)
算法:
Step1: p = head
Step2: while POSITION > 2 #Indexing from 1
p = p->next
POSITION = POSITION - 1
Step3: temp = p->next
Step4: p->next = p->next->next
Step5: free(temp)
答案 1 :(得分:0)
您的“链接列表”只是列表中第一个元素的指针。
MyStruct *my_list;
因此,如果my_list-> next为null,则意味着列表中只有一个元素。 如果要删除他,这很简单:
free(my_list)
my_list = NULL;
您的列表现在为空(请勿尝试阅读此内容;))
答案 2 :(得分:0)
从列表中删除元素时,有两种特殊情况需要担心:第一个元素和最后一个元素,有时它们是同一元素。
两者都可以这样处理:
typedef struct node {
int val;
struct node *next;
} node;
void deleteNode(node **head, int value) {
node *prev = NULL, *curr = *head;
// look for the node to delete
while (curr && curr->value != value) {
prev = curr;
curr = curr->next;
}
if (curr == NULL) {
printf("node to delete not found\n");
} else if (prev == NULL) {
// need to delete the first node, so repoint head to next node
*head = (*head)->next;
} else {
// deleting an internal node, so have the previous point to the current's next
prev->next = curr->next;
}
// no need to check for the last node
// since we're copying next which may or may not be NULL
free(curr);
}
答案 3 :(得分:0)
这完全取决于您对链表的实现。
一些可能的实现方式。
根据列表的结构,实现可能会有所不同。
一般来说,您可以从指针H
开始,该指针指向元素E
,并且该元素具有指向后继{{1}的指针next
}。
您正确的将S
设置为H
的内容。由于next
和H
必须有效,因此不会出现分段错误。
以最简单的形式(未经检查/未经编译的代码-应该只显示原理):
E
考虑以下列表。
typedef struct ListNode{
void* data,
struct ListNode* next;
}ListNode;
/**
* \brief removes an element from the linked list
*
* \param io_el the 'next' pointer of the previous
* element or the pointer to the head
* \return the pointer to the removed element
*
* \details
* uses the io_el pointer to advance to the next list element and
* sets the io_el pointer to the content of the next pointer of
* this element. This effectivly removes the element from the chain.
* The removed element is returned so that it may be free'd if necessary.
*/
Node* ListDeleteElement(Node** io_el){
Node* res = NULL;
if( io_el && *io_el){
res = *io_el;
*io_el = (*io_el)->next;
}
}
此实现有点危险-传递的指针绝对是指向列表实际元素的head指针或指向Node E1 ,E2,E3;
Node* H = &E1;
E1.next = &E2;
E2.next = &E3;
E3.next = NULL;
// (H = ) E1 -> E2 -> E3 -> NULL
// remove E3;
ListDeleteElement( &(H->next->next) ); // passes pointer to the nextpointer of E2,
// E2.next should be NULL now
// (H = ) E1 -> E2 -> NULL
// remove E1
ListDeleteElement( &H );
// *H should now be E2
// (H = ) E2 -> NULL
// again remove first element
ListDeleteElement( &H );
// (H = ) NULL
指针的指针。
将任意指针的地址传递到列表结构中会损坏列表。
因此,该代码应用作内部帮助程序函数,该函数由一些更高级的函数包装,或者应在较小的本地列表中使用,因为它们不会传递给其他程序部分。在这种情况下,我将设计一个更强大的列表类。
答案 4 :(得分:0)
删除不是第一个节点的节点时,步骤是
1)previous_node->next = node_to_delete->next;
2)free(node_to_delete)
当删除为的第一个节点时,您跳过步骤1 ,因为没有previous_node。相反,您必须像这样更新列表的开头:
3)head = node_to_delete->next;
这可以通过多种方式实现。例如:
node* delete(node* head, int n)
{
node* prev = NULL;
node* temp = head;
while (temp)
{
if (temp->value == n)
{
if (prev)
{
// All except first node
prev->next = temp->next;
}
else
{
// First node
head = temp->next;
}
free(temp);
return head;
}
prev = temp;
temp = temp->next;
}
return head;
}
并这样称呼它:
head = delete(head, 42);
答案 5 :(得分:0)
1:如果元素是头部。
nodeptr deleteBeginning(nodeptr head){
nodeptr current = head;
head= head->next;
free(current);
return head;
}
2:对于其余元素。
nodeptr deleteNode(nodeptr head, int value){
if(value == head->data) {
head = deleteBeginning(head);
return head;
}
nodeptr current = head;
nodeptr previous;
while(current->data != value){
previous = current;
current = current->next;
}
previous->next = current->next;
free(current);
return head;
}
nodeptr只是结构Node *的typedef