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

时间:2018-01-25 07:04:12

标签: 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 = *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;}

获取随机节点:

void RandomFromList(node *head){
// IF list is empty
if (head == NULL){
   return -1;
}
word = head->name;
// Iterate from the (k+1)th element to nth element
node *current = head;
int n;
for (n=2; current!=NULL; n++)
{
    // change result with probability 1/n
    if (rand() % n == 0)
       word = current->name;
    // Move to next node
    current = current->next;
}
sprintf(words , "%s" , word);
deleteNode(&head , search(head , word));
printf("Randomly selected key is %s\n", words);}

和文件阅读器:

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);
}

4 个答案:

答案 0 :(得分:1)

我看到你删除函数的主要逻辑问题是它是无效的,即它什么都不返回。如果要删除的节点位于列表的中间(或末尾),则可以正常工作,因为磁头不会更改。但是对于删除头部的情况,调用者可能期望在进行调用之后,他的引用将指向下一个节点(或者如果是一个元素的列表,则为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;
}

答案 1 :(得分:0)

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

node * temp = *head_ref;
if(position == 0)
{
    *head_ref = temp->next;
    free(temp);    // <--------
    return;
}

另外,你已经有一个指向* head_ref的指针(temp),对我来说看起来更干净,只是使用那个指针而不是再次取消引用head_ref。

答案 2 :(得分:0)

如果您想让deleteNode无效,则问题在于您的RandomFromList功能。您只是更改函数体中存在的* head而不是传递给函数的指针,因此它仍然指向上一个节点。

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

P.S。我认为你在delete函数中也有一些内存泄漏。

答案 3 :(得分:0)

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;
    }