链表删除位置N的节点

发布于 2024-10-17 14:21:28 字数 3553 浏览 1 评论 0原文

编辑:找出问题所在。另外,如果您通过谷歌或其他搜索引擎发现了这个问题,这里就是我出错的地方以及如何修复它。

我的deleteNode()方法以正确的温度正确地在列表中移动,并保持头部不变。我出错的地方在于我作为该方法的结果返回的内容。我返回了 temp 或 newNode,这是不正确的,因为它会遍历列表直到找到定义的位置。一旦找到定义的位置,它将重新分配 ->next 指针以指向下一个 ->next> 位置。指针是正确的,但我再次返回了错误的东西。因为我们已经使用 temp/NewNode 移动了列表,所以我们丢失了标题,并且我们返回了我们找到的位置以及列表中下一个位置中仍然存在的内容。

我们如何解决这个问题是返回头部(这是传递到方法中的内容)。之所以有效,是因为我们必须了解 LinkedList 的工作原理。每个节点的指针都指向下一个节点。前任。我们有一个链表 |A|| - |B|| - |C|| - |D|| - |E|| - |F||

如果我们想删除节点 C,我们使用临时指针移动到节点 B,然后将 B->next 分配给 temp->next->next,从而跳过 C 节点并分配 D 节点。

注意:(据我所知,这实际上并没有释放 C 节点的内存,因此这不是最佳实践,因为这样可能会导致内存泄漏)您应该在 C 节点上使用 free() 方法。

这是我最终使用的代码,

struct node* DeleteNode(struct node* head, int pos) {

     struct node* temp = head;
     int length = LinkedListLength(temp);
     int i;

    if(pos <= 0 || pos > length){
        printf("ERROR: Node does not exist!\n");
    }else{
        if(pos == 1){
            head = head->next; //move from head (1st node) to second node
        }else{
            for(i = 1; i < pos-1; ++i){ //move through list
                    temp = temp->next;
            }
            temp->next = temp->next->next;
        }
    }
    return head;
}

希望有助于理解我是如何修复它的。

/////////////////////////////////////////////////////////// /////////////////////////////////////////////////
/////////////////////////////////////////////////////////// /////////////////////////////////////////////////
原帖
/////////////////////////////////////////////////////////// /////////////////////////////////////////////////
/////////////////////////////////////////////////////////// ////////////////////////////////////////////////

编辑: 注意:这是一项家庭作业,我花了几天(估计 4 小时)对其进行编程,我只是卡在这一部分上。您可以在下面查看我的尝试

我已经能够从开始/结束处插入和删除,但是我似乎无法让链接列表中位置 N 的删除节点正常工作。

我的伪代码如下所示:

  1. LinkedList: 1,3,5,7,9,23
  2. Grab LinkedList
  3. 创建新的结构节点 A = head
  4. 通过链表移动直到 位置
  5. 将节点分配给节点->下一个
  6. 返回链接列表

示例输入

Node structure 
int data;
struct node* next;

int values[] = {1,3,5,7,9,23};
struct node* llist = CreateList(values,6);

llist = DeleteNode(llist, 1);
llist = DeleteNode(llist, 5);
llist = DeleteNode(llist, 3);

一旦代码运行,应该将 llist 保留为值 3、5、9 但是,它用 0 替换第一个节点

实际代码:

struct node* DeleteNode(struct node* head, int pos) {

struct node* temp = head;
struct node* newNode = head;
int length;
int i;

printf("DeleteNode: position = %d \nBefore: ", pos);
PrintList(temp);

if(pos <= 0){ //node does NOT exist
    printf("ERROR: Node does not exist!\n");
}else{ //node DOES exist
    length = LinkedListLength(temp);

    if(length < pos){ //if length < position Node does not exist
        printf("ERROR: Node does not exist!\n");
    }else{
        if(pos == 0){
            newNode = temp->next;
        }else if(pos == 1){
            newNode = temp->next;
        }else{
            for(i = 1; i < pos; i++){
                printf("i = %d\n", i);
                temp = temp->next;
                newNode->next;
            }
            if(temp->next == NULL){
                newNode = NULL;
            }else{
                newNode = temp->next;
            }
        }
    printf("After: ");
    PrintList(newNode);
    printf("\n");
    }
}
return newNode;
}

编辑#2:代码拼写错误

感谢您提前提供的任何帮助。根据我的结论,我的问题是我没有正确地浏览列表,但我不确定为什么我没有。

EDIT: Figured out the problem. Also if you found this through google or another search engine here is where I went wrong and how to fix it.

My deleteNode() method was moving through the list properly with the correct temp and keeping the head untouched. Where I was going wrong was in what I was returning as the result of the method. I was returning either temp or newNode which is incorrect because it goes through the list until it finds defined position. Once it finds that defined position it it would reassign the ->next pointer to point to the next->next> pointer which is correct but again I was returning the wrong thing. Because we had moved through the list using temp/NewNode we lost the header and we were returning the position we found and whatever was still in the next positions of the list.

How we fix this is returning the head (which is what is passed into the method). The reason why this works is because we have to understand how LinkedLists work. The pointers of each node point to the next node. Ex. we have a linked list |A|| - |B|| - |C|| - |D|| - |E|| - |F||

If we want to delete Node C we move to node B using the temp pointer and then assign the B->next to temp->next->next Thus skipping over C node and assigning D node.

NOTE: (From what I know this does not actually free the memory of C node so it isn't best practice because you can cause memory leaks this way) You should use the free() method on the C node.

Here is the code I ended up using

struct node* DeleteNode(struct node* head, int pos) {

     struct node* temp = head;
     int length = LinkedListLength(temp);
     int i;

    if(pos <= 0 || pos > length){
        printf("ERROR: Node does not exist!\n");
    }else{
        if(pos == 1){
            head = head->next; //move from head (1st node) to second node
        }else{
            for(i = 1; i < pos-1; ++i){ //move through list
                    temp = temp->next;
            }
            temp->next = temp->next->next;
        }
    }
    return head;
}

Hopefully that helps understand how I went out fixing it.

//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
ORIGINAL POST
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

EDIT: Note: This is a homework assignment I have spent a few days (estimated 4 hours) programming it I am just stuck on this one part. You can view my attempt below

I've been able to insert and delete from begining/end however I can't seem to get my delete node at position N in linkedlist to work.

My psuedocode looks like this:

  1. LinkedList: 1,3,5,7,9,23
  2. Grab LinkedList
  3. Create new struct node A = head
  4. Move through linkedlist until
    position
  5. Assign node to node->next
  6. return linkedlist

EXAMPLE INPUT

Node structure 
int data;
struct node* next;

int values[] = {1,3,5,7,9,23};
struct node* llist = CreateList(values,6);

llist = DeleteNode(llist, 1);
llist = DeleteNode(llist, 5);
llist = DeleteNode(llist, 3);

Which should leave the llist with the values 3, 5, 9 once the code has been run However, It is replacing the first node with a 0

Actual Code:

struct node* DeleteNode(struct node* head, int pos) {

struct node* temp = head;
struct node* newNode = head;
int length;
int i;

printf("DeleteNode: position = %d \nBefore: ", pos);
PrintList(temp);

if(pos <= 0){ //node does NOT exist
    printf("ERROR: Node does not exist!\n");
}else{ //node DOES exist
    length = LinkedListLength(temp);

    if(length < pos){ //if length < position Node does not exist
        printf("ERROR: Node does not exist!\n");
    }else{
        if(pos == 0){
            newNode = temp->next;
        }else if(pos == 1){
            newNode = temp->next;
        }else{
            for(i = 1; i < pos; i++){
                printf("i = %d\n", i);
                temp = temp->next;
                newNode->next;
            }
            if(temp->next == NULL){
                newNode = NULL;
            }else{
                newNode = temp->next;
            }
        }
    printf("After: ");
    PrintList(newNode);
    printf("\n");
    }
}
return newNode;
}

EDIT #2: Code typo

Thanks for any help in advance. From what I have concluded my problem is that I am not moving through the list properly but I am unsure as to why I am not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

静待花开 2024-10-24 14:21:28

有该行

newNode->next;

在您的代码中,您的 for 循环中 。该操作没有任何作用。

你还有

newNode-> = NULL;

which 不是有效的C,我不知道你是如何编译它的。

但实际上,不要使用该循环。链表是最基本的递归数据结构之一。因此,几乎所有操作它们的算法都是最优雅的递归解决方案。

typedef struct node node_t;

node_t* delete_at_index(node_t* head, unsigned i)
{
    node_t* next;

    if(head == NULL)
        return head;

    next = head->next;

    return i == 0
             ? (free(head), next)                                 /* If i == 0, the first element needs to die. Do it. */
             : (head->next = delete_at_index(next, i - 1), head); /* If it isn't the first element, we recursively check the rest. */
}

In your code, you have the line

newNode->next;

in your for loop. That operation doesn't do anything.

You also have

newNode-> = NULL;

which is not valid C, and I have no idea how you got that to compile.

But really, don't use that loop. A linked list is one of the most basic recursive data structures. As a result, almost all algorithms manipulating them are most elegant as a recursive solution.

typedef struct node node_t;

node_t* delete_at_index(node_t* head, unsigned i)
{
    node_t* next;

    if(head == NULL)
        return head;

    next = head->next;

    return i == 0
             ? (free(head), next)                                 /* If i == 0, the first element needs to die. Do it. */
             : (head->next = delete_at_index(next, i - 1), head); /* If it isn't the first element, we recursively check the rest. */
}
甜味超标? 2024-10-24 14:21:28

从单链表中删除给定节点 n 可以归结为以下操作:

  • 将指向 n 的指针设置为指向 n-> ;下一步

您可以将其分解为两个操作:

  • 查找指向 n 的指针;
  • 将该指针设置为n->next

出现问题的原因是,指向 n 的指针可能是列表中前一个节点的 p->next 字段,或者是 head code> 指针(如果 n 是列表中的第一个节点)。

您的代码似乎并不完整 - 它从未将任何节点的 ->next 字段设置为任何内容,因此很难说到底出了什么问题。

Removing a given node n from a singly-linked list can be boiled down to this operation:

  • Set the pointer that points to n to point instead to n->next.

You can break this down into two operations:

  • Find the pointer that points to n;
  • Set that pointer to n->next.

The complication arises because the pointer that points to n might either be the p->next field of the previous node in the list, or the head pointer (if n is the first node in the list).

Your code does not appear to be complete - it doesn't ever set the ->next field of any node to anything, so it's hard to say what's actually wrong.

诗酒趁年少 2024-10-24 14:21:28
// Remove list's node located at specified position.
// Arguments:
//  head -- list's head
//  pos -- index of a node to be removed (1-based!!!)

struct node* DeleteNode(struct node* head, int pos) 
{

    struct node* node;
    struct node* prev;
    int length;
    int i;

    printf("DeleteNode: position = %d \nBefore: ", pos);
    PrintList(head);

    // Check position's lower bound. Should be >= 1
    if(pos <= 0) { //node does NOT exist
        printf("ERROR: Node does not exist!\n");
        return head;
    }

    // Seek to the specified node, and keep track of previous node.
    // We need previous node to remove specified node from the list.

    for(i=1, prev = 0, node = head; i < pos && node != 0; i++) {
        prev = node;
        node = node->next;
    }

    // Out of range
    if(0 == node) {
        printf("ERROR: Index out of bounds!\n");
        return head;
    }

    // @node points to a list's node located at index pos 
    // @prev points to a previous node.

    // Remove current node from the list.
    if(0 == prev) {
        head = node->next;
    }
    else {
        prev->next = node->next;
    }
    free(node);

    return head;   
}
// Remove list's node located at specified position.
// Arguments:
//  head -- list's head
//  pos -- index of a node to be removed (1-based!!!)

struct node* DeleteNode(struct node* head, int pos) 
{

    struct node* node;
    struct node* prev;
    int length;
    int i;

    printf("DeleteNode: position = %d \nBefore: ", pos);
    PrintList(head);

    // Check position's lower bound. Should be >= 1
    if(pos <= 0) { //node does NOT exist
        printf("ERROR: Node does not exist!\n");
        return head;
    }

    // Seek to the specified node, and keep track of previous node.
    // We need previous node to remove specified node from the list.

    for(i=1, prev = 0, node = head; i < pos && node != 0; i++) {
        prev = node;
        node = node->next;
    }

    // Out of range
    if(0 == node) {
        printf("ERROR: Index out of bounds!\n");
        return head;
    }

    // @node points to a list's node located at index pos 
    // @prev points to a previous node.

    // Remove current node from the list.
    if(0 == prev) {
        head = node->next;
    }
    else {
        prev->next = node->next;
    }
    free(node);

    return head;   
}
情痴 2024-10-24 14:21:28

您的DeleteNode不会删除节点,它会从列表的前面删除pos节点。因此,您尝试从仅包含 6 个项目的列表中删除 9 个项目,这当然会导致空列表 (NULL)。此外,您的代码过于复杂,并且包含以前尝试的残余内容。请不要对自己或我们这样做;提供简单干净的代码,它会更容易理解和修复。

Your DeleteNode doesn't delete a node, it removes pos nodes from the front of the list. So you're trying to remove 9 items from a list that only contains 6, resulting of course in an empty list (NULL). Also, your code is overly complex and contains remnants of previous attempts. Please don't do that to yourself or to us; provide simple clean code and it will be easier to understand and to fix.

娜些时光,永不杰束 2024-10-24 14:21:28

发现你的 for 循环没有达到你想要的位置。
最好使用等号来表示它起作用的约束。
例如

for (i=1;i<=position-1;i++)
{

}

Figured out your for loop isn't reaching the desired position you wanted.
Better use equal to sign for the constraint it will work.
e.g.

for (i=1;i<=position-1;i++)
{

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文