C编程链接列表删除位置N处的节点

时间:2011-02-16 02:43:14

标签: c data-structures struct linked-list

编辑:找出问题所在。此外,如果你通过谷歌或其他搜索引擎发现这是我出错的地方以及如何解决它。

我的deleteNode()方法正确地使用正确的temp移动列表并保持头部不变。我出错的地方在于我作为该方法的结果返回的内容。我正在返回temp或newNode,这是不正确的,因为它通过列表直到找到定义的位置。一旦找到定义的位置,它就会重新分配 - >下一个指针指向下一个 - >下一个>指针是正确的,但我又回来了错误的东西。因为我们使用temp / NewNode移动了列表,所以我们丢失了标题,我们返回了我们找到的位置以及列表中下一个位置的任何位置。

我们如何解决这个问题就是返回头部(这是传递给方法的内容)。这有效的原因是因为我们必须了解LinkedLists的工作原理。每个节点的指针指向下一个节点。防爆。我们有一个链表| A | | - | B | | - | C | | - | D | | - | E | | - | F | |

如果我们要删除节点C,我们使用临时指针移动到节点B,然后在temp-> next-> next旁边分配B->那么跳过C节点并分配D节点。

注意:(据我所知,这实际上并没有释放C节点的内存,所以这不是最佳实践,因为你可以通过这种方式导致内存泄漏)你应该在C节点上使用free()方法。 / p>

以下是我最终使用的代码

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. 将节点分配给node-&gt; next
  6. return linkedlist
  7. 示例输入

    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:代码错误

    提前感谢您的帮助。根据我的结论,我的问题是我没有正确地通过清单,但我不确定为什么我不是。

5 个答案:

答案 0 :(得分:1)

在您的代码中,您有

newNode->next;
for循环中

。该操作没有做任何事情。

你也有

newNode-> = NULL;

这是无效的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. */
}

答案 1 :(得分:1)

从单链接列表中删除给定节点n可归结为此操作:

  • 将指向n的指针设置为指向n->next

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

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

由于指向n的指针可能是列表中上一个节点的p->next字段,或head指针(如果n},因此出现了复杂情况。是列表中的第一个节点。

您的代码似乎并不完整 - 它不会将任何节点的->next字段设置为任何内容,因此很难说出实际上是什么错误。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

想出你的for循环并没有达到你想要的位置。 更好地使用等于符号的符号它将起作用。 e.g。

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

}