get2top
@get2top

Структура данных Java. Как сделать multilist?

Здравствуйте, может ли кто то объяснить доступно или скинуть сайт где хорошо объясняется структуру мультисписков (Multilist). Нашел сайт на английском где объясняется то что мне нужно, но не совсем понятно до конца как это реализовать на Java.
Как в примере ниже, мне нужно связать два списка, на пример (Студенты и Предметы).
1 студент изучает n придметов, а 1 предмнета - n студентов.
Это что бы не дублировать данные. Можно сделать два два списка списков. Но тогда поля студента будут бублироваться. Нужен именно multilist. Да и список должен динамический.
Но как это реализировать? Не совсем понимаю саму структуру до конца, если можно пример какой то минимальный. Спасибо.

Multilists
56_a.gif
Our last example shows a more complicated use of linked lists. A university with 40,000 students and 2,500 courses needs to be able to generate two types of reports. The first report lists the class registration for each class, and the second report lists, by student, the classes that each student is registered for.

The obvious implementation might be to use a two-dimensional array. Such an array would have 100 million entries. The average student registers for about three courses, so only 120,000 of these entries, or roughly 0.1 percent, would actually have meaningful data.

What is needed is a list for each class, which contains the students in the class. We also need a list for each student, which contains the classes the student is registered for. Figure 3.27 shows our implementation.

As the figure shows, we have combined two lists into one. All lists use a header and are circular. To list all of the students in class C3, we start at C3 and traverse its list (by going right). The first cell belongs to student S1. Although there is no explicit information to this effect, this can be determined by following the student's linked list until the header is reached. Once this is done, we return to C3's list (we stored the position we were at in the course list before we traversed the student's list) and find another cell, which can be determined to belong to S3. We can continue and find that S4 and S5 are also in this class. In a similar manner, we can determine, for any student, all of the classes in which the student is registered.
  • Вопрос задан
  • 545 просмотров
Решения вопроса 2
Labunsky
@Labunsky
Я есть на хабре
Вот такая наивная реализация приходит в голову.
Роль заголовков исполняют два мэпа. Все остальное, по сути, хранится двунаправленными связными списками, у которых мы знаем начало

Код
/**
 * Created by Labunsky on 24.03.2017.
 */
public class MultiListEntry<S, C> {
    private MultiListEntry<S, C> nextStudentEntry = null;
    private MultiListEntry<S, C> nextCourseEntry = null;

    private S student;
    private C course;

    MultiListEntry(S student, C course) {
        this.student = student;
        this.course = course;
    }

    public S getStudent() {
        return student;
    }

    public C getCourse() {
        return course;
    }

    public void setNextStudentEntry(MultiListEntry<S, C> next) {
        nextStudentEntry = next;
    }

    public void setNextCourseEntry(MultiListEntry<S, C> next) {
        this.nextCourseEntry = next;
    }

    public MultiListEntry<S, C> getNextStudentEntry() {
        return nextStudentEntry;
    }

    public MultiListEntry<S, C> getNextCourseEntry() {
        return nextCourseEntry;
    }
}

/**
 * Created by Labunsky on 24.03.2017.
 */
public class MultiList<S, C> {
    private Map<S, MultiListEntry<S, C>> studentsIndex = new HashMap<>();
    private Map<C, MultiListEntry<S, C>> coursesIndex = new HashMap<>();

    public void add(S student, C course) {
        MultiListEntry<S, C> newEntry = new MultiListEntry<>(student, course);
        MultiListEntry<S, C> lastEntry;

        if (studentsIndex.containsKey(student)) {
            lastEntry = studentsIndex.get(student);

            while (lastEntry.getNextStudentEntry() != null)
                lastEntry = lastEntry.getNextStudentEntry();
            lastEntry.setNextStudentEntry(newEntry);
        } studentsIndex.put(student, newEntry);

        if (coursesIndex.containsKey(course)) {
            lastEntry = coursesIndex.get(course);
            
            while (lastEntry.getNextCourseEntry() != null)
                lastEntry = lastEntry.getNextCourseEntry();
            lastEntry.setNextCourseEntry(newEntry);
        } else coursesIndex.put(course, newEntry);
    }

    public MultiListEntry<S, C> getStudentEntries(S student) {
        return studentsIndex.get(student);
    }

    public MultiListEntry<S, C> getCourseEntries(C course) {
        return coursesIndex.get(course);
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы