How to implement a Linked List in Java? [duplicate]
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;
}
@Overrid开发者_Go百科e
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!
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);
}
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.
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.
}
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).
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));
}
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;
}
//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;
}
}
}
精彩评论