Why do linked lists use pointers instead of storing nodes inside of nodes

后端 未结 11 2163
春和景丽
春和景丽 2020-12-07 13:53

I\'ve worked with linked lists before extensively in Java, but I\'m very new to C++. I was using this node class that was given to me in a project just fine

         


        
相关标签:
11条回答
  • 2020-12-07 14:13

    Why do linked lists use pointers instead of storing nodes inside of nodes?

    There is of course a trivial answer.

    If they didn't link one node to the next by a pointer, they wouldn't be linked lists.

    The existence of linked lists as a thing is because we want to be able to chain objects together. For example: we already have an object from somewhere. We now want to put that actual object (not a copy) at the end of a queue, for example. That is achieved by adding a link from the last element already on the queue to the entry we are adding. In machine terms, that's filling in a word with the address of the next element.

    0 讨论(0)
  • 2020-12-07 14:14

    Overview

    There are 2 ways to reference and allocate objects in C++, while in Java there is only one way.

    In order to explain this, the following diagrams, show how objects are stored in memory.

    1.1 C++ Items without pointers

    class AddressClass
    {
      public:
        int      Code;
        char[50] Street;
        char[10] Number;
        char[50] POBox;
        char[50] City;
        char[50] State;
        char[50] Country;
    };
    
    class CustomerClass
    {
      public:
        int          Code;
        char[50]     FirstName;
        char[50]     LastName;
        // "Address" IS NOT A pointer !!!
        AddressClass Address;
    };
    
    int main(...)
    {
       CustomerClass MyCustomer();
         MyCustomer.Code = 1;
         strcpy(MyCustomer.FirstName, "John");
         strcpy(MyCustomer.LastName, "Doe");
         MyCustomer.Address.Code = 2;
         strcpy(MyCustomer.Address.Street, "Blue River");
         strcpy(MyCustomer.Address.Number, "2231 A");
    
       return 0;
    } // int main (...)
    
    .......................................
    ..+---------------------------------+..
    ..|          AddressClass           |..
    ..+---------------------------------+..
    ..| [+] int:      Code              |..
    ..| [+] char[50]: Street            |..
    ..| [+] char[10]: Number            |..
    ..| [+] char[50]: POBox             |..
    ..| [+] char[50]: City              |..
    ..| [+] char[50]: State             |..
    ..| [+] char[50]: Country           |..
    ..+---------------------------------+..
    .......................................
    ..+---------------------------------+..
    ..|          CustomerClass          |..
    ..+---------------------------------+..
    ..| [+] int:      Code              |..
    ..| [+] char[50]: FirstName         |..
    ..| [+] char[50]: LastName          |..
    ..+---------------------------------+..
    ..| [+] AddressClass: Address       |..
    ..| +-----------------------------+ |..
    ..| | [+] int:      Code          | |..
    ..| | [+] char[50]: Street        | |..
    ..| | [+] char[10]: Number        | |..
    ..| | [+] char[50]: POBox         | |..
    ..| | [+] char[50]: City          | |..
    ..| | [+] char[50]: State         | |..
    ..| | [+] char[50]: Country       | |..
    ..| +-----------------------------+ |..
    ..+---------------------------------+..
    .......................................
    

    Warning: The C++ syntax used in this example, is similar to the syntax in Java. But, the memory allocation is different.

    1.2 C++ Items using pointers

    class AddressClass
    {
      public:
        int      Code;
        char[50] Street;
        char[10] Number;
        char[50] POBox;
        char[50] City;
        char[50] State;
        char[50] Country;
    };
    
    class CustomerClass
    {
      public:
        int           Code;
        char[50]      FirstName;
        char[50]      LastName;
        // "Address" IS A pointer !!!
        AddressClass* Address;
    };
    
    .......................................
    ..+-----------------------------+......
    ..|        AddressClass         +<--+..
    ..+-----------------------------+...|..
    ..| [+] int:      Code          |...|..
    ..| [+] char[50]: Street        |...|..
    ..| [+] char[10]: Number        |...|..
    ..| [+] char[50]: POBox         |...|..
    ..| [+] char[50]: City          |...|..
    ..| [+] char[50]: State         |...|..
    ..| [+] char[50]: Country       |...|..
    ..+-----------------------------+...|..
    ....................................|..
    ..+-----------------------------+...|..
    ..|         CustomerClass       |...|..
    ..+-----------------------------+...|..
    ..| [+] int:      Code          |...|..
    ..| [+] char[50]: FirstName     |...|..
    ..| [+] char[50]: LastName      |...|..
    ..| [+] AddressClass*: Address  +---+..
    ..+-----------------------------+......
    .......................................
    
    int main(...)
    {
       CustomerClass* MyCustomer = new CustomerClass();
         MyCustomer->Code = 1;
         strcpy(MyCustomer->FirstName, "John");
         strcpy(MyCustomer->LastName, "Doe");
    
         AddressClass* MyCustomer->Address = new AddressClass();
         MyCustomer->Address->Code = 2;
         strcpy(MyCustomer->Address->Street, "Blue River");
         strcpy(MyCustomer->Address->Number, "2231 A");
    
         free MyCustomer->Address();
         free MyCustomer();
    
       return 0;
    } // int main (...)
    

    If you check the difference between both ways, you'll see, that in the first technique, the address item is allocated within the customer, while the second way, you have to create each address explictly.

    Warning: Java allocates objects in memory like this second technique, but, the syntax is like the first way, which may be confusing to newcomers to "C++".

    Implementation

    So your list example could be something similar to the following example.

    class Node
    {
      public:
       Node(int data);
    
       int m_data;
       Node *m_next;
    };
    
    .......................................
    ..+-----------------------------+......
    ..|            Node             |......
    ..+-----------------------------+......
    ..| [+] int:           m_data   |......
    ..| [+] Node*:         m_next   +---+..
    ..+-----------------------------+...|..
    ....................................|..
    ..+-----------------------------+...|..
    ..|            Node             +<--+..
    ..+-----------------------------+......
    ..| [+] int:           m_data   |......
    ..| [+] Node*:         m_next   +---+..
    ..+-----------------------------+...|..
    ....................................|..
    ..+-----------------------------+...|..
    ..|            Node             +<--+..
    ..+-----------------------------+......
    ..| [+] int:           m_data   |......
    ..| [+] Node*:         m_next   +---+..
    ..+-----------------------------+...|..
    ....................................v..
    ...................................[X].
    .......................................
    

    Summary

    Since a Linked List has a variable quantity of items, memory is allocated as is required, and, as is available.

    UPDATE:

    Also worth to mention, as @haccks commented in his post.

    That sometimes, references or object pointers, indicate nested items (a.k.a. "U.M.L. Composition").

    And sometimes, references or object pointers, indicates external items (a.k.a. "U.M.L. Aggregation").

    But, nested items of the same class, cannot be applied with the "no-pointer" technique.

    0 讨论(0)
  • 2020-12-07 14:18

    The latter (Node m_next) would have to contain the node. It wouldn't point to it. And there would then be no linking of elements.

    0 讨论(0)
  • 2020-12-07 14:20

    Because this in C++

    int main (..)
    {
        MyClass myObject;
    
        // or
    
        MyClass * myObjectPointer = new MyClass();
    
        ..
    }
    

    is equivalent to this in Java

    public static void main (..)
    {
        MyClass myObjectReference = new MyClass();
    }
    

    where both of them create a new object of MyClass using the default constructor.

    0 讨论(0)
  • 2020-12-07 14:23

    Why is it better to use pointers in a linked list?

    The reason is that when you create a Node object, compiler has to allocate memory for that object and for that the size of object is calculated.
    Size of pointer to any type is known to compiler and therefore with self referential pointer size of object can be calculated.

    If Node m_node is used instead then compiler has no idea about the size of Node and it will stuck in an infinite recursion of calculating sizeof(Node). Always remember: a class cannot contain a member of its own type.

    0 讨论(0)
提交回复
热议问题