按升序排序双向链表

时间:2015-01-18 22:04:33

标签: java doubly-linked-list

我需要根据ID的升序对包含其ID,姓名,年龄和GPA的学生列表进行排序。我的方法insertAscending试图这样做,但由于某种原因不能正常工作。我的私有内部Node类也包含在内。任何帮助将不胜感激。

public class StudentInfo
{
    //Node class (inner class)
    private class Node
    {
        private int id;
        private String name;
        private int age;
        private double gpa;
        private Node next;
        private Node prev;


        //constructor of Node
        private Node(int id, String name, int age, double gpa, Node prev, Node next)
        {
            this.id = id;
            this.name = name;
            this.age = age;
            this.gpa = gpa;
            this.prev = prev;
            this.next = next;

        }
    }
   /*******************************************************************/

   private Node head;
   private Node tail;
   int size;
   //constructor of list
   public StudentInfo()
   {
       head = null;
       tail = null;
   }
   /*********************************************************************/

   public void insertAscending(int id, String name, int age, double gpa)
   {



     if (head == null)
     { 
         head = tail = new Node(id, name, age, gpa, null, null );
         size ++;

     }

     //insert at beginning
     else if( id < head.id)
     {

         head = new Node(id, name, age, gpa, null, head);
         size ++;

     }


     //insert at end
     else if(id > tail.id)
     {
         tail = new Node(id, name, age, gpa, tail, null);
         size++;
     }

     //insert at other positions 
     else 
     {
         for(Node temp = head; temp.next != null; temp = temp.next)
         {
             if (id > temp.id && id < temp.next.id)
             {
                 temp.next = new Node(id, name, age, gpa, temp, temp.next);
                 temp.next.next.prev = temp.next;
                 size++;
                 break;
             }
         }
     }

   }
}

1 个答案:

答案 0 :(得分:1)

这是作业的一部分吗?您是否必须使用双向链表?

保持LinkedList的排序顺序否定了LinkedList的许多好处,即头部和尾部的O(1)插入。通常,这听起来像是TreeMap的工作,其中键是学生ID,值是Student对象。这将为您提供学生ID顺序的迭代以及更快的查找。

关于这段代码的实际问题,我认为您忘记更新列表中已有的节点的一些头/尾(不是您要插入的节点)。例如,我认为你的else / if梯子中添加新尾部的部分看起来应该是这样的:

else if(id > tail.id)
{
     Node newTail = new Node(id, name, age, gpa, tail, null);
     tail.next = newTail;
     tail = newTail;
     size++;
}

以前您没有更新旧尾部的next指针。同样,我认为您设置新头的代码应如下所示:

else if( id < head.id)
{
     Node newHead = new Node(id, name, age, gpa, null, head);
     head.prev = newHead;
     head = newHead;
     size ++;
}

您没有设置旧头的prev指针,因为添加了新头。

其他快速想法:

  • 您应该在构造函数
  • 中明确初始化size0

不仅纠正任何其他错误,我认为这里更大的问题是:你是如何测试的?我只是通过运行一些快速测试就可以很容易地找到一些这些错误。我在类中添加了一些方便的方法(仅用于测试...有更好的方法来执行迭代器):

public void print()
{
   for(Node temp = head; temp != null; temp = temp.next)
   {
       System.out.println(temp.name);
   }
}

public void printReverse()
{
   for(Node temp = tail; temp != null; temp = temp.prev)
   {
       System.out.println(temp.name);
   }
}

然后我添加了一个简单的main方法,如下所示:

public static void main(final String[] args)
{
   StudentInfo si = new StudentInfo();
   si.insertAscending(2, "Brent", 23, 2.2);
   //si.insertAscending(3, "Steve", 23, 2.2);
   //si.insertAscending(5, "Joe", 23, 2.2);
   //si.insertAscending(4, "Pat", 23, 2.2);
   //si.insertAscending(1, "Mike", 23, 2.2);
   si.print();
   System.out.println("==========");
   si.printReverse();
}

即使不使用调试器或任何东西,也很容易看出出现了什么问题。一旦我确定单元素的情况有效,我就会取消注释下一个insertAscending调用等等,直到它完成所有工作。

我在此处未提及的代码中可能存在或可能没有其他错误。我认为非常重要的是你了解我是如何发现这些错误的,并且你想出了一个更好的方法来测试你的代码并说服自己它正常工作。