deleting a node in the middle of a linked list

给你一囗甜甜゛ 提交于 2019-12-10 12:17:45

问题


I have written a piece of code that uses linked lists. I get the user to enter a couple of numbers and then ask the user to enter the index of the digit he wishes to delete. I did some research and found out that i need to check whether the next node is the one I want to delete, then have 2 temp pointers point to the current node and the next node(which is the one i want to delete), then assign the next node of the first temp pointer to the next node of the second temp pointer then finally free the second temp pointer. Here is my code:

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
    int item;
    struct node *next;
}ListNode;

void print(ListNode *head);
int deleteNode(ListNode **ptrHead, int index);

int main()
{
    int n;
    int remove;
    ListNode *head = NULL;
    ListNode *temp = NULL;
    printf("Enter a value: ");
    scanf("%d", &n);
    while (n != -1)
    {
        if (head == NULL)
        {
            head = malloc(sizeof(ListNode));
            temp = head;
        }
        else
        {
            temp->next = malloc(sizeof(ListNode));
            temp = temp->next;
        }
        temp->item = n;
        temp->next = NULL;
        printf("Enter a value: ");
        scanf("%d", &n);
    }

    printf("Enter index to remove: ");
    scanf("%i", &remove);

    while (remove != -1)
    {
        deleteNode(&head, remove);
        print(head);
        printf("Enter index to remove: ");
        scanf("%i", &remove);
    }
    while (head != NULL)
    {
        temp = head;
        head = head->next;
        free(temp);
    }
    head = NULL;
    return 0;
}
int deleteNode(ListNode **ptrHead, int index)
{
    int count = 0;
    ListNode* temp1 = NULL;
    ListNode* temp2 = NULL;
    while (count <= index)
    {
        if (index == 0)
        {
            temp2 = (*ptrHead)->next;
            free((*ptrHead));
            (*ptrHead) = temp2;
            return 0;
            break;
        }
        if (count+1 == index)//checking for the node ahead
        {
            temp1 = (*ptrHead);
            temp2 = (*ptrHead)->next;//the one to free
            temp1->next = temp2->next;
            free(temp2);
            return 0;
            break;
        }
        (*ptrHead) = (*ptrHead)->next;
        count++;
    }
    return -1;
}
void print(ListNode *head){
    if (head == NULL)
    {
        return;
    }
    while (head != NULL)
    {
        printf("%i\n", head->item);
        head = head->next;
    }
}

So for example if i enter 1 2 3 4 5 -1, the linked list will contain 1 2 3 4 5. Then if i enter 0 for the index to remove, the program will print out 2 3 4 5. This works whether I enter 0 or 1. However, when I enter the indexes 2 and above, it gives me weird outputs like for example if I set the linked list as 1 2 3 4 5, and enter the index 2 to remove, by rights it should output 1 2 4 5, but instead it outputs 2 4 5, I have no idea whats going on, please point me in the right direction.


回答1:


Find the modified deleteNode function (handles boundary conditions also , if we are trying to delete an index which is more then the list length)

int deleteNode(ListNode **ptrHead, int index)

{

int count = 0;
ListNode* temp1 = NULL;
ListNode* temp2 = NULL;

temp1 = (*ptrHead);

while((temp1 != NULL) && (count <= index))
{
    if (index == 0)
    {
        temp2 = temp1->next;
        free(temp1);
        (*ptrHead) = temp2;
        return 0;
    }
    if ((count+1 == index) && (temp1->next != NULL))
    {
        ListNode*temp = NULL;

        temp = temp1->next;
        temp2 = temp->next;
        temp1->next = temp2;
        free(temp);
        return 0;
    }

    temp1 = temp1->next;
    count++;
}

return -1;

}




回答2:


In deleteNode you use the actual headpointer to traverse the list. As you loop through the list you move the actual head! You should only modify (*ptrHead) when you delete the first element.

I suggest that you copy *ptrHead to a local variable and use the local variable to traverse the list.

I've highlighted the important lines with comments starting with // ***

int deleteNode(ListNode **ptrHead, int index)
{
    int count = 0;
    ListNode* temp1 = NULL;
    ListNode* temp2 = NULL;
    ListNode* traverse = *ptrHead;   // *** make a copy that we can use to traverse the list
    while (count <= index)
    {
        if (index == 0)
        {
            temp2 = (*ptrHead)->next;
            free((*ptrHead));
            (*ptrHead) = temp2;  // *** Keep this line as it is to correctly handle deletion of index 0.
            return 0;
            break;
        }
        if (count+1 == index)//checking for the node ahead
        {
            temp1 = traverse;                           // *** Use local copy of pointer
            temp2 = traverse->next;//the one to free    // *** Use local copy of pointer
            temp1->next = temp2->next;
            free(temp2);
            return 0;
            break;
        }
        traverse = traverse->next;                         // *** Use local copy of pointer
        count++;
    }
    return -1;
}


来源:https://stackoverflow.com/questions/22531201/deleting-a-node-in-the-middle-of-a-linked-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!