Полный связанный список не будет печатать все значения

#java #linked-list #queue #tostring #implementation

#java #связанный список #очередь #tostring #реализация

Вопрос:

Я думаю, что у меня возникли проблемы с моим классом Queue, потому что я знаю, что при использовании Queue используется метод FIFO, но хочу убедиться, что при добавлении элемента он добавляется в конец очереди. В моей основной программе я добавил числа 1-4, но когда я хочу распечатать всю свою очередь, используя метод toString в моем классе Queue, он распечатает только первый элемент, который равен 1. Я был бы признателен за помощь!

Спасибо!

  public class QuestionFive
    {
       public static void main(String[] args)
       {
          // creating a queue
          Queue q = new Queue();
    
          // adding numbers 1,2,3 and 4
          q.insert(1);
          q.insert(2);
          q.insert(3);
          q.insert(4);

          System.out.println(q);
       }
    }
    class Queue 
    {
       //Private Data Member
       private Link _head;
       
       //Constructor: A constructor to create an empty Queue,
       public Queue() 
       {
          _head = null;
       }
       
       //Insert Method: A method to insert a given Object into the Queue.
       //Note: We will inserton
       public void insert(Object item) 
       {
          Link add = new Link();
          add.data = item;
          add.next = null;
          
          if(_head == null)
          {
             _head = add;
          }
          else
          {
             for(Link curr = _head; curr.next != null; curr = curr.next)
             {
                curr.next = add;
             }
          }
       }
       
       //Delete Method: A method to delete an Object from the Queue
       public Object delete() 
       {
            if ( _head == null ) return null; 
               
            Link prev = null;    
            Link curr = _head;     
            while (curr.next != null )    
            {      
                prev = curr;      
                curr = curr.next; 
            }     
            if ( prev != null ) 
            {
                prev.next = null; 
            }   
            else
            {       
                _head = null;   
            } 
            return curr.data;
        }
        
        // IsEmpty Method: A method to test for an empty Queue
        public boolean isEmpty() 
        {
          // queue is empty if front is null
          return (_head == null);
        }
        
        //toString Method:
        public String toString()
        {
          String s = "";
          for (Link curr = _head; curr != null; curr = curr.next)
          {
              s = s   " "   curr.data;
          }
          return s;
        }
    }
    
    //Link Class
    class Link 
    {
       public Object data;
       public Link next;
    }
 

Комментарии:

1. Вы пробовали использовать отладчик и / или регистрировать поведение вашего кода при добавлении элемента в очередь? Мне кажется, что ваш insert метод по сути переписывает очередь каждый раз, когда вы что-то добавляете, поэтому в итоге вы получаете только _head запись.

2. curr.next = add; принадлежит после цикла, а не внутри него.

3. @KevinAnderson Если curr.next = add находится вне цикла, это не сработает?

4. Этого не будет, если вы не объявите curr перед циклом и не запишете цикл как for (curr = _head;... . Идея состоит в том, чтобы позволить циклу перемещаться curr до последнего узла, а затем все curr еще быть доступным после этого, чтобы вы могли поместить новый узел в конец с next = add; ,

Ответ №1:

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

 class Queue {
       private Link head;
       private Link tail;
       
       public void insert(Object item) {
          Link add = new Link();
          add.data = item;
          add.next = null;
          
          if(head == null)
          {
             head = add;
             tail = add;
          }
          else {
             tail.next = add;
             tail = add;
          }
       }
}
 

Метод действительно должен быть вызван add , поскольку он добавляется в конец, а не вставляется.

Комментарии:

1. Большое вам спасибо за вашу помощь! Это сработало! Я глубоко ценю вашу помощь!

2. @rockyDodgers если это работает, то отметьте ответ как принятый.

Ответ №2:

Логика в вашем insert() методе требует внимания. Я изменил else часть метода следующим образом, и это сработало:

           else
          {
             for(Link curr = _head; ; curr = curr.next)
             {
                if(curr.next == null){
                    curr.next = add;
                    break;
                }
             }
          }
 

Вот полный рабочий класс:

  public class QuestionFive
    {
       public static void main(String[] args)
       {
          // creating a queue
          Queue q = new Queue();
    
          // adding numbers 1,2,3 and 4
          q.insert(1);
          q.insert(2);
          q.insert(3);
          q.insert(4);

          System.out.println(q);
       }
    }
    class Queue 
    {
       //Private Data Member
       private Link _head;
       
       //Constructor: A constructor to create an empty Queue,
       public Queue() 
       {
          _head = null;
       }
       
       //Insert Method: A method to insert a given Object into the Queue.
       //Note: We will inserton
       public void insert(Object item) 
       {
          Link add = new Link();
          add.data = item;
          add.next = null;
          
          if(_head == null)
          {
             _head = add;
          }
          else
          {
             for(Link curr = _head; ; curr = curr.next)
             {
                if(curr.next == null){
                    curr.next = add;
                    break;
                }
             }
          }
       }
       
       //Delete Method: A method to delete an Object from the Queue
       public Object delete() 
       {
            if ( _head == null ) return null; 
               
            Link prev = null;    
            Link curr = _head;     
            while (curr.next != null )    
            {      
                prev = curr;      
                curr = curr.next; 
            }     
            if ( prev != null ) 
            {
                prev.next = null; 
            }   
            else
            {       
                _head = null;   
            } 
            return curr.data;
        }
        
        // IsEmpty Method: A method to test for an empty Queue
        public boolean isEmpty() 
        {
          // queue is empty if front is null
          return (_head == null);
        }
        
        //toString Method:
        public String toString()
        {
          String s = "";
          for (Link curr = _head; curr != null; curr = curr.next)
          {
              s = s   " "   curr.data;
          }
          return s;
        }
    }
    
    //Link Class
    class Link 
    {
       public Object data;
       public Link next;
    }
 

Ответ №3:

Исправлено в вашем коде (вместо метода toString printList):

  
public class QuestionFive
    {
       public static void main(String[] args)
       {
          // creating a queue
          Queue q = new Queue();
    
          // adding numbers 1,2,3 and 4
          q.insert(1);
          q.insert(2);
          q.insert(3);
          q.insert(4);
          q.printList();
          System.out.println(q);
       }
    }
    class Queue 
    {
       //Private Data Member
       private Link _head;
       
       //Constructor: A constructor to create an empty Queue,
       public Queue() 
       {
          _head = null;
       }
       
       //Insert Method: A method to insert a given Object into the Queue.
       //Note: We will inserton
       public void insert(Object item) 
       {
          Link add = new Link();
          add.data = item;
          add.next = _head;
          _head = add;
          
       }
       
       //Prints list data
       public void printList() {
           Link currentLink = _head;
           System.out.print("List: ");
           while(currentLink != null) {
               currentLink.printLink();
               currentLink = currentLink.next;
           }
           System.out.println("");
       }
       
       //Delete Method: A method to delete an Object from the Queue
       public Object delete() 
       {
            if ( _head == null ) return null; 
               
            Link prev = null;    
            Link curr = _head;     
            while (curr.next != null )    
            {      
                prev = curr;      
                curr = curr.next; 
            }     
            if ( prev != null ) 
            {
                prev.next = null; 
            }   
            else
            {       
                _head = null;   
            } 
            return curr.data;
        }
        
        // IsEmpty Method: A method to test for an empty Queue
        public boolean isEmpty() 
        {
          // queue is empty if front is null
          return (_head == null);
        }
        
    }
    
    //Link Class
    class Link 
    {
       public Object data;
       public Link next;
       //Print Link data
       public void printLink() {
           System.out.print("{"   data   "}");
       }
    }