0

I have created a class SLList where I'm going to take a doubly linked list SLlist and I'm trying to find how to add a new node of any type to the start of that doubly linked list.

In order to do this, I have made some sentinels firstsen and lastsen since I was told that this approach would be a lot better to do.

Now, as said earlier, I'm trying to add a new node to the start of that doubly linked list using a function public void addFirst(T) {}.

Here is my code so far...

public class SLList{
    private class IntNode<T> {
        private int data;
        private IntNode previous;
        private IntNode next;

        public IntNode (int data, IntNode previous, IntNode next) {
            this.data = data;
            this.previous = previous;
            this.next = next;

        }
    }
    IntNode firstsen;
    IntNode Lastsen;
    public SLList(){
        firstsen = new IntNode(0,null,null );
        Lastsen = new IntNode(0, firstsen, null);
        firstsen.next = Lastsen;


    }
    public void addFirst(T) {}


}

However, I'm stumped on what I have to do next because I'm new to object oriented programming, so if anyone would be willing to help, that would be really helpful.

Furthermore, I would also appreciate if anyone could explain how to edit my code to accept any generic type

Thank you, Dave

Nutnicha
  • 335
  • 1
  • 10
  • For generics make `SLList` generic too and use the type for the nodes, e.g. `SLList` + `Node firstsen` etc.. Note that I changed `IntNode` to `Node` because your node only takes an `int` instead of the generic type `T`. For `Node` also use `private T data`. – Thomas Oct 04 '22 at 08:09
  • For adding a node at the start think about how a doubly linked list works: `firstsen` refers to the first node, `lastsen` to the last. Assuming the list is empty just point both to the new node. If there already is a node then you need to do the following: 1) make a temporary reference to the first node in your method, 2) replace `firstsen` with the new node, 3) change the new node's `next` to refer to the "old first" node using the reference from step 1. 4) change the "old first" node's `previous` to refer to the new node. – Thomas Oct 04 '22 at 08:11
  • I think the problem I have is implementing the code. I'm not sure what to put in for sentinels. My guess would be firstsen.next = data; firstsen.previous = T. I doubt that I'm correct so, can you please explain how to implement it? Thank you – Nutnicha Oct 04 '22 at 08:30
  • 1
    *"I'm trying to add a new node"*: I don't see any trace of an attempt, yet there are so many Q&A on this site (let alone on the internet) about adding nodes to linked lists, that it feels like you should first look at those and start writing code accordingly... – trincot Oct 04 '22 at 08:49

1 Answers1

1

Make SLList generic as SLList<T>, and replace any occurrence of int with T.

When using the sentinel pattern in a doubly linked list, realise that you only need one sentinel node, which will serve for marking both the end end the beginning of the list. It starts out as a self-referencing node. For this purpose it would be elegant to provide a constructor without arguments.

In addFirst you obviously create a node instance. In total 4 node references need to get initialised when inserting a new node. Two of those are set by the IntNode constructor (these are references from the new node to its neighbors), and two more references need to be set in already existing nodes (these are references to the new node from its neighbors).

The new node reference thus gets assigned to sentinel.next and to node.next.previous (where node is the new instance).

Here is how that would look:

public class SLList<T>{ // Add Generics here
    private class IntNode {
        private T data;
        private IntNode previous;
        private IntNode next;

        public IntNode (T data, IntNode previous, IntNode next) {
            this.data = data;
            this.previous = previous;
            this.next = next;
        }
        
        public IntNode () { // Self-referencing node
            next = previous = this;
        }
    }
    
    IntNode sentinel; // One sentinel can serve both purposes

    public SLList(){
        sentinel = new IntNode(); // Self referencing previous/next
    }

    public void addFirst(T data) {
        IntNode node = new IntNode(data, sentinel, sentinel.next);
        sentinel.next = node;
        node.next.previous = node;
    }

    public void addLast(T data) {
        IntNode node = new IntNode(data, sentinel.previous, sentinel);
        sentinel.previous = node;
        node.previous.next = node;
    }
}
trincot
  • 317,000
  • 35
  • 244
  • 286
  • can you please explain the purpose of the self referencing nodes and also how did you declare node in sentinel.next = node? – Nutnicha Oct 04 '22 at 10:12
  • Because this uses just one sentinel, the node *after* that sentinel is the sentinel itself (the list is empty). So it needs to be self-referencing. In `addFirst`, the variable `node` is declared on the line just above `sentinel.next = node`. It is a node instance that holds the data that you want to insert. – trincot Oct 04 '22 at 11:44
  • so if I want to create another function, for instance addLast, where I will add to the end of the list, do I have to create another self referencing node? – Nutnicha Oct 04 '22 at 12:58
  • No, you use the same sentinel node, but then insert the node *before* the sentinel instead of *after* it. I added the code for it to my answer. – trincot Oct 04 '22 at 12:59
  • Actually, can u pls explain what this does, so that I can be able to do this myself later on sentinel.previous = node; node.previous.next = node; – Nutnicha Oct 04 '22 at 13:03
  • 1
    It establishes the two links from the two neighbors towards the new node. The new node is inserted between `sentinel.previous` and `sentinel` (see the arguments passed to the `IntNode` constructor), so the neighbor *after* the new node is `sentinel`. So `sentinel` needs its `previous` reference to refer to the new node, so `sentinel.previous = node`. A similar reasoning (but for the other neighbor) explains the other assignment. – trincot Oct 04 '22 at 13:56