这个 class 如何以这种方式使用和分配?
How can this class be used and assigned in this manner?
我目前正在尝试理解 linked 列表。
我不理解 SinglyLinkedList.java class 中的某些代码。节点class如何被调用然后赋值,如:private Node first;
我原以为你必须做这样的事情
Node<T> help =new Node<>();
help = first;
如果有人可以解释,或向我提供 link 对我有帮助,将不胜感激。
谢谢!
public class Node<T> {
public T elem;
public Node<T> next;
public Node(T elem) {
this.elem = elem;
next = null;
}
public Node(T elem, Node<T> next) {
this.elem = elem;
this.next = next;
}
@Override
public String toString() {
return "Node{" + "elem=" + elem + '}';
}
}
package list;
/**
*
* @author dcarr
*/
public class SinglyLinkedList<T> implements List<T> {
private Node<T> first;
private Node<T> last;
public SinglyLinkedList() {
first = null;
last = null;
}
@Override
public boolean isEmpty() {
return first == null;
}
@Override
public int size() {
if (isEmpty()){
return 0;
} else {
int size = 1;
Node<T> current = first;
while(current.next != null){
current = current.next;
size++;
}
return size;
}
}
@Override
public T first() {
return first.elem;
}
@Override
public void insert(T elem) {
// if there is nothing in the list
if (isEmpty()){
first = new Node<>(elem);
last = first;
// if the list has elements already
} else {
// the new element will be the next of what was the last element
last.next = new Node<>(elem);
last = last.next;
}
}
@Override
public void remove(T elem) {
if (!isEmpty()){
int index = 0;
Node<T> current = first;
while (current != null && current.elem != elem){
current= current.next;
index++;
}
remove(index);
}
}
@Override
public String toString() {
if (isEmpty()){
return "Empty List";
} else {
String str = first.elem.toString() + " ";
Node<T> current = first;
while(current.next != null){
current = current.next;
str += current.elem.toString() + " ";
}
return str;
}
}
@Override
public void insertAt(int index, T e) {
if (index == 0){
first = new Node<>(e, first);
if (last == null){
last = first;
}
return;
}
Node<T> pred = first;
for (int i = 0; i < index-1; i++) {
pred = pred.next;
}
pred.next = new Node<>(e, pred.next);
System.out.println(pred);
if (pred.next.next == null){
// what does this mean pred.next is?
last = pred.next;
}
}
@Override
public void remove(int index) {
if (index < 0 || index >= size()){
throw new IndexOutOfBoundsException();
} else if (isEmpty()){
return;
}
if (index == 0){
first = first.next;
if (first == null){
last = null;
}
return;
}
Node<T> pred = first;
for (int i = 1; i <= index-1; i++) {
pred = pred.next;
}
// remove pred.next
pred.next = pred.next.next;
if (pred.next == null){
last = pred;
}
}
}
first
字段自动初始化为null
:
private Node<T> first;
我假设会有一些方法可以在末尾添加一个元素,如下所示:
public void add(T element) {
if (first == null) {
first = new Node<T>(element);
last = first;
}
else {
last.next = new Node<>(element);
last = last.next;
}
}
因此,当您创建一个新的 SinglyLinkedList 时:
SinglyLinkedList<String> sillyList = new SinglyLinkedList<>();
first
和 last
字段都包含空引用。
请注意,first
方法此时会引发 NullPointerException。更好的实现是:
@Override
public Optional<T> first() {
if (first != null) {
return Optional.ofNullable(first.elem);
}
else {
return Optional.empty();
}
}
现在如果你添加一个元素:
sillyList.add("Adam");
add
方法中执行的代码为:
first = new Node<>(elem);
last = first;
因此 first
指向一个新的 Node 实例,其中 elem
字段保存值 "Adam"。 last
指向同一个 Node 实例。
这个class中的一些方法我会以不同的方式实现,例如:
@Override
public void remove(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative");
}
else if (index == 0 && first != null) {
first = null;
last = null;
}
else {
Node<T> curr = new Node<>("dummy", first);
int c = 0;
while (curr.next != null) {
if (c == index) {
curr.next = curr.next.next;
if (curr.next == null) {
last = curr;
}
return;
}
curr = curr.next;
c++;
}
throw new IndexOutOfBoundsException(String.valueOf(c));
}
此外,java.util.List 接口中实际上并不存在某些方法,例如 insert、insertAt 和 first。所以这些方法一定不能有@Override注解。
我目前正在尝试理解 linked 列表。
我不理解 SinglyLinkedList.java class 中的某些代码。节点class如何被调用然后赋值,如:private Node first;
我原以为你必须做这样的事情
Node<T> help =new Node<>();
help = first;
如果有人可以解释,或向我提供 link 对我有帮助,将不胜感激。 谢谢!
public class Node<T> {
public T elem;
public Node<T> next;
public Node(T elem) {
this.elem = elem;
next = null;
}
public Node(T elem, Node<T> next) {
this.elem = elem;
this.next = next;
}
@Override
public String toString() {
return "Node{" + "elem=" + elem + '}';
}
}
package list;
/**
*
* @author dcarr
*/
public class SinglyLinkedList<T> implements List<T> {
private Node<T> first;
private Node<T> last;
public SinglyLinkedList() {
first = null;
last = null;
}
@Override
public boolean isEmpty() {
return first == null;
}
@Override
public int size() {
if (isEmpty()){
return 0;
} else {
int size = 1;
Node<T> current = first;
while(current.next != null){
current = current.next;
size++;
}
return size;
}
}
@Override
public T first() {
return first.elem;
}
@Override
public void insert(T elem) {
// if there is nothing in the list
if (isEmpty()){
first = new Node<>(elem);
last = first;
// if the list has elements already
} else {
// the new element will be the next of what was the last element
last.next = new Node<>(elem);
last = last.next;
}
}
@Override
public void remove(T elem) {
if (!isEmpty()){
int index = 0;
Node<T> current = first;
while (current != null && current.elem != elem){
current= current.next;
index++;
}
remove(index);
}
}
@Override
public String toString() {
if (isEmpty()){
return "Empty List";
} else {
String str = first.elem.toString() + " ";
Node<T> current = first;
while(current.next != null){
current = current.next;
str += current.elem.toString() + " ";
}
return str;
}
}
@Override
public void insertAt(int index, T e) {
if (index == 0){
first = new Node<>(e, first);
if (last == null){
last = first;
}
return;
}
Node<T> pred = first;
for (int i = 0; i < index-1; i++) {
pred = pred.next;
}
pred.next = new Node<>(e, pred.next);
System.out.println(pred);
if (pred.next.next == null){
// what does this mean pred.next is?
last = pred.next;
}
}
@Override
public void remove(int index) {
if (index < 0 || index >= size()){
throw new IndexOutOfBoundsException();
} else if (isEmpty()){
return;
}
if (index == 0){
first = first.next;
if (first == null){
last = null;
}
return;
}
Node<T> pred = first;
for (int i = 1; i <= index-1; i++) {
pred = pred.next;
}
// remove pred.next
pred.next = pred.next.next;
if (pred.next == null){
last = pred;
}
}
}
first
字段自动初始化为null
:
private Node<T> first;
我假设会有一些方法可以在末尾添加一个元素,如下所示:
public void add(T element) {
if (first == null) {
first = new Node<T>(element);
last = first;
}
else {
last.next = new Node<>(element);
last = last.next;
}
}
因此,当您创建一个新的 SinglyLinkedList 时:
SinglyLinkedList<String> sillyList = new SinglyLinkedList<>();
first
和 last
字段都包含空引用。
请注意,first
方法此时会引发 NullPointerException。更好的实现是:
@Override
public Optional<T> first() {
if (first != null) {
return Optional.ofNullable(first.elem);
}
else {
return Optional.empty();
}
}
现在如果你添加一个元素:
sillyList.add("Adam");
add
方法中执行的代码为:
first = new Node<>(elem);
last = first;
因此 first
指向一个新的 Node 实例,其中 elem
字段保存值 "Adam"。 last
指向同一个 Node 实例。
这个class中的一些方法我会以不同的方式实现,例如:
@Override
public void remove(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative");
}
else if (index == 0 && first != null) {
first = null;
last = null;
}
else {
Node<T> curr = new Node<>("dummy", first);
int c = 0;
while (curr.next != null) {
if (c == index) {
curr.next = curr.next.next;
if (curr.next == null) {
last = curr;
}
return;
}
curr = curr.next;
c++;
}
throw new IndexOutOfBoundsException(String.valueOf(c));
}
此外,java.util.List 接口中实际上并不存在某些方法,例如 insert、insertAt 和 first。所以这些方法一定不能有@Override注解。