在java实现中单独链接列表

时间:2016-03-27 11:14:00

标签: 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)使用上面的列表符号为SubList(S,L)提供递归关系。

b)使用递归关系在Java中实现递归算法。

现在被困在这项任务上一天半,但仍然无法做到这一点。感谢,如果有人能帮我解决这个问题。

这是我用过的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;
             }
    }

}

1 个答案:

答案 0 :(得分:0)

SubList([], L)      = true (1)
SubList(H|[], H|*)  = true (2)
SubList(H|[], [])   = false (3)
SubList(SH|[], H|R) = SubList(SH|[], H|[]) OR SubList(SH|[], R) (4)
SubList(SH|SR, L)   = SubList(SH|[], L) AND SubList(SR, L) (5)

在英语中,这意味着如果L包含子列表S的第一个元素并且它包含子列表的其余元素,那么您的SubList方法将返回true。

此处的递归在第4行和第5行可见,您可以看到我们一次又一次地调用相同的函数,直到SR只包含一个元素。

例如:

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

可能的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);
}

我还没有对代码进行测试,可能会遗漏一些空检查,但重要的是你可以了解递归是如何工作的。