Этот связанный список реализован по кругу? - PullRequest
0 голосов
/ 12 декабря 2018

Это мой первый пост здесь!Я студент CS, поэтому я все еще учусь.Если у вас есть какие-либо советы или указатели (ха-ха ..!), Которые можно дать в отношении структурирования моего кода или общей практики, я был бы признателен за любые отзывы!

Мне дали задание повторно реализовать класс Queueв Java (https://docs.oracle.com/javase/7/docs/api/java/util/Queue.html) с использованием кругового связанного списка. Мое представление прилагается к этому вопросу. Я получил ноль на задании - согласно оценщику, моя реализация связанного списка не является круговой.

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

Например ( и я знаю, что этот сегмент выглядит грязно, у меня только он установлен таким образом с целью отладки - это фактически раздел, который я имею сопущен мой действительный код ):

System.out.println("next: " + cursor.getNext().getData());
System.out.println("next.next: " + cursor.getNext().getNext().getData());
System.out.println("next.next.next: " + cursor.getNext().getNext().getNext().getData());
System.out.println("next.next.next.next: " + cursor.getNext().getNext().getNext().getNext().getData());

отпечатки:

следующий: 45

следующий. следующий: 71

next.next.next: 3

next.next.next.next: 45

при наличии трех узлов, содержащих данные, введенные в список.

Кроме того, метод add , начинающийся со строки 30, назначает следующий узел после хвоста списка заголовку (в отличие от нулевого значения), таким образом, список должен циклически циклически изменяться, верно?Вот сегмент:

Node<T> node = new Node<T>(element);
if(isEmpty() == true){
    head = node;
}else{tail.setNext(node);}

tail = node;
node.setNext(head);

Наверное, мой вопрос: каким образом это не реализовано циклически?

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

Заранее благодарен за любую помощь!

Полный код (три класса - CircularLinkedQueue, Node и CircularLinkedListTest соответственно):

CircularLinkedQueue:

import java.util.NoSuchElementException;

public class CircularLinkedQueue<T> {
int count = 0;
private Node<T> head = null;
private Node<T> tail = head;

public CircularLinkedQueue(){
    Node<T> node = new Node<T>();
    tail = node;
}

/* Inserts the specified element into this queue if it is
 * possible to do so immediately without violating capacity
 * restrictions, returning true upon success and throwing
 * an IllegalStateException if no space is currently available.
 */
public boolean add(T element){
    try{
        Node<T> node = new Node<T>(element);
        if(isEmpty() == true){
            head = node;
        }else{tail.setNext(node);}

        tail = node;
        node.setNext(head);
        count++;
        return true;
    }catch(Exception all){
        Node<T> node = new Node<T>(element);
        if(element == null){throw new NullPointerException("Specified 
element is null.");}
        else if(element.getClass().getName() != 
node.getData().getClass().getName()){
            throw new ClassCastException
            ("Class of specified element prevents it from being added.");
        }
        return false;
    }
}
/* Retrieves, but does not remove, the head of this queue.
 * This method differs from peek only in that it throws
 * an exception if this queue is empty.
 */
public T element(){
    Node<T> cursor;
    if(isEmpty() != true){
        cursor = head;
    }else{throw new NoSuchElementException("No such element exists.");}
    return cursor.getData();

}
/*
Inserts the specified element into this queue if it is possible
to do so immediately without violating capacity restrictions.
When using a capacity-restricted queue, this method is generally
preferable to add(E), which can fail to insert an element only
by throwing an exception.
/*
public boolean offer(T element){
    try{
        Node<T> node = new Node<T>(element);
        if(isEmpty() == true){
            head = node;
        }else{tail.setNext(node);}

        tail = node;
        node.setNext(head);
        count++;
        return true;
    }catch(Exception all){return false;}
}

/* Retrieves, but does not remove, the head of this queue,
 * or returns null if this queue is empty.
 */
public T peek(){
    Node<T> cursor;
    //set cursor to head if not empty, create new null node otherwise
    if(isEmpty() != true){
        cursor = head;
    }else{cursor = new Node<T>(); cursor.setData(null);}
    //return null if no data is stored
    return cursor.getData();
}
/* Retrieves and removes the head of this queue,
 * or returns null if this queue is empty.
 */
public T poll(){
    Node<T> cursor = head;
    if(isEmpty() != true){
        if(count <= 1){
            head.setNext(null);
            head = head.getNext();
            tail = head;
            count--;
            return null;
        }else{
            //cursor = head;
            head = head.getNext();
            tail.setNext(head);
        }
    }else{cursor = new Node<T>(); cursor.setData(null);}
    count--;
    return cursor.getData();
}
/* Retrieves and removes the head of this queue.
 * This method differs from poll only in that it
 * throws an exception if this queue is empty.
 */
public T remove(){
    Node<T> cursor;
    if(isEmpty() != true){
        if(count <= 1){
            head.setNext(null);
            head = head.getNext();
            tail = head;
            count--;
            return null;
        }else{
            cursor = head;
            head = head.getNext();
            tail.setNext(head);
        }
    }
    else{throw new NoSuchElementException("No such element exists.");}
    count--;
    return cursor.getData();
}
//returns whether the list is empty or not
public boolean isEmpty(){return head == null;}

/* This method puts all the values of the circular linked list
 * into a String type for output purposes.
 */
@Override
public String toString(){
    int cycles = count;
    String s = "";
    Node<T> cursor = head;
    while(cycles > 0){
        s = s + cursor.getData() + "\n";
        cursor = cursor.getNext();
        cycles--;
    }
    /*
     * these lines print as expected & exist only for debugging purposes
    System.out.println("next: " + cursor.getNext().getData());
    System.out.println("next.next: " + 
cursor.getNext().getNext().getData());
    System.out.println("next.next.next: " + 
cursor.getNext().getNext().getNext().getData());
    System.out.println("next.next.next.next: " + 
cursor.getNext().getNext().getNext().getNext().getData());
    */
    return s;
}
//returns the length of the list
public int getCount(){return count;}
}

Узел:

public class Node<T> {
T data;
Node<T> next;

public Node(){data = null;}

public Node(T data){this.data = data;}

public void setData(T data){this.data = data;}

public void setNext(Node<T> nextNode){next = nextNode;}

public T getData(){return data;}

public Node<T> getNext(){return next;}
}

CircularLinkedListTest:

public class CircularLinkedListTest<T>{

public static void main(String[] args) {
    /* demonstrates creation of new circular linked lists/linked queues,
     * uses two different data types
     */
    CircularLinkedQueue<Integer> c1 = new CircularLinkedQueue<Integer>();
    CircularLinkedQueue<String> c2 = new CircularLinkedQueue<String>();
    //demonstrate add and offer methods detailed in Queue interface
    c1.add(3);
    c1.offer(45);
    c1.offer(71);
    c2.add("hello");
    c2.offer("good evening");
    c2.offer("how do you do");
    //demonstrates a toString method and prints after data has been added
    System.out.println("c1.toString(): \n" + c1.toString());
    System.out.println("c2.toString(): \n" + c2.toString());
    /* demonstrates the remove and poll methods, prints out the values in 
the list,
     * poll method returns null when implemented, isEmpty method shows the
     * nodes are truly being removed from the list after poll or remove
methods are
     * called
     */
    c1.remove();
    c2.remove();
    c2.remove();
    System.out.println("c1.toString(): \n" + c1.toString());
    System.out.println("c2.poll(): " + c2.poll());
    System.out.println("c2.getCount(): " + c2.getCount());
    System.out.println("c2.isEmpty(): " + c2.isEmpty());
    System.out.println("");
    //re-add data to c2
    c2.offer("howdy");
    c2.offer("hi there");
    //reprint c2, getCount and isEmpty to prove updated data values
    System.out.println("c2.toString(): \n" + c2.toString());
    System.out.println("c2.getCount(): " + c2.getCount());
    System.out.println("c2.isEmpty(): " + c2.isEmpty());
    System.out.println("");
    /* demonstrate peek and element functions by printing out most
     * recent items in the linked queue
     */
    System.out.println("c1.peek(): " + c1.peek());
    System.out.println("c2.element(): " + c2.peek());
    System.out.println("");
    //remove items from c1 to show peek returns null when list is empty
    c1.remove();
    c1.remove();
    System.out.println("c1.peek(): " + c1.peek());
    System.out.println("c1.getCount(): " + c1.getCount());
    System.out.println("c1.isEmpty(): " + c1.isEmpty());

    //all methods in queue interface have been demonstrated
}

}

Еще раз спасибо за любую помощь!

1 Ответ

0 голосов
/ 12 декабря 2018

Я получил ноль в задании - согласно оценщику, моя реализация связанного списка не круглая.

Я считаю, что оценка немного резкая. Если смотреть со стороны , ваш класс ведет себя циклически: он может добавлять новые значения за время O (1), а «последнее» значение имеет ссылку на «первое», закрывая цикл.

Наверное, мой вопрос: каким образом это не реализовано циклически?

В действительно циклической реализации я бы не ожидалсм. понятия «голова» и «хвост».Ведь круг не имеет ни начала, ни конца.Может иметь текущий элемент со ссылками на следующий и предыдущий элементы.И, возможно, это то, что требовалось. Если смотреть изнутри , эта реализация очень похожа на стандартный список связанных ссылок с быстрым доступом к хвосту.Лучше всего спросить у грейдера!

...