Как создать двусвязный список из нескольких типов данных - PullRequest
0 голосов
/ 13 февраля 2019

В настоящее время я пишу программу, которая создает студентов и сохраняет их в двусвязном списке в соответствии с их естественным порядком (фамилия, имя, средний балл, затем идентификатор студента).Я только начинаю с дженериков и как они работают, поэтому я немного растерялся.Я считаю, что большая часть моего кода работает;единственная часть, в которой мне нужна помощь, - это добавление учеников (которые имеют несколько типов данных) в мой список в моем методе 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 голосов
/ 14 февраля 2019

Все еще не совсем уверен, может быть, есть некоторые варианты этого.

Особенно это вставляет перед первым Узлом, который больше, и я все еще не уверен, для чего используются дженерики в этом случае, и 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;
    }
}
...