【问题标题】:Does this function add new node to the end of the linked list? [closed]此函数是否将新节点添加到链表的末尾? [关闭]
【发布时间】:2020-05-24 07:26:07
【问题描述】:

我想知道,这会在列表末尾插入一个节点吗?假设我有一个 1->2->3->8->NULL 的链表,我想插入一个数据为 9 的新节点。它将递归遍历到 NULL。当 head 指向 NULL 时,head = nextNode 不起作用。还是 head 仍然指向 8 的节点?谢谢。

我只想知道这可以在列表末尾插入一个节点吗?我不这么认为。

void insert(Node *&head, int data) {
    if (head == NULL || data <head ->data) {
        Node *nextNode = new Node;
        nextNode->data = data;
        nextNode->next = head;
        head= nextNode;
    } else {
        insert(head->next, data);
    }
}

【问题讨论】:

  • 是的,这可以在列表末尾插入一个节点。在我的答案中的链接中自己尝试一下。
  • 也许这个函数令人困惑的部分是参数的名称head。除了第一次迭代之外,它不是列表的头部。

标签: c++ sorting recursion insert singly-linked-list


【解决方案1】:

这个函数是完全错误的,因为它会导致内存泄漏。它只适用于第一次迭代。 我正在给你写代码,但它不会帮助你学习。

if(head==NULL)
{
    Node *nxtNode=new Node;
    nxtNode->data=data;
    head=nxtNode;
    nxtNode->next=NULL;
    return;
}
if(head->next==NULL||data<head->next->data)
{
    Node *nxtNode=new Node;
    nxtNode->data=data;
    nxtNode->next=head->next;
    head->next=nxtNode->next;
    return;
}
else
{
    insert(head->next,data);
}

【讨论】:

  • 你的函数现在有很多悬空指针
  • 代码不会泄露内存。应该有一个遍历列表并释放它的类的析构函数。该功能似乎也可以正常工作。
  • @okovko 没有任何迹象表明,如果只有在节点周围有列表类的情况下,也可以遍历析构函数。在节点中这样做会导致堆栈溢出
  • @Swift-FridayPie 而且他们使用所谓的 Java 方法(这是我的术语),你不能使用例如指针指针。所以逻辑分为节点是等于NULL的头节点还是头节点不等于NULL。
  • 我的代码可以完美运行,但现在我知道他正在使用 *& 这就是他这样做的原因。但每当我这样做时我都会感到不安。
【解决方案2】:

这个条件

if ( head == NULL || data < head->data )

对于包含节点序列的列表中的每个节点,

不计算为真

1->2->3->8->NULL

因为数据9的值不小于现有节点的任何数据值。

所以函数将被递归调用,直到下一个节点等于 NULL(即当函数将参考最后一个节点的数据成员 next 等于 nullptr 时被调用)。结果,新节点被附加到列表的尾部。也就是说,列表中最后一个值为 NULL 的指针将被替换为新节点。因此节点按升序插入到列表中。

这是一个演示程序。

#include <iostream>

struct Node
{
    int data;
    Node *next;
};

void insert( Node * &head, int data ) 
{
    if ( head == nullptr || data < head ->data ) 
    {
        head = new Node { data, head };
    } 
    else 
    {
        insert( head->next, data );
    }
}

std::ostream & output( const Node *head, std::ostream &os = std::cout )
{
    for ( ; head != nullptr; head = head->next)
    {
        os << head->data << " -> ";
    }

    return os << "null";
}

int main() 
{
    Node *head = nullptr;

    for ( int data : { 3, 8, 1, 2, 9 } )
    {
        insert( head, data );
        output( head ) << '\n';
    }

    return 0;
}

它的输出是

3 -> null
3 -> 8 -> null
1 -> 3 -> 8 -> null
1 -> 2 -> 3 -> 8 -> null
1 -> 2 -> 3 -> 8 -> 9 -> null

为了清楚起见,考虑一个包含两个节点的列表,其中数据为 13

head  |node A with value 1|next B|  |node B with value 3| next nullptr|
 |______________|              |______________| 

并且您正在尝试插入一个值为 2 的节点。

函数调用

insert( head, 2 );

head->等于1的数据不大于2。所以函数调用类似

insert( ( node A )->next, 2 );

(节点A)->next->数据等于3大于2。

所以你必须用值 2 的新创建节点的地址替换 ( node A )->next。

head  |node A with value 1|next C|  |node B with value 3| next nullptr|
 |______________|              |              |
                               |              |
          |node C with value 2 | the value of next B of node A|

【讨论】:

  • 我没有得到的是,如果指针指向 NULL,nextNode 将指向 NULL。那么,NULL是否指向nextNode?​​span>
  • @HageNezz 节点的值为 8 的数据成员 next 将具有 NULL。该数据成员被新创建的节点替换,并且该创建节点的数据成员 next 设置为该节点的数据成员 next 的先前值,其值为 8,即 NULL。所以附加的节点将是列表的最后一个节点。
【解决方案3】:

它将一个新节点插入到链表中的排序位置。至少,这是意图。

这里是使用输入的编译代码来演示该行为:link

感兴趣的线路:if (head == NULL || data &lt; head-&gt;data)

新条目放置在这个条件通过的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 2013-11-13
    • 1970-01-01
    相关资源
    最近更新 更多