java实现中的单链表
我被分配了一个任务来在Java中实现以下方法:如果列表S是列表L的子列表,则SubList(S,L)返回true 当我将列表作为递归关系中的抽象对象进行处理时,需要使用以下符号。给定一个列表L,我们写L=[H | R],其中H是列表的头,R是列表的其余部分。对于空列表L,我们写L=[]。例如,如果L=[1,2,3,4,5],H=1,R=[2,3,4,5] 因此,我的任务是: a) 使用上述列表表示法提供子列表(S,L)的重复关系 b) 利用递归关系在Java中实现递归算法 在这项任务上已经坚持了一天半了,但仍然很难做到这一点。如果有人能帮我解决这个问题,我将不胜感激 这是提供给我使用的java代码java实现中的单链表,java,linked-list,singly-linked-list,recurrence,Java,Linked List,Singly Linked List,Recurrence,我被分配了一个任务来在Java中实现以下方法:如果列表S是列表L的子列表,则SubList(S,L)返回true 当我将列表作为递归关系中的抽象对象进行处理时,需要使用以下符号。给定一个列表L,我们写L=[H | R],其中H是列表的头,R是列表的其余部分。对于空列表L,我们写L=[]。例如,如果L=[1,2,3,4,5],H=1,R=[2,3,4,5] 因此,我的任务是: a) 使用上述列表表示法提供子列表(S,L)的重复关系 b) 利用递归关系在Java中实现递归算法 在这项任务上已经坚持了
class SLLNode {
public Object info; // This is the data
public SLLNode next; // this is the address of the next node
public SLLNode() { // Here's how we construct an empty list.
next = null;
}
public SLLNode(Object el) {
info = el; next = null;
}
public SLLNode(Object el, SLLNode ptr) {
info = el; next = ptr;
}
}
class SLList {
protected SLLNode head = null;
public SLList() {
}
public void setToNull() {
head = null;
}
public boolean isEmpty() {
return head == null;
}
public Object first() {
return head.info;
}
public SLLNode head() {
return head;
}
public void printAll() {
for (SLLNode tmp = head; tmp != null; tmp = tmp.next)
System.out.print(tmp.info.toString());
}
public void add(Object el) {
head= new SLLNode(el,head);
}
public Object find(Object el) {
SLLNode tmp = head;
for ( ; tmp != null && !el.equals(tmp.info); tmp = tmp.next);
if (tmp == null)
return null;
else return tmp.info;
}
public boolean member(Object el) {
SLLNode tmp = head;
for ( ; tmp != null && !el.equals(tmp.info); tmp = tmp.next);
if (tmp == null)
return false;
else return true;
}
public Object deleteHead() { // remove the head and return its info;
Object el = head.info;
head = head.next;
return el;
}
public void delete(Object el) { // find and remove el;
if (head != null) // if non-empty list;
if (el.equals(head.info)) // if head needs to be removed;
head = head.next;
else {
SLLNode pred = head, tmp = head.next;
for ( ; tmp != null && !(tmp.info.equals(el));
pred = pred.next, tmp = tmp.next);
if (tmp != null) // if found
pred.next = tmp.next;
}
}
}
在英语中,这意味着如果L包含子列表S的第一个元素,并且它包含子列表的其余元素,那么子列表方法将返回true
这里的递归显示在第4行和第5行,您可以看到我们一次又一次地调用同一个函数,直到SR只包含一个元素
例:
可能的Java实现:
public SLList(SLNode h) {
this.head = h;
}
public SLList singletonList(SLNode n) {
return new SLList(new SLNode(n.info));
}
public SLList remainingList(SLNode n) {
if(n == null) return new SLList();
return new SLList(n);
}
private static boolean subList(SLList s, SLList l) {
if(s.isEmpty()) return true;
if(l.isEmpty()) return false;
if(s.head.next == null && l.first().equals(s.first())) return true;
return (subList(singletonList(s.head), singletonList(l.head)) ||
subList(singletonList(s.head), remainingList(l.head.next))) &&
subList(remainingList(s.head.next), l);
}
我还没有测试代码,可能缺少一些空检查,但重要的是您了解了递归的工作原理。可能的重复应该更新,而不是创建重复。提示:定义一个
startsWith
关系,然后将其用于每个可能的起始位置。很抱歉出现重复,我不知道如何更新我的旧版本,因为我在我的问题上找不到。非常抱歉。另外,我在这个问题上还没有得到任何帮助。谢谢你的帮助,比我的prac老师解释得更好。我试图实现递归,但似乎无法实现它。我现在的代码看起来很可怕。我不想问,但你能告诉我如何实现它吗?我不太擅长实施这个计划,但我懂理论。非常感谢,谢谢。
L = [1,2,5]
S = [1,5]
SubList(S, L) = SubList([1,5], [1,2,5])
= SubList(1|[5], 1|[2,5]) (4+5)
= SubList(1|[], 1|[2,5]) AND SubList([5], 1|[2,5])
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR SubList(5|[], [2,5]))
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR (SubList(5|[], 2|[]) OR SubList(5|[], [5])))
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR (SubList(5|[], 2|[]) OR SubList(5|[], 5|[])))
= true AND (false OR (false OR true))
= true AND true
= true
public SLList(SLNode h) {
this.head = h;
}
public SLList singletonList(SLNode n) {
return new SLList(new SLNode(n.info));
}
public SLList remainingList(SLNode n) {
if(n == null) return new SLList();
return new SLList(n);
}
private static boolean subList(SLList s, SLList l) {
if(s.isEmpty()) return true;
if(l.isEmpty()) return false;
if(s.head.next == null && l.first().equals(s.first())) return true;
return (subList(singletonList(s.head), singletonList(l.head)) ||
subList(singletonList(s.head), remainingList(l.head.next))) &&
subList(remainingList(s.head.next), l);
}