How to implement a Linked List in Java? [duplicate]

青春壹個敷衍的年華 提交于 2019-12-12 07:24:17

问题


I am trying to implement a simple HashTable in Java that uses a Linked List for collision resolution, which is pretty easy to do in C, but I don't know how to do it in Java, as you can't use pointers...

First, I know that those structures are already implemented in Java, I'm not planning on using it, just training here...

So I created an element, which is a string and a pointer to the next Element:

public class Element{
        private String s;
        private Element next;

        public Element(String s){
            this.s = s;
            this.next = null;
        }

        public void setNext(Element e){
            this.next = e;
        }

        public String getString(){
            return this.s;
        }

        public Element getNext(){
            return this.next;
        }

        @Override
        public String toString() {
            return "[" + s + "] => ";
        }
    }

Of course, my HashTable has an array of Element to stock the data:

public class CustomHashTable {
    private Element[] data;

Here is my problem:

For example I want to implement a method that adds an element AT THE END of the linked List (I know it would have been simpler and more efficient to insert the element at the beginning of the list, but again, this is only for training purposes). How do I do that without pointer?

Here is my code (which could work if e was a pointer...):

public void add(String s){
        int index = hash(s) % data.length;
        System.out.println("Adding at index: " + index);
        Element e = this.data[index];
        while(e != null){
            e = e.getNext();
        }
        e = new Element(s);
    }

Thanks!


回答1:


public void add(String s){
    int index = hash(s) % data.length;
    System.out.println("Adding at index: " + index);
    Element curr = new Element(s);
    Element e = this.data[index];
    if (e == null) {
       this.data[index] = curr;
       return;
    }
    while(e.getNext() != null){
        e = e.getNext();
    }
    e.setNext(curr);
}



回答2:


For your purposes here Java's references are not used differently from C's pointers. In fact, the major problem (or benefit, depending on who you ask) pointers have in C is not that they can point to something, but that you can do math with them.

For just the pointing purposes, you can do the same here:

e.setNext(new Element(s));

instead of

e = new Element(s);

(which would just let the variable e point to a new element, but won't change anything on the old ones).

and you're done.




回答3:


If you want to write your own, start by having it implement the java.util.List interface.

If you can use a library class, use the java.util.LinkedList.

Now it's been pointed out to me that you're "practicing", so some good advice might be off limits according to some, but you should be aware of generics. I'd recommend reading up on them and building them into your Element (Node?) and List implementations. Generics were born for use with collections in just this way. I'd start here:

package list;

public class Node<T>
{
    private T value;
    private Node<T> prev;
    private Node<T> next;
    // You add the rest.
}



回答4:


Reassigning a local variable at the end of a method isn't going to change anything. You need something like:

Element e = this.data[index];
while (e.getNext() != null) {
    e = e.getNext();
}

Then e refers to the element at the end of the list. Create a new element, and set that as the next one:

Element newElement = new Element(s);
e.setNext(newElement);

For efficiency, I'd urge you to consider doubly-linked nodes and a list type which knows about the head and tail of the list. Differentiate between the list as a whole (which knows the head, the tail, and probably the count), and a node within the list (which knows about the next, previous, and possibly what list it belongs to).




回答5:


A recursive solution:

public class Element{
  /* ... */
  public void addTail(Element e){
    if (next == null)
      next = e; //we are at the end, add it
    else
      next.addTail(e);//let the next node take responsibility
  }
}

public void add(String s){

  int index = hash(s) % data.length;
  System.out.println("Adding at index: " + index);
  Element e = this.data[index];
  e.addTail(new Element(s));
}



回答6:


LinkedList in java works as like that:

There is a static class like this:

private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;
Entry(E element, Entry<E> next, Entry<E> previous) {
    this.element = element;
    this.next = next;
    this.previous = previous;
}
}

LinkedList constructors:

public LinkedList() {
    header.next = header.previous = header;
}

public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}

addAll method:

public boolean addAll(Collection<? extends E> c) {
    return addAll(size, c);
}

You should check here:

private transient Entry<E> header = new Entry<E>(null, null, null);
private transient int size = 0;

private Entry<E> addBefore(E e, Entry<E> entry) {
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}

private E remove(Entry<E> e) {
if (e == header)
    throw new NoSuchElementException();

    E result = e.element;
e.previous.next = e.next;
e.next.previous = e.previous;
    e.next = e.previous = null;
    e.element = null;
size--;
modCount++;
    return result;
}

private Entry<E> addBefore(E e, Entry<E> entry) {
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}

public boolean add(E e) {
addBefore(e, header);
    return true;
}



回答7:


//Single linked list implementation

public class Nodes {

    int data;
    Nodes next = null;

    public Nodes(int data) {
        this.data = data;
    }
}


public class Lists {

    static Nodes first = null;

    public static void insertBegin(int data) {
        Nodes temp = new Nodes(data);
        if(first == null) {
            first = temp;
        }
        else {
            temp.next = first;
            first = temp;           
        }
    }

    public static void insertEnd(int data) {
        Nodes temp = new Nodes(data);
        if(first == null) {
            first = temp;
        }
        else{
            Nodes n = first;
            while(n.next != null) {
                n = n.next;
            }
            n.next = temp;
        }
    }

    public static void insertPos(int pos, int data) {
        Nodes temp = new Nodes(data);
        if(first == null) {
            System.out.println("List empty. Cannot insert");
        }
        else {
            Nodes n = first;
            while(n.data != pos && n.next != null) {
                n = n.next;
            }
            if(n.data != pos){
                System.out.println("Position not found");
            }
            else {
                temp.next = n.next;
                n.next = temp;
            }
        }
    }

    public static void deleteBegin() {
        if(first == null) {
            System.out.println("List empty. Cannot delete");
        }
        else {
            first = first.next;
        }       
    }


    public static void deleteEnd() {
        if(first == null) {
            System.out.println("List empty. Cannot delete");
        }
        else {
            Nodes n = first;
            while(n.next.next != null) {
                n = n.next;
            }
            n.next = n.next.next;
        }
    }

    public static void deletePos(int pos) {
        if(first == null) {
            System.out.println("List empty. Cannot delete");
        }
        else {
            Nodes n = first;
            while(n.next.data != pos && n.next.next != null) {
                n = n.next;
            }
            if(n.next.data != pos) {
                System.out.println("Element not found. Deletion failed");
            }
            else{
                n.next = n.next.next;
            }
        }
    }

    public static void printAll() {
        System.out.println("Elements in link list");
        Nodes n = first;
        while(n != null) {
            System.out.print(n.data + "->");
            n = n.next;
        }
    }
}


来源:https://stackoverflow.com/questions/4670631/how-to-implement-a-linked-list-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!