繁体   English   中英

链接列表-新节点指针与新节点变量

[英]Linked list - new Node pointer vs. new Node variable

我正在创建一个练习链接列表,但遇到了问题。

我已经创建2个类似代码和在第一个我创建某些structure called Node作为一个variable和在第二代码创建一个structure called Node作为一个pointer

我认为它应该以相同的方式工作,但事实并非如此。 我将发布代码,并查看名为addNode()的函数。

我还有一个下一个问题:为什么我必须传递这样的指针: addNode( Node *& head, Node *& tail )才能使其正常工作,而不是将它们作为addNode( Node * head, Node * tail )传递。

第一个代码(错误):

#include <iostream>
#include <string>

using namespace std;

struct Node{
    int    val;
    Node * prev;
    Node * next;

    Node( int val ) : val( val ) { }
};


void printList( Node * ptr ){
    while( ptr != NULL ){
        cout << ptr -> val << " ";
        ptr = ptr -> next;
    }   
    cout << endl;
}

void addNode( int val, Node *& head, Node *& tail ){
    Node tmp( val );
    if( head == NULL ){
        head            = &tmp;
        tail            = &tmp;
        tmp . prev      = NULL;
        tmp . next      = NULL;
    }
    else{
        tail -> next    = &tmp;
        tmp . prev      = tail;
        tmp . next      = NULL;
        tail            = &tmp;
    }
}

int main(){

    Node * head         = NULL;
    Node * tail         = NULL;

    addNode( 3, head, tail );
    addNode( 8, head, tail );
    addNode( 2, head, tail );
    addNode( 4, head, tail );
    addNode( 15, head, tail );
    addNode( 11, head, tail );

    /*Node b( 5 );

    cout << b . val << endl;
    */
    printList( head );
    return 0;
}

第二个代码(好):

#include <iostream>
#include <string>

using namespace std;

struct Node{
    int      val;
    Node * prev;
    Node * next;

    Node( int val ) : val( val ) { }
};


void printList( Node * ptr ){
    while( ptr != NULL ){
        cout << ptr -> val << " ";
        ptr = ptr -> next;
    }   
    cout << endl;
}

void addNode( int val, Node *& head, Node *& tail ){
    Node * tmp = new Node( val );
    if( head == NULL ){
        head            = tmp;
        tail            = tmp;
        tmp -> prev     = NULL;
        tmp -> next     = NULL;
    }
    else{
        tail -> next    = tmp;
        tmp -> prev     = tail;
        tmp -> next     = NULL;
        tail            = tmp;
    }
}

int main(){

    Node * head         = NULL;
    Node * tail         = NULL;

    addNode( 3, head, tail );
    addNode( 8, head, tail );
    addNode( 2, head, tail );
    addNode( 4, head, tail );
    addNode( 15, head, tail );
    addNode( 11, head, tail );

    /*Node b( 5 );

    cout << b . val << endl;
    */
    printList( head );
    return 0;
}

如果执行Node tmp ,则退出定义范围后tmp被销毁。

在另一方面,这样做Node *tmp = new Node的分配内存Node上堆和给你一个指针tmp它。 仅当您在其上调用delete时,该Node才被销毁。

进入问题的第二部分,如果需要修改指针而不是指针指向的对象,则希望通过引用传递指针。

如果执行head = tmp, tail = tmp而不通过引用传递headtail ,那么headtail将只保留该值,直到该函数的范围为止。 此更改不会反映在addNode()

为了使用功能修改headtail ,必须通过引用(即第二代码段)传递它们。 在第一个代码段中,它们是通过value传递的,在函数addNode()内进行的任何修改都将在函数超出范围后消失。


情况1 :按值传递

addNode(head);   // call

功能体:

void addNode(Node *headCopy) {   // Node *headCopy = head,   copy is created
    headCopy = &someThing;    // the copy of head point to something else
                              // not the actual 'head' that changes its pointee
}

情况2 :通过引用传递

addNode(&head);

功能体:

void addNode(Node *&headReference) {    // reference to 'head'
    headReference = &someThing;  // the actual 'head' changes its pointee
}

由于原始指针的复制操作便宜,因此没有理由通过引用传递它。

void addNode( int val, Node *& head, Node *& tail ){
Node tmp( val ); // tmp - local variable
if( head == NULL ){
    head            = &tmp; // address of local variable
    tail            = &tmp; // above
    tmp . prev      = NULL;
    tmp . next      = NULL;
}
else{
    tail -> next    = &tmp; // above
    tmp . prev      = tail;
    tmp . next      = NULL;
    tail            = &tmp; // above
}
} // local variable tmp get destructed, tail head contain address of unexisting object

它是一个双向链接列表,并在Node构造函数中更改Node成员val或参数val的名称,添加head(nullptr),tail(nullptr),否则不会为NULL

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM