我有这个抽象类我实现,其中所有实现的函数必须使用递归完成:
public abstract class List<E> implements Iterable<E> {
protected class Node<T> {
protected Node(T data) {
this.data = data;
}
protected T data;
protected Node<T> next;
}
public abstract void insert(E data);
public abstract void remove(E data);
public abstract E retrieve(int index);
public abstract boolean search(E data);
protected Node<E> head;
}
以下是我目前的实施情况。我相信我已经正确地完成了搜索和检索方法,并且大部分的删除方法都是正确的。我担心的一个问题是我使用insert方法的错误(我不是特别需要工作代码,但可能是一个伪代码,就像解释当抽象类只接受数据参数时如何插入,导致需要一个私人课程)。另一个问题是在remove方法的这种情况下:
if (key.compareTo(temp.data) == 0){
}
由于只能访问当前节点和下一个节点,因此我不确定如何删除头节点。任何帮助将不胜感激!
import java.util.Iterator;
import java.util.Random;
public class SortedList<E extends Comparable<? super E>> extends List<E> {
public static void main(String[] args) {
Random rand = new Random(1);
SortedList<Integer> list = new SortedList<Integer>();
list.insert(1);
System.out.println(list.search(1));
}
public Iterator<E> iterator() {
return new Iterator<E>() {
public boolean hasNext() {
return curr != null;
}
public E next() {
E temp = curr.data;
curr = curr.next;
return temp;
}
public void remove() {
throw new UnsupportedOperationException();
}
private Node<E> curr = (Node<E>)head;
};
}
public void insert(E data) {
Node<E> temp = new Node<E>(data);
Node<E> curr = head;
if (head == null || data.compareTo(head.data) < 0) {
temp.next = head;
head = temp;
}
insert(curr, data);
}
private void insert(Node<E> curr, E data){
if (curr.next == null) {
curr.next.data = data;
} else {
curr.next.insert(curr, data);
}
}
public void remove(E data) {
Node<E> curr = head;
remove(curr, data);
}
private void remove(Node<E> temp, E key){
if (temp == null){
return;
}
if (key.compareTo(temp.data) == 0){
}
if (key.compareTo(temp.next.data) == 0){
temp.next = temp.next.next;
return;
}
if (key.compareTo(temp.next.data) < 0){
remove(temp.next, key);
}
}
public E retrieve(int index)
{
Node<E> curr = head;
int counter = 0;
return retrieve(curr, index, counter);
}
private E retrieve(Node<E> temp, int idx, int c)
{
if (idx == c){
return temp.data;
}
return retrieve(temp.next, idx, c++);
}
public boolean search(E data)
{
Node<E> curr = head;
return search(curr, data);
}
private boolean search(Node<E> temp, E key)
{
if (temp == null){
return false;
}
if (key.compareTo(temp.data) == 0){
return true;
}
if (key.compareTo(temp.data) < 0){
return search(temp.next, key);
}
return false;
}
}
答案 0 :(得分:1)
从脑袋中移除:
由于你知道你的列表应该总是被排序,如果你删除(当前)头部值,那么下一个头应该是&#34; next&#34;排队。您最初只能访问&#34; head&#34;节点,必须逐个向下移动列表。
所以在这种情况下,假设你有一群人按名字顺序排队等候。如果他们全部牵手并按顺序与下一个人形成链条,那么你就会排除第一个人。你可以逻辑地假设握着他们的人是新的头。
Node<E> temp = new Node<E>(data);
if(check to see if you want to remove head){
temp.next = head.next; //current head points to next in line so so shall new head(temp);
head = temp; //head ref variable points to only new head and old one is inaccessible and will be cleared out during garbage collection.
}
在中间插入和移除:
使用与先前牵手相同的类比。如果我需要&#34;插入&#34;一个人在两个人的中间,我首先必须找到他们所属的地方,然后让他们与他们之前和之后的人联系。#34; current&#34; &#34; next&#34;。
对于插入代码,您必须搜索,直到找到正确的插入位置(可以位于两个节点之间),而不是假设您只是在下一个值为空时插入。
private void insert(Node<E> curr, E data){
if (curr.next == null) {
curr.next.data = data; //only inserts if next value is null
} else { // what about inserting 3, into a list of {1,5}.
curr.next.insert(curr, data);
}
}
您想要检查排序顺序中的当前值和下一个值是否正确。
else if(curr.data <= data && curr.next.data > data){
// you've found the nodes you want to insert in between
}else{
... keep searching until you hit a null
}