Кръгов свързан списък и достъп до предишен/следващ от вътрешността на възела

Имам нужда от кръгов списък с обекти. И всеки трябва да знае кое е предишното или следващото. Направих го:

class Bus {

    private Bus previous;
    private Bus next;

    public Bus() {
      //anything
    }

    public void setPrevious(Bus bus) {
      this.previous = bus;
    }

    public void setNext(Bus bus) {
      this.next = bus;
    }

    private void someMethod() {
     // if (previous.xxx() && next.xxx()) {
     //   do something
     // } 
    }

}

И създадох масив от Bus. След като добавя всички автобуси в него, задавам следващ и предишен на всеки елемент. И ми се струва грозно :D. Можете ли да ми предложите по-добър начин?


person ciembor    schedule 05.01.2012    source източник


Отговори (4)


Ако коригирате вашите setNext и setPrevious методи, за да актуализирате не само техния екземпляр, но и екземпляра, който е зададен като next и като previous, искате да зависи от външен механизъм.

Да кажем, че първоначално сте създали Bus A и B. Когато извикате A.setNext( B ), той също трябва да актуализира предишния възел на B, без да се налага да извиквате B.setPrevious( A ). Подобно на това, когато добавяте нещо към LinkedList в Java, не е нужно ръчно да задавате връзката между последния обект и обекта, който току-що сте добавили. Нещо като

public void setPrevious(Bus bus) {
  this.previous = bus;
  if ( bus.next != this ){
    bus.next = this;
  }
}

Разбира се, тогава все още трябва да обмислите сценария, при който автобусът вече се съдържа в друг List, който трябва да актуализирате и този List.

Следователно предложението за отделяне на възлите от действителните екземпляри на шина, както е предложено в един от другите отговори, е по-добра идея. Това ви позволява да добавяте автобуси към множество списъци и вероятно улеснява писането на вашия кръгъл списък (или просто да използвате налична реализация за списъка). Това също е по-добър OO дизайн, тъй като можете да използвате повторно списъка, който сте написали.

person Robin    schedule 05.01.2012

Само мисъл, но може би има един клас за възлите и един за списъка. По този начин можете да имате конструктор за класа на възела, който обработва задаването на неговите следващи и последни препратки. Това позволява на списъка наистина да трябва да се тревожи само за стандартните списъчни функции като Add().

Разгледайте интерфейса на списъка.

person user489041    schedule 05.01.2012
comment
Знам, но имам нужда от достъп до предишния и следващия от възел, а не контролера на списъка... - person ciembor; 06.01.2012

Свързаният списък не се нуждае от масив. За да създадете списъка, трябва да използвате next и previous методи, за да свържете вашите обекти и да свържете последния с първия (за да направите кръгово). И пример за използване (използване на вашата реализация):

Bus one = new Bus();
Bus two = new Bus();
Bus three = new Bus();

one.setPrevious(three);
one.setNext(two);

two.setPrevious(one);
two.setNext(three);

three.setPrevious(two);
three.setNext(one);

Това повече или по-малко е идеята за циркулярно писмо за свързани списъци. Препоръчвам да видите този друг въпрос, за да разберете Свързан списък. Да го направите кръгово е лесно.

person jenaiz    schedule 05.01.2012
comment
Но имам нужда от N възела и ги създавам един по един. В кръговия списък не знам къде да поставя нов обект. Трябва да е между последния и първия. - person ciembor; 06.01.2012
comment
Да, нов обект трябва да е между последния и първия. Трябва да промените внедряването на Bus, за да направите това автоматично. - person jenaiz; 06.01.2012

Защо ви е необходим масив? Вече имате референциите във всеки обект.

person Fortunato    schedule 05.01.2012