排序链表实现

时间:2011-10-24 20:27:11

标签: java

我是一名新手程序员,具体来说,我正在学习java编程,我应该实现sortedLinkedList类,它从Java库扩展LinkedList类。该列表必须按姓氏的升序存储人员。我已经编写了实现Comparable接口的Person类。我的问题是,我一直在努力实现这个sortedLinkedClass,但无济于事。我的代码运行没有任何编译或运行时错误,但程序不打印任何东西。另一件事你可以看到,我用Integers而不是Persons测试它,当它试图添加一个已经在列表中的数字时它会抛出NullPointerException。我的代码如下所示。

import java.util.*;
public class SortedLinkedList< E> extends LinkedList<E> 
{
   private Link<E> first;
   private Link<E> last;

/**
 * Constructor for objects of class SortedLinkedList
 */
public SortedLinkedList()
{
    //super();
    first = null;
    last = null;

}

/*
 * Link class for creating Link nodes in the SortedLinkedList objects
 */
private class Link<E> 
{
    public Comparable<E> data;
    public Link next;

}
/*
 * Overiding add method from LinkedList class
 */
public boolean add(E obj)
{
    Link newLink = new Link();
    newLink.data = (Comparable<E>)obj;

    // When the list is initially empty
    if (first == null)
    {
        first = newLink;
        last = newLink;
        return true;
    }


    // When the element to be added is less than the first element in the list
    if (newLink.data.compareTo(first.data) < 0)
    {
        //newLink.data = obj;
        newLink.next = first;
        first = newLink;
        return true;
    }

    // When the element to be added is greater than every element in in list
    // and has to be added at end of the list
    if (newLink.data.compareTo(last.data) > 0)
    {
        //newLink.data = obj;
        last.next = newLink;
        last = newLink;
        return true;
    }

    //When the element to be added lies between other elements in the list
    if (newLink.data.compareTo(first.data) >= 0 && newLink.data.compareTo(last.data) <= 0)
    {
        //newLink.data = obj;
        Link current = first.next;
        Link previous = first;
        while (newLink.data.compareTo(current.data) <= 0)
        {
           previous = current;
           current = current.next;
        }
        previous.next = newLink;
        newLink.next = current;

    }

    return true;
}


public static void main (String[] args)
{
    LinkedList<Integer> list = new SortedLinkedList<Integer>();
    list.add(4);
    list.add(5);
    list.add(10);
    list.add(9);
    //list.add(5);
    ListIterator<Integer> iterator = list.listIterator();

    while (iterator.hasNext())
    {
         System.out.println(iterator.next());
    }


}

}

4 个答案:

答案 0 :(得分:4)

如果必须使用LinkedList,那么您真正需要做的就是覆盖“add”方法,以便将元素插入到正确的位置。您可以通过调用add(integer,Object)方法来实现,该方法将元素插入特定位置。

这是我正在谈论的快速而肮脏(和非泛型:P)的实现。

public class PersonLinkedList extends LinkedList<Person> {

    public boolean add(Person personToAdd) {
        int index = 0;
        for( ; index<size() ; index++){
            Person personAlreadyInList = get(index);

            if(personToAdd.compareTo(personAlreadyInList) < 0){
                break;
            }
        }

        add(index, personToAdd);
        return true;
    };

    public static void main(String[] args) {
        Person amy = new Person("Amy");
        Person bob = new Person("Bob");
        Person claire = new Person("Claire");

        PersonLinkedList list = new PersonLinkedList();
        list.add(bob);
        list.add(claire);
        list.add(claire);
        list.add(amy);
        list.add(bob);

        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            Person person = (Person) iterator.next();
            System.out.println(person);
        }
    }
}

class Person implements Comparable<Person>{

    private String name;

    public Person(String name) { this.name = name; }

    public String getName() { return name; }

    @Override
    public String toString() { return getName();}

    @Override
    public int compareTo(Person p) {
        return name.compareTo(p.name);
    }
}

答案 1 :(得分:1)

没有打印的原因是因为您将数据存储在您自己的链表数据树中而不是LinkedList的数据树中。您不会覆盖迭代器方法,因此迭代器将遍历LinkedList的数据,该数据为空。这也是LinkedList中所有其他方法的问题。

您确定需要从LinkedList类继承,还是想要创建自己的类。

如果您应该从LinkedList继承,请删除您的节点并使用LinkedList存储数据。然后,您的add方法将使用ListIterator来查找添加和使用ListIterator的add方法的正确位置。

如果您不从LinkedList继承,则扩展AbstractSequentialList。

注意:

这两个选项都不应该用于实际代码中。添加自动排序会破坏List接口。

整个问题是“喜欢构成而不是继承”的完美例子。

如果这是作业,请按照指示进行,否则我建议更改练习以实现由LinkedList支持的SortedCollection。然后实现Collection并使用List作为成员变量。

答案 2 :(得分:0)

如果您不需要支持具有相同排序键的元素,则可以使用SortedSet

此外,您的代码不打印任何内容的原因是因为您覆盖了向列表添加项目,但没有迭代(iterator()listIterator()方法。)扩展LinkedList不会除非使用基类add()remove()和其他方法修改其内容,否则不会自动使您的数据结构可迭代。

答案 3 :(得分:0)

除了iterator, add/remove覆盖之外,我认为你的排序算法不正确。当您将现有元素添加到“sortedLinkedList”时,这会导致nullpointer异常。

 while (newLink.data.compareTo(current.data) <= 0)
        {
           previous = current;
           current = current.next;
        }

我认为你想要的是while (newLink.data.compareTo(current.data) >0)。不是<=0。这是错误。

因为“= 0”处于while状态,它将遍历整个列表,直到最后一个元素,然后执行:

(current is the last now)
    previous = current;
    current = current.next; (now, current is Null, since last.next is Null)

最后,当前是Null,然后又来了,current = current.next;砰!空指针。

所以我猜Nullpointer被扔到了这条线上。