首页 文章

删除链表中间的节点

提问于
浏览
0

我写了一段使用链表的代码 . 我让用户输入几个数字,然后要求用户输入他希望删除的数字的索引 . 我做了一些研究,发现我需要检查下一个节点是否是我要删除的节点,然后有2个临时指针指向当前节点和下一个节点(我想要删除的节点),然后将第一个临时指针的下一个节点分配给第二个临时指针的下一个节点,然后最后释放第二个临时指针 . 这是我的代码:

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

因此,例如,如果我输入1 2 3 4 5 -1,链表将包含1 2 3 4 5.然后,如果我输入0表示要删除的索引,程序将打印出2 3 4 5.这是否有效输入0或1.但是,当我输入索引2及以上时,它给出了奇怪的输出,例如,如果我将链表设置为1 2 3 4 5,并输入索引2以删除,通过权限它应该输出1 2 4 5,但它输出2 4 5,我不知道最新情况,请指出我正确的方向 .

2 回答

  • 1

    找到修改后的deleteNode函数(如果我们试图删除一个超过列表长度的索引,也会处理边界条件)

    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

    在deleteNode中,您使用实际的headpointer来遍历列表 . 当您循环浏览列表时,您移动实际的头部!您应该只在删除第一个元素时修改 (*ptrHead) .

    我建议您将 *ptrHead 复制到局部变量并使用局部变量遍历列表 .

    我突出了重要的一行,评论以 // *** 开头

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

相关问题