【问题标题】:linked list sublist method-java链表子列表方法-java
【发布时间】:2014-10-15 13:05:27
【问题描述】:

我正在尝试编写一个 subList 方法,该方法返回一个包含当前对象列表的列表,包括索引 fromIndextoIndex 之间。

例如,如果我的列表包含

3 5 7 9 11 20 23

我打电话给subList(0,3),我应该得到一个新的列表

3 5 7 9

返回。

我正在使用辅助方法来协助编写方法。我编写此方法的逻辑是,我将头节点分配为索引fromIndex 处的节点,同时将列表中的最后一个节点分配给索引toIndex 处的节点,但没有返回任何内容。任何帮助表示赞赏!

编辑:我创建了一个将节点添加到列表的添加方法。我仍在尝试编写自己的 subList 方法来工作。

EDIT2:我更新了一些代码,可以在底部看到(忽略上面的旧代码)。 fromIndex 和 toIndex 包含在新的子列表中。

private class Node<N extends Comparable<N>> {
    private N data;
    private Node<N> next;
}

private Node<L> head;

public List() {
    head=null;
}   

public void add(Node<L> node) {
        Node<L> add = new Node<L>();
        add.data = node.data;
        add.next = null;
        getFinal().next = add;
    } 

public Node<L> getFinal(){
    Node<L> node = head;
    while (node.next != null) {
        node = node.next;
    }
    return node;
}

public int size() {
    if (head == null) return 0;
    int counter = 0;
    for (Node<L> curr = head; curr != null; curr = curr.next)
        counter++;
    return counter;
}

public List<L> subList(int fromIndex, int toIndex)
            throws IndexOutOfBoundsException {
        List<L> n=new List<L>();
        Node<L> tail= new Node<L>();
        n.head=nthItem(fromIndex);
        tail=n.getFinal();
        tail=nthItem(toIndex);
        return n;
    }

public Node<L> nthItem(int index) {
    if (index < 0 || index >= size()) 
        throw new IndexOutOfBoundsException();

    Node<L> ptr = head;

    int i = 0;
    while (ptr != null) {
        if (i == index) return ptr;
        i++;
        ptr = ptr.next;
    }

    throw new IndexOutOfBoundsException();
}

更新代码

private void add(Node<L> node) {
        if(head==null){
            head=node;
        } else {
            getFinal().next = node;
        }
    }

public List<L> subList(int fromIndex, int toIndex)
        throws IndexOutOfBoundsException {
    if(fromIndex<0 || fromIndex>size()-1 || toIndex<0 || toIndex>size()-1){ //size() is 1 bigger than max index so I subtract 1 from size() to equal them out
         throw new IndexOutOfBoundsException();
    }

    List<L> n=new List<L>();
    Node<L> startNode = head;
    int counter=0;
    while(startNode!=null){
         if(counter>=fromIndex && counter<=toIndex){ //fromIndex and toIndex are inclusive so I've added the equals to them. However, it enters an infinite loop, which I do not understand why.
              n.add(startNode);
         }
         startNode=startNode.next;
         counter++;
    }
    return n;
}

【问题讨论】:

    标签: java linked-list nodes sublist


    【解决方案1】:

    问题 1 - 你为什么要这样做? LinkedList 就可以了,不需要重写...

    第 2 点(或 b)- 您的子列表函数创建一个新列表,设置其头部,然后设置一个临时变量以包含子列表的所需尾部...

    在链表中,如果您有一个节点,则该节点表示从该点开始的该列表的其余部分。要解决您的问题,您需要克隆所有节点以创建子列表,将最后一个克隆的尾部设置为 null。

    但是为什么要这样做呢?

    --- 编辑 - 澄清答案

    public List<L> subList(int fromIndex, int toIndex) {
        Node<L> currentInOriginal = nthItem(fromIndex);
    
        int count = (toIndex - fromIndex) + 1;
    
        List<L> newSubList = new List<L>();
        newSubList.head = new Node<L>(current.data);
    
        Node<L> lastItemInList = newSubList.head;
        int soFar = 1;
    
        currentInOriginal = currentInOriginal.next;
        while(currentInOriginal!=null && soFar<count) {
            lastItemInList.next = new Node<L>(currentInOriginal.data);
            listItemInList = lastItemInList.next;
    
            currentInOriginal=currentInOriginal.next;
            soFar++;
        }
    
        return newSubList;
    }
    

    【讨论】:

      【解决方案2】:

      也许你已经知道了,但是,你试过LinkedList.sublist()吗?这里有一个例子:

      import java.util.LinkedList;
      import java.util.List;
      
      public class GetSubListLinkedListJavaExample {
      
        public static void main(String[] args) {
      
          //create LinkedList object
          LinkedList lList = new LinkedList();
      
          //add elements to LinkedList
          lList.add("1");
          lList.add("2");
          lList.add("3");
          lList.add("4");
          lList.add("5");
      
          System.out.println("LinkedList contains : " + lList);
      
          /*
           * To get a sublist from Java LinkedList, use
           * List subList(int start, int end) method.
           *
           * This method returns portion of list containing element from start index
           * inclusive to end index exclusive.
           */
      
          List lst = lList.subList(1,4);
          System.out.println("Sublist contains : " + lst);
      
          /*
           * Please note that sublist is backed by the original list, so any changes
           * made to sublist will also be reflected back to original LinkedList
           */
      
           //remove element from sublist
           lst.remove(2);
           System.out.println("Sublist now contains : " + lst);
           System.out.println("Original LinkedList now contains : " + lList);
        }
      }
      
      /*
      Output would be
      LinkedList contains : [1, 2, 3, 4, 5]
      Sublist contains : [2, 3, 4]
      Sublist now contains : [2, 3]
      Original LinkedList now contains : [1, 2, 3, 5]
      */
      

      希望对你有帮助。

      克莱门西奥·莫拉莱斯·卢卡斯。

      【讨论】:

      • 这不是 OP 明确表示他们正在编写自己的实现的答案。
      • 我看不到你说什么。我清楚地写了“也许你已经知道了”。有时您正在编写一个方法,并且在查看 API 后发现它已经存在。
      • 虽然实际使用 Java API 会更好,但这看起来像是一个家庭作业,所以我想 Mob Barley 想要更多关于链表如何使用的信息,而不是使用哪个。
      【解决方案3】:

      您的方法不正确,您必须从头开始循环,如果索引介于 fromIndex 和 toIndex 之间,则返回所有值。在开始之前,您还需要验证提供的索引是否有效。

      这条线上的东西

      public List<L> subList(int fromIndex, int toIndex)
              throws IndexOutOfBoundsException {
          if(fromIndex<0 || fromIndex>size() || toIndex<fromIndex || toIndex>size()){
               throw new IndexOutOfBoundsException();
          }
      
          List<L> n=new List<L>();
          Node<L> startNode = head;
          int counter=0;
          while(startNode!=null){
               if(counter>fromIndex && counter<toIndex){
                    n.add(startNode);
               }
               startNode=startNode.next;
               counter++;
          }
          return n;
      }
      

      在此我们检查 fromIndex 和 toIndex 是否有效,如果无效则抛出异常。 我们遍历整个列表并放入仅在提供的索引之间的元素。


      根据评论

      是的,您的 Add 也不正确。 你要做的是先设置头节点。

      public void add(Node<L> node) {
          if(head==null){
             head=node;
          } else {
            getFinal().next = node;
          }
      } 
      

      【讨论】:

      • 我查看了您的建议并最终编写了自己的 add 方法。我不确定为什么它仍然不起作用......虽然我想首先你能告诉我为什么我的 add 方法是错误的(我认为是原因)?
      • @MobBarley 请检查编辑。你的头也不对
      • @MobBarley“最终编写了我自己的 add 方法”听起来更像是为您提供了 add 方法作为分配的一部分,并且需要针对该方法编写代码。如果是这样,最好不要修改它,除非它完全损坏。
      • @wrongAnswer 我已经修复了 add 方法。这只是练习,所以事先没有给我任何书面方法。我已经尝试了你给我的 while 循环,调整了一些东西以适应我得到的东西(toIndex 和 fromIndex 是包容性的,所以我添加了等于,而不仅仅是小于或大于),但现在我' m 进入一个等于的无限循环。我不明白为什么会发生这种情况,因为代码看起来确实“很好”......
      • @MobBarley 不看你的代码,它是在黑暗中拍摄的。你有没有把 && 改成 || ?如果你分享你的代码,我可以看看它。请编辑问题。不要将代码作为评论发布。
      【解决方案4】:

      使用 java 8 Stream 函数,您可以从任何给定类型的列表中获取子列表

      如果您想要特定类型的 List,而不是 List,那么您可以将方法中的返回类型转换为特定类型的 List

      获取任何类型的给定列表的子列表,如 ArrayList、LinkedList、ArrayDeque 以下方法可用于获取任何类型的子列表

      package com.techsqually.datastructure.collections.lists.linkedlist;
      
      import java.util.LinkedList;
      import java.util.List;
      import java.util.stream.Collectors;
      
      public class LinkedListTest {
      
      
          public static void main(String[] args) {
      
              LinkedList<Integer> giveString = new LinkedList<>();
              giveString.add(1);
              giveString.add(2);
              giveString.add(3);
              giveString.add(4);
              giveString.add(3);
              giveString.add(5);
      
              System.out.println(giveString);
              System.out.println(getSubList(giveString,0,3));
          }
      
          public static List getSubList(LinkedList<Integer> givenList, int startIndexInclusive, int endIndexExclusive){
      
              return givenList.stream().collect(Collectors.toList()).subList(startIndexInclusive,endIndexExclusive);
          }
      }
      

      输出:

      [1, 2, 3, 4, 3, 5]

      [1, 2, 3]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-03
        • 2013-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-16
        • 1970-01-01
        相关资源
        最近更新 更多