如何创建多个数据类型的双向链接列表

时间:2019-02-13 19:34:41

标签: java generics doubly-linked-list

我目前正在编写一个程序,该程序创建学生并将其基于其自然顺序(姓,名,GPA,然后是学生ID)存储在双链表中。我只是从泛型及其工作原理开始,所以我有点迷茫。我相信我的大部分代码都可以正常工作;我唯一需要帮助的部分是将我的学生(具有多种数据类型)添加到我的双向链接列表类的main方法中的列表中。任何帮助是极大的赞赏!这是我的学生,双向链接列表和节点类,以及我正在从中读取的输入文件的片段以及每个学生的数据:

学生班:

public class Student{
long studentID;
String firstName;
String lastName;
float GPA;

public Student(String lastName, String firstName, float GPA, long studentID){
    this.lastName = lastName;
    this.firstName = firstName;
    this.GPA = GPA;
    this.studentID = studentID;
}

public int compareTo(Student s){
    int result = this.lastName.compareTo(s.lastName);
    if(result == 0){
        result = this.firstName.compareTo(s.firstName);
        if(result == 0){
            result = Float.compare(this.GPA, s.GPA);
            if(result == 0){
                result = Long.compare(this.studentID, s.studentID);
            }
        }
    }
    return result;
}

public String toString(){
    return this.lastName + ", " + this.firstName +
     " GPA: " + this.GPA + " ID: " + this.studentID;
}

}

节点类:

public class Node<T>{
Node<T> previous;
Node<T> next;
Student data;

public Node(Student data){
    this(data, null, null);
}

public Node(Student data, Node<T> previous, Node<T> next){
    this.data = data;
    this.previous = previous;
    this.next = next;
}
}

双向链表类:

import java.io.*;
import java.util.*;
import csci1140.*;

public class DoublyLinkedList<T> implements Iterable<Node>{
private Node root;
private Node tail;
private Node previous;

 private class ListIterator implements Iterator<Node>{
    Node current = root;
    public boolean hasNext(){
        return (current != null);
    }


    public Node next(){
        Node answer;

        answer = current;
        current = current.next;

        return answer;
    }

} 

 public Iterator<Node> iterator(){
    ListIterator listIterator = new ListIterator();
    return listIterator;
}  

public void add(T data){
    Node<Student> newNode = new Node<Student>(data);

    if(root == null){
        root = newNode;
        tail = root;
        return;
    }

    Node current = root;
    for( ; current!= null; current = current.next){
        if(newNode.data.compareTo(current.data)<= 0){
            break;
        }

    }

    if(previous == null){
        previous.next = newNode;
        newNode.next = current;
        if(current == null){
            tail = newNode;
        }
    } else {
        newNode.next = root;
        root = newNode;
    }
}

public static final void main(String[] args){

   FileInputStream fileIn = null;
    try{ 
        fileIn = new FileInputStream("student_input.txt"); 
        System.setIn(fileIn);            
    } catch(FileNotFoundException fnfe){ 
        fnfe.printStackTrace(System.err); 
    } 

    //Do work here to create list of students

    }
    try{                        
        fileIn.close();         
    } catch(Exception e){}            
}
}

Student_input.txt:

1000
Lisa
Licata
2.28
1001
Shelley
Santoro
1.56
1002
Ok
Ota
3.33
1003
Cindi
Caggiano
1.65

1 个答案:

答案 0 :(得分:0)

仍然不确定,也许对此有所改动。

特别是这会在第一个更大的Node之前插入,我仍然不确定这种情况下的泛型是什么,并且T必须是扩展Student的东西(很好,它需要compareTo方法):

public void add(T data) {
    for(Node<T> current = root; current != null; current = current.next) {
        if (data.compareTo(current.data) <= 0) {
            current = new Node<>(data,current.previous,current);
            if(null == current.previous){
                root = current;
            }else {
                current.previous.next = current; 
            }
            if(null == current.next){
               tail = current; 
            } else {
               current.next.previous = current; 
            }
            return;
        }
    }
    tail = new Node<>(data,tail,null);
    if(null == tail.previous) root=tail;
}

因此您的列表应该看起来像这样(以确保T具有compareTo方法):

public class DoublyLinkedList<T extends Student> implements Iterable<Node<T>> {
...
}

全部在一起(像您一样将Node作为一个单独的文件会更好-但为简便起见,我将其放入列表中):

public class DoublyLinkedList<T extends Student> implements Iterable<Node<T>> {

    public static class Node<S> {

        Node<S> previous;
        Node<S> next;
        S data;

        public Node(S data) {
            this(data, null, null);
        }

        public Node(S data, Node<S> previous, Node<S> next) {
            this.data = data;
            this.previous = previous;
            this.next = next;
        }
    }
    private Node<T> root = null;
    private Node<T> tail = null;

    private class ListIterator implements Iterator<Node<T>> {

        Node<T> current = root;

        @Override
        public boolean hasNext() {
            return (current != null);
        }

        @Override
        public Node<T> next() {
            Node<T> answer;

            answer = current;
            current = current.next;

            return answer;
        }

    }

    @Override
    public Iterator<Node<T>> iterator() {
        ListIterator listIterator = new ListIterator();
        return listIterator;
    }

    public  void add(T data) {
        for(Node<T> current = root; current != null; current = current.next) {
            if (data.compareTo(current.data) <= 0) {
                current = new Node<>(data,current.previous,current);
                if(null == current.previous){
                    root = current;
                }else {
                    current.previous.next = current; 
                }
                if(null == current.next){
                   tail = current; 
                } else {
                   current.next.previous = current; 
                }
                return;
            }
        }
        tail = new Node<>(data,tail,null);
        if(null == tail.previous) root=tail;
    }
}