The approach that you describe is compatible not only with C++, but also with its (mostly) subset language C. Learning to develop a C-style linked-list is a good way to introduce yourself to low-level programming techniques (such as manual memory management), but it generally is not a best-practice for modern C++ development.
Below, I have implemented four variations on how to manage a list of items in C++.
- raw_pointer_demouses the same approach as yours -- manual memory management required with the use of raw pointers.  The use of C++ here is only for syntactic-sugar, and the approach used is otherwise compatible with the C language.
- In shared_pointer_demothe list management is still done manually, but the memory management is automatic (doesn't use raw pointers). This is very similar to what you have probably experienced with Java.
- std_list_demouses the standard-library- listcontainer. This shows how much easier things get if you rely on existing libraries rather than rolling your own.
- std_vector_demouses the standard-library- vectorcontainer. This manages the list storage in a single contiguous memory allocation. In other words, there aren't pointers to individual elements. For certain rather extreme cases, this may become significantly inefficient. For typical cases, however, this is the recommended best practice for list management in C++.
Of note: Of all of these, only the raw_pointer_demo actually requires that the list be explicitly destroyed in order to avoid "leaking" memory.  The other three methods would automatically destroy the list and its contents when the container goes out of scope (at the conclusion of the function). The point being: C++ is capable of being very "Java-like" in this regard -- but only if you choose to develop your program using the high-level tools at your disposal.
/*BINFMTCXX: -Wall -Werror -std=c++11
*/
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <memory>
using std::cerr;
/** Brief   Create a list, show it, then destroy it */
void raw_pointer_demo()
{
    cerr << "\n" << "raw_pointer_demo()..." << "\n";
    struct Node
    {
        Node(int data, Node *next) : data(data), next(next) {}
        int data;
        Node *next;
    };
    Node * items = 0;
    items = new Node(1,items);
    items = new Node(7,items);
    items = new Node(3,items);
    items = new Node(9,items);
    for (Node *i = items; i != 0; i = i->next)
        cerr << (i==items?"":", ") << i->data;
    cerr << "\n";
    // Erase the entire list
    while (items) {
        Node *temp = items;
        items = items->next;
        delete temp;
    }
}
raw_pointer_demo()...
9, 3, 7, 1
/** Brief   Create a list, show it, then destroy it */
void shared_pointer_demo()
{
    cerr << "\n" << "shared_pointer_demo()..." << "\n";
    struct Node; // Forward declaration of 'Node' required for typedef
    typedef std::shared_ptr<Node> Node_reference;
    struct Node
    {
        Node(int data, std::shared_ptr<Node> next ) : data(data), next(next) {}
        int data;
        Node_reference next;
    };
    Node_reference items = 0;
    items.reset( new Node(1,items) );
    items.reset( new Node(7,items) );
    items.reset( new Node(3,items) );
    items.reset( new Node(9,items) );
    for (Node_reference i = items; i != 0; i = i->next)
        cerr << (i==items?"":", ") << i->data;
    cerr<<"\n";
    // Erase the entire list
    while (items)
        items = items->next;
}
shared_pointer_demo()...
9, 3, 7, 1
/** Brief   Show the contents of a standard container */
template< typename C >
void show(std::string const & msg, C const & container)
{
    cerr << msg;
    bool first = true;
    for ( int i : container )
        cerr << (first?" ":", ") << i, first = false;
    cerr<<"\n";
}
/** Brief  Create a list, manipulate it, then destroy it */
void std_list_demo()
{
    cerr << "\n" << "std_list_demo()..." << "\n";
    // Initial list of integers
    std::list<int> items = { 9, 3, 7, 1 };
    show( "A: ", items );
    // Insert '8' before '3'
    items.insert(std::find( items.begin(), items.end(), 3), 8);
    show("B: ", items);
    // Sort the list
    items.sort();
    show( "C: ", items);
    // Erase '7'
    items.erase(std::find(items.begin(), items.end(), 7));
    show("D: ", items);
    // Erase the entire list
    items.clear();
    show("E: ", items);
}
std_list_demo()...
A:  9, 3, 7, 1
B:  9, 8, 3, 7, 1
C:  1, 3, 7, 8, 9
D:  1, 3, 8, 9
E:
/** brief  Create a list, manipulate it, then destroy it */
void std_vector_demo()
{
    cerr << "\n" << "std_vector_demo()..." << "\n";
    // Initial list of integers
    std::vector<int> items = { 9, 3, 7, 1 };
    show( "A: ", items );
    // Insert '8' before '3'
    items.insert(std::find(items.begin(), items.end(), 3), 8);
    show( "B: ", items );
    // Sort the list
    sort(items.begin(), items.end());
    show("C: ", items);
    // Erase '7'
    items.erase( std::find( items.begin(), items.end(), 7 ) );
    show("D: ", items);
    // Erase the entire list
    items.clear();
    show("E: ", items);
}
std_vector_demo()...
A:  9, 3, 7, 1
B:  9, 8, 3, 7, 1
C:  1, 3, 7, 8, 9
D:  1, 3, 8, 9
E:
int main()
{
    raw_pointer_demo();
    shared_pointer_demo();
    std_list_demo();
    std_vector_demo();
}