问题
I am attempting to write a subList method, which returns a list consisting of the current object list inclusively between indexes fromIndex
and toIndex
.
For example, if I had list consisting of
3 5 7 9 11 20 23
and I called subList(0,3)
, I should get a new list of
3 5 7 9
returned.
I am using helper methods to assist in writing the method. My logic in writing this method is that I assign the head node to to be the node at index fromIndex
while assigning the last node in the list to the node at index toIndex
, but nothing gets returned. Any help is appreciated!
EDIT: I am created an add method that that adds nodes to a list. I am still trying to write my own subList method to work.
EDIT2: I have updated some codes, which can be seen at the bottom (disregard older ones above). The fromIndex and toIndex are inclusive in the new sublist.
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();
}
updated code
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;
}
回答1:
Question 1 - why are you doing this? LinkedList would be fine and doesn't need rewriting...
Point 2 (or b) - your sublist function creates a new list, sets its head and then sets a temporary variable to contain the desired tail of the sublist...
In a linked list, if you have a node, then that node represents the remainder of that list from that point onwards. To solve your problem, you would need to clone all the nodes to create your sublist, setting the tail of the last clone to null.
But why do it?
--- EDIT - to clarify the answer
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:
Maybe you already know it, but, have you tried LinkedList.sublist()
? Here you have an example:
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]
*/
Hope it helps.
Clemencio Morales Lucas.
回答3:
Your approach is not correct you have to loop starting from head and return all values if the index in-between fromIndex and toIndex. Before you start you also need to verify that the indexes supplied are valid.
Something on this line
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;
}
In this we check for the fromIndex and toIndex being valid if not then it throws an exception. We loop through the entire list & put in the elements which are only between the indexes supplied.
As per the comment
Yes your Add is also incorrect. What you want to do is set the head node first.
public void add(Node<L> node) {
if(head==null){
head=node;
} else {
getFinal().next = node;
}
}
回答4:
Using java 8 Stream function you can get sublist from any given type of List
if you want specific type of List, instead of List<> then you can cast the return type in the method into that specific type of List
To get the sublist of any type of giving List like ArrayList, LinkedList, ArrayDeque Below method can be used to get sub list of any type
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);
}
}
OUTPUT:
[1, 2, 3, 4, 3, 5]
[1, 2, 3]
来源:https://stackoverflow.com/questions/26383377/linked-list-sublist-method-java