[英]deleting a node in the middle of a linked list
我写了一段使用链表的代码。 我让用户输入几个数字,然后要求用户输入他希望删除的数字的索引。 我做了一些研究,发现我需要检查下一个节点是否是我要删除的节点,然后有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 45。然后,如果我输入0以删除索引,程序将打印出2 3 4 5。输入0或1。但是,当我输入2或更高的索引时,它会给我奇怪的输出,例如,如果我将链接列表设置为1 2 3 4 5,然后输入要删除的索引2,则应按权利输出1 2 4 5,但输出2 4 5,我不知道发生了什么,请向正确的方向指点我。
在deleteNode中,您使用实际的指针来遍历列表。 当您遍历列表时,您将移动实际的头部! 删除第一个元素时,仅应修改(*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;
}
找到修改后的deleteNode函数(还处理边界条件,如果我们试图删除一个比列表长度大的索引)
int deleteNode(ListNode ** ptrHead,int索引)
{
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.