C 为什么删除节点中的位置0不起作用?

C 为什么删除节点中的位置0不起作用?,c,linked-list,C,Linked List,我是c编程新手。我想从给定的文件中创建一个链表,然后从链表中随机获取一个节点,然后删除该节点。 因此,代码工作得很好,但对于链表中的位置0不起作用。 请帮帮我 代码如下: typedef struct node{ int *name; struct node *next; }node; 删除节点: void deleteNode(node **head_ref, int position){ if(*head_ref == NULL){ return; } node * temp =

我是c编程新手。我想从给定的文件中创建一个链表,然后从链表中随机获取一个节点,然后删除该节点。 因此,代码工作得很好,但对于链表中的位置0不起作用。 请帮帮我 代码如下:

typedef struct node{
int *name;
struct node *next;
}node;
删除节点:

void deleteNode(node **head_ref, int position){
if(*head_ref == NULL){
    return;
}
node * temp = *head_ref;
if(position == 0)
{
    *head_ref = (*head_ref)->next;
    return;
}
int h;
for(h=0 ; temp!=NULL && h<position-1 ; h++){
    temp = temp->next;
}
if(temp == NULL || temp->next == NULL)
    return;
node * next = temp->next->next;
free(temp->next);
temp->next = next;}
以及文件读取器:

node* fileReader(FILE *file){
node *t = malloc(sizeof(node));
char TopicName[20];
int fileRead = fscanf(file,"%s",TopicName);
if(fileRead != EOF){
    t->name = strdup(TopicName);
    tedad++;
    t->next = fileReader(file);
}
if(fileRead == EOF) {
    return NULL;
}
return t;}
编辑: 当代码运行时,当位置随机变为0时,链表的0位置不会删除,并继续使用链表中的节点

EDIT2:我更改了我的删除节点,它运行良好,没有任何问题,谢谢大家

node* deleteNode(node* head, unsigned i){
node* next;

if(head == NULL)
    return head;

next = head->next;

return i == 0
         ? (free(head), next)                              
         : (head->next = delete_at_index(next, i - 1), head);
}

我看到delete函数的主要逻辑问题是它是void,即它不返回任何内容。如果删除的节点位于列表的中间(或结束),这是很好的,因为头不会改变。但是对于删除head的情况,调用方可能期望他的引用在调用之后指向下一个节点(如果是一个元素列表,则为null)。考虑这个代码:

node* deleteNode (node *head_ref, int position)
{
    // passing in a NULL list returns NULL
    if (head_ref == NULL) {
    {
        return NULL;
    }

    // deleting the first element returns the second element as the new head
    node* temp = head_ref;
    if (position == 0)
    {
        node* ret = temp->next;
        free(head_ref);
        return ret;
    }

    // otherwise walk down the list to one before the deletion position
    for (int h=0; temp != NULL && h < position-1; h++) {
        temp = temp->next;
    }
    // if found, delete the node at the desired position
    if (temp != NULL && temp->next == NULL) {
        node* next = temp->next->next;
        free(temp->next);
        temp->next = next;
    }

    // for cases other than deleting the head, just return the current
    // (unmodified) head
    return head_ref;
}
node*deleteNode(node*head\u ref,int位置)
{
//传入NULL列表将返回NULL
if(head_ref==NULL){
{
返回NULL;
}
//删除第一个元素将返回第二个元素作为新的头
节点*temp=头部\u参考;
如果(位置==0)
{
节点*ret=temp->next;
免费(头参考);
返回ret;
}
//否则,沿着列表向下走到删除位置之前的位置
对于(int h=0;temp!=NULL&&h下一步;
}
//如果找到,请删除所需位置处的节点
if(temp!=NULL&&temp->next==NULL){
节点*next=temp->next->next;
自由(临时->下一步);
临时->下一步=下一步;
}
//对于删除头部以外的情况,只需返回当前
//(未修改的)头部
返回头_ref;
}

这与您的问题无关,但不要忘记释放内存:

node * temp = *head_ref;
if(position == 0)
{
    *head_ref = temp->next;
    free(temp);    // <--------
    return;
}
节点*temp=*head\u ref;
如果(位置==0)
{
*头部参考=温度->下一步;

free(temp);//如果您想保持
deleteNode
无效,那么问题在于
RandomFromList
函数。您只需更改函数体中存在的
*head
,而不是您传递给函数的指针,因此它仍然指向上一个节点

这是因为指针是按值传递的(复制的),就像C中的其他东西一样。 尝试使
RandomFromList
返回头部指针

另外,我认为删除功能中也存在一些内存泄漏。

void deleteNode(node**head\u ref,int pos){
void deleteNode(node **head_ref, int pos){
    node *del;

    for (   ; *head_ref; head_ref = &(*head_ref)->next) {
        if (pos-- <= 0) break;
        }

    if (!*head_ref) return; // Reached end of list: nothing found
    del = *head_ref;
    *head_ref = del->next;
    free(del);
    return;
    }
节点*del; 对于(;*head\u ref;head\u ref=&(*head\u ref)->下一步){ if(pos--next; 免费(del); 返回; }
请更具体地说明什么不起作用。是否有错误消息?实际结果是否与预期结果不同?如果“对于链表中的位置0不起作用”,然后您需要修复位置0的代码。有了这一点,我想向您表明,您的问题不够清楚。请更详细地描述它不起作用的方式。发生了什么不希望发生的事情?发生了什么希望发生的事情?请提供一些调试信息。所有涉及的变量的值是什么在尝试执行不起作用的操作之前和之后?使用printf()s查找,或者更高级地使用调试器:处理链表(以及所有其他指针问题),如果你用笔和纸,画变量的矩形,把它们的值写在里面,解决方案通常会更容易找到。使用箭头指向其他矩形的矩形来表示指针。在空指针的某个地方使用“NULL”一词。使用大“?”对于未初始化的变量。仅当程序有行时才更改变量。指向指针的指针是一个矩形,箭头从该矩形指向箭头开始的矩形。为什么RandomFromList是一个空函数但返回一些内容?我在RandomFromList中使用了如下代码:head=deleteNode(head,0);它出现了逻辑错误,我认为它丢失了链表。@Bob_uuuuu我也使用了更改后的代码,但对于0位置是链表,它在我要打印列表时会打印此代码:并且它也不会删除其他节点。我认为这不是真的,因为他使用了您可以使用指针到指针来更改指针值。例如,使用
**head
您可以更改函数中的
head
指针,但必须记住使用
&head
调用此函数。他在delete方法中使用指针指向指针,但在random方法中不使用指针指向指针。因为他在random函数中调用delete,我认为他看不到调用该函数的位置的更改。
void deleteNode(node **head_ref, int pos){
    node *del;

    for (   ; *head_ref; head_ref = &(*head_ref)->next) {
        if (pos-- <= 0) break;
        }

    if (!*head_ref) return; // Reached end of list: nothing found
    del = *head_ref;
    *head_ref = del->next;
    free(del);
    return;
    }