我正在尝试在Java中实现一个简单的HashTable,它使用链接列表进行冲突解决,这在C中很容易做到,但我不知道如何用Java做,因为你不能使用指针...
首先,我知道这些结构已经用Java实现了,我不打算使用它,只是在这里训练......
所以我创建了一个元素,它是一个字符串和指向下一个元素的指针:
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 + "] => ";
}
}
当然,我的HashTable有一个Element数组来存储数据:
public class CustomHashTable {
private Element[] data;
这是我的问题:
例如,我想实现一个方法,在链接列表的末尾添加一个元素(我知道在列表的开头插入元素会更简单,更有效,但同样,这只是用于培训目的)。没有指针我该怎么做?
这是我的代码(如果e是一个指针,它可以工作......):
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);
}
谢谢!
答案 0 :(得分:5)
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);
}
答案 1 :(得分:1)
如果你想自己编写,首先让它实现java.util.List接口。
如果可以使用库类,请使用java.util.LinkedList。
现在我已经向你指出你正在“练习”,所以根据一些人的说法,一些好的建议可能会超出限制,但是你应该注意泛型。我建议你阅读它们并将它们构建到你的Element(Node?)和List实现中。仿制药就是以这种方式诞生的。我从这里开始:
package list;
public class Node<T>
{
private T value;
private Node<T> prev;
private Node<T> next;
// You add the rest.
}
答案 2 :(得分:1)
为了您的目的,Java的引用与C的指针的使用方式不同。事实上,C中的主要问题(或好处,取决于你提出的问题)指针并不是说他们可以指向某事,而是你可以用它们做数学。
仅作为指点,你可以在这里做同样的事情:
e.setNext(new Element(s));
而不是
e = new Element(s);
(这只会让变量e
指向一个新元素,但不会改变旧元素上的任何内容。)
你已经完成了。
答案 3 :(得分:0)
在方法结束时重新分配局部变量不会改变任何东西。你需要这样的东西:
Element e = this.data[index];
while (e.getNext() != null) {
e = e.getNext();
}
然后e
引用列表末尾的元素。创建一个新元素,并将其设置为下一个元素:
Element newElement = new Element(s);
e.setNext(newElement);
为了提高效率,我建议您考虑双链接节点和一个知道列表的头和尾的列表类型。区分整个列表(它知道头部,尾部,可能是计数),以及列表中的一个节点(它知道它所属的下一个,前一个,可能是哪个列表)。
答案 4 :(得分:0)
递归解决方案:
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));
}
答案 5 :(得分:0)
java中的LinkedList就像那样:
有一个像这样的静态类:
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构造函数:
public LinkedList() {
header.next = header.previous = header;
}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
addAll方法:
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
你应该在这里查看:
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;
}
答案 6 :(得分:0)
//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;
}
}
}