2010-11-16 1 views
1

Да, это один из моих домашних проектов - реализовать Циркулярный Связанный Список, основанный на Едином Связанном списке. Это довольно просто, и код легко читать. Все мои атрибуты общедоступны, чтобы избежать геттеров и сеттеров и частного бизнеса. Для целей этого проекта достаточно общественности.Нужна помощь с Circular Linked List на Java!

Я инициализировал свой счетчик (№ элементов в списке) и ссылку «Прямо в поле атрибута», но я его поменю позже, инициализируя его внутри конструктора.

Мой Этап() Метод, похоже, не работает вообще. Мой компилятор просто замораживается на мгновение, а затем ничего не появляется. Это как шаг() метод должен работать, если я называю это в 4 раза:

List: 40 80 30 20 10 70 50 
List: 80 30 20 10 70 50 40 
List: 30 20 10 70 50 40 80 
List: 20 10 70 50 40 80 30 

Find() метод отлично работает, то есть до тех пор, пока значение мы ищем внутри связного списка. Если это не так, это будет продолжаться вечно. Если это мой список, это то, что происходит с находки() методом, если вы ищете значение, которое не существует (я отлажена его шаг за шагом):

70 60 50 40 30 20 10 10 10 10 10 10 10 10...and 10 forever 

Причина: Если ключ ценность, которую мы ищем, не существует, она никогда не выйдет из цикла while, поэтому навсегда повторяется current = current.next.

while(current.dData != key) { 
current = current.next; 

Мой метод удаления говорит он удаляется значение 60 так же, как я хотел, но это то, что я получаю:

Deleted link with key 60 
70 60 40 30 20 10  // lie! it deletes 50 instead of 60 

Обратите также внимание на мой дисплей() и моя вставка() методы , Они отлично смотрятся на меня, но я могу ошибаться, и это может быть источником всех проблем, которые возникают у меня с методами find() и delete().

Большое вам спасибо!

class Link { 
    public int dData; 
    public Link next; 

    public Link(int dd) { 
     dData = dd; 
    } 

    public void displayLink() { 
     System.out.print(dData + " "); 
    } 
} 

class CircList { 
    public Link head = null; 
    int nItems = 0; 

    public boolean isEmpty() { 
     return (nItems == 0); 
    } 
    // INSERT 
    public void insert(int key) { 

     Link current = new Link(key); 
     if(isEmpty()) 
      head = current; 

     current.next = head; 
     head = current; 
     nItems++; 
    } 
    // STEP 
    public void step() { 
     Link current = head; 
     do { 
      current = current.next; 
     } while(current != head); 
    } 
    // FIND 
    public Link find (int key) { 
     Link current = head; 
     while(current.dData != key) { 
      current = current.next; 
     } 
     return current; 
    } 
    // DELETE 
    public Link delete(int key) { 
    Link current = head; 
    while(current.dData != key) { 
     current = current.next; 
    } 
    if(current == head) 
     head = head.next; 
    else { 
     current.next = current.next.next; 
     nItems--; 
    } 
    return current; 
} 
    // DISPLAY 
    public void displayList() { 
     Link current = head; // start at beginning 
     int counter = nItems; 
     while(true) { 
      if(counter != 0) { 
       current.displayLink(); 
       current = current.next; // move to next link 
       counter--; 
      } 
      else 
       break; 
     } 
    } 
} 

class CircListApp { 
    public static void main(String[] args) { 
    Link f, d; 
    CircList theList = new CircList(); 


    theList.insert(10);  // insert items 
    theList.insert(20); 
    theList.insert(30); 
    theList.insert(40); 
    theList.insert(50); 
    theList.insert(60); 
    theList.insert(70); 

    //System.out.println(theList.nItems + " "); 
    theList.displayList();    // display list 

    System.out.println(""); 

    f = theList.find(30);    // find item 
    if(f != null) 
     System.out.println("Found link with key " + f.dData); 
    else 
     System.out.println("Can't find link with key 30"); 

// theList.step(); 

// 
// System.out.println("Inserting link with key 80"); 
// theList.insert(80); 
// theList.displayList();    // display list 
// 
    d = theList.delete(60);    // delete item 

    if(d != null) 
     System.out.println("Deleted link with key " + d.dData); 
    else 
     System.out.println("Can't delete link with key 60"); 
    theList.displayList();    // display list 
// 
// f = theList.find(99);    // find item 
// if(f != null) 
//  System.out.println("Found link with key " + f.dData); 
// else 
//  System.out.println("Can't find link with key 99"); 
// theList.displayList();    // display list 
// 
// d = theList.delete(13);    // delete item 
// if(d != null) 
//  System.out.println("Deleted link with key " + d.dData); 
// else 
//  System.out.println("Can't delete link with key 13"); 
// theList.displayList();    // display list 
// 
// System.out.println("Stepping through list"); 
// for(int j=0; j<theList.getSize; j++) 
//  { 
//  theList.step(); 
//  theList.displayList(); 
//  } 
// 
// System.out.println("Will delete and step one by one"); 
// while(theList.isEmpty() == false) 
//  { 
//  theList.delete(); 
//  theList.step(); 
//  theList.displayList(); 
//  } 
    } // end main() 

} 
+0

Чтобы исправить Find(), посмотрите на Step(), чтобы выяснить, как остановиться. – Stu

+0

Я получаю подсказку, мне нужно использовать цикл do-while? Но это ничего не изменит. Я чувствую, что мне не хватает другого условия в инструкции while, или мне нужно ввести какие-то счетчики, например. в то время как (nItems! 0) nItems--; –

+0

На самом деле, вам не нужен счетчик! Вы можете просто использовать «current == head» в качестве проверки, если вы пропустили весь список. – Lagerbaer

ответ

1

К вашему методу «шаг»: Вы создаете локальную ссылку под названием ток, который изначально указывает на голову. После

current = current.next 

ссылка на преемника головы. И на следующем шаге он ссылается на преемника этого и т. Д. Но это локальная ссылка, поэтому вы ничего не меняете в списке.

То, что вы должны сделать, так как я вывожу из нужного выхода, так просто, как

if(head != null && head.next != null) 
    head = head.next 

Следующая: Для вашего FIND-метода: Ну, от вашего состояния контура, то вполне очевидно, что это будет выполняться вечно, если ключ отсутствует в списке, потому что это ваше единственное нарушение. Вам следует подумать о механизме, который заставит его остановиться после того, как вы просмотрите каждый элемент в списке. Подсказка. Посмотрите, что вы сделали в своей версии метода step().

К вашему методу удаления: Первая часть (частично) в порядке (она имеет ту же проблему с бесконечным контуром, что и метод find). Что вы делаете, это перебирать список до тех пор, пока данные тока не будут равны ключу. Хорошо.

Но теперь текущий - это ссылка на элемент, который вы хотите удалить. Но то, что вы делаете, это установить current.next to current.next.next, что означает, что вы удаляете преемника текущего, а не самого тока! В вашем цикле, где вы ищете ключ, вы должны следить за предшественником, чтобы вы могли изменить predecessor.next на current.next, что вы действительно хотите сделать.

И тогда, конечно, вы должны проверить, является ли это той головкой, которую вы удаляете, и если это так, вы должны установить ее либо предшественнику, либо его преемнику.

И наконец, я вижу проблему с вашим методом insert()! Я не вижу, как это может создать круговой связанный список, потому что вы позволяете вновь вставленному элементу указывать на голову и превращать его в новую голову, но ничто не указывает на это. Таким образом, вы создаете только отдельный список? Вы вставляете новый элемент «до» головы (current.next = head), но тогда вы также должны иметь прежнего предшественника головы, теперь указывающего на новый элемент, текущий!

+0

С вызовами 2 шага я получаю этот результат: 60 50 40 30 20 10 10 50 40 30 20 10 10 10. Вы уверены, что это правильно? Iirc нам не нужно беспокоиться о NULL вообще в Circular Linked Lists. И сейчас ток никогда не использовался после того, как я инициализировал Link current = head; –

+0

Не уверен, что я понимаю, что вы имеете в виду. Цель метода шага состоит в том, чтобы переместить голову на один шаг дальше по кругу, так что вам в основном нужен только head = head.next, но поскольку ваш список может быть пустым, я бы тестировал head == null. Конечно, вы можете опустить head.next == null, это правда. – Lagerbaer

+0

Лаг, ты прав. Но есть большая проблема, вы видите эти отстающие 10? Их там не должно быть, вместо этого «старая» голова должна быть в том месте. Связанный список должен оставаться в тактике: у меня есть 10, 20, 30, 40, 50, 60, 70, поэтому на каждом шагу у меня должны быть эти ценности. –

 Смежные вопросы

  • Нет связанных вопросов^_^