循环链表帮助(Java)

循环链表帮助(Java),java,linked-list,circular-list,Java,Linked List,Circular List,我正在做的一个程序有点困难。我试着从我的一些同龄人那里得到帮助,但我们无法找到答案。我相信这很简单,但我没有足够的经验在我的一次经历中弄清楚。这是作业: 在一个古老的国度,美丽的夏娃公主有许多追求者。她决定按照以下程序来决定嫁给哪个求婚者。首先,所有的求婚者将一个接一个地排好队,并分配号码。第一个求婚者是1号,第二个求婚者是2号,依此类推,最后一个求婚者是n号。从第一个位置的求婚者开始,她会数到队伍中的三个求婚者(因为她名字中有三个字母),第三个求婚者将被淘汰出局。伊芙接着说,再数到三个求婚者,

我正在做的一个程序有点困难。我试着从我的一些同龄人那里得到帮助,但我们无法找到答案。我相信这很简单,但我没有足够的经验在我的一次经历中弄清楚。这是作业:

在一个古老的国度,美丽的夏娃公主有许多追求者。她决定按照以下程序来决定嫁给哪个求婚者。首先,所有的求婚者将一个接一个地排好队,并分配号码。第一个求婚者是1号,第二个求婚者是2号,依此类推,最后一个求婚者是n号。从第一个位置的求婚者开始,她会数到队伍中的三个求婚者(因为她名字中有三个字母),第三个求婚者将被淘汰出局。伊芙接着说,再数到三个求婚者,每三个求婚者就被淘汰一次。当她走到队伍的尽头时,她会继续从头开始数数

例如,如果有六名申请人,则淘汰过程将按如下方式进行:

123456   Initial list of suitors: start counting from 1.
12456       Suitor 3 eliminated:  continue counting from 4.
1245        Suitor 6 eliminated:  continue counting from 1.
125     Suitor 4 eliminated:  continue counting from 5.
15      Suitor 2 eliminated:  continue counting from 5.
1       Suitor 5 eliminated:  1 is the lucky winner.
编写一个程序,创建节点的循环链接列表,以确定如果有n个求婚者,你应该站在哪个位置与公主结婚。您的程序应该通过删除与过程中每个步骤中被消除的追求者对应的节点来模拟消除过程

以下是我目前掌握的情况:

    public class CircularLinkedList
    {
      private class Node
      {
        private int candidate;
        private Node next;
        public Node()
        {
          candidate = 0;
          next = null;
        }
        public Node(int newCandidate)
        {
          candidate = newCandidate;
          next = null;
        }
        public Node(int newCandidate, Node nextValue)
        {
          candidate = newCandidate;
          next = nextValue;
        }
      }//end inner class
      private Node first;
      private Node last;
      public CircularLinkedList()
      {
        first = null;
        last = null;
      }
      public boolean isEmpty() //checks to see if the list is empty
      {
        return first == null;
      }
      public int size() //checks the size
      {
        int count = 0; 
        Node p = first;
        while(p != last)
        {
          count++;
          p = p.next;
        } 
        return count;
      }
      public void add(int e) //adds a Node to the list
      {
        Node newEntry = new Node(e, first);
        if(first==null)
        {
          last = newEntry;
          first = last;
        }
        else
        {
          last.next = newEntry;
          last = last.next;
        }
      }
      public void removeAfter(Node e) //removes the Node after the current Node
      {
        e.next = e.next.next;
      }
      public void remove() //removes every third Node 
      {
        Node curNode = first;
        int size = size();
        while(size>1)
        {
          curNode = curNode.next;
          removeAfter(curNode);
          size -= 1;
        }
      }
      public void print() //prints the list
      {
        Node ref = first;
        for(int index = -1;index<size();index++)
        {
          System.out.print(ref.candidate + " ");
          ref = ref.next;
        }
      }
    }

编辑1-在删除中循环时更新。输出已更新。

尝试将最后一个节点分配给第一个节点,使其成为循环链接列表。(Assigning last.next=first in add())

下面是它的要点,使用OOP方法和一些输入验证

public class SuitorProblem
{
    public static void main(String[] args)
    {

        Scanner sc = new Scanner(System.in);
        int totalSuitors = 0;
        boolean goodInput;
        System.out.print("Enter the number of suitors: ");

        //************************************  INPUT VALIDATION  ***********************************************
        do
        {
            try
            {
                totalSuitors = sc.nextInt();
                while (totalSuitors <= 0)
                {
                    System.out.print("Enter a positive integer value greater than 0: ");
                    totalSuitors = sc.nextInt();
                }
                goodInput = true;
            }
            catch (InputMismatchException e)        //  if not integer, prompt the user to go back
            {
                System.out.print("Enter a positive integer value greater than 0: ");
                sc.nextLine();                      //  clear input
                goodInput = false;
            }
        } while (!goodInput);
        //********************************************************************************************************


        ListOfSuitors suitorList = new ListOfSuitors();
        for (int i = 1; i <= totalSuitors; i++)
            suitorList.addEnd(i);

        System.out.print("Before elimination process, the line-up of suitors is: ");
        System.out.print(suitorList.toString());
        System.out.println();

        suitorList.deleteSuitors();
        System.out.print("After  elimination process, the winning suitor is: ");
        System.out.print(suitorList.toString());
    }
}


    //  I use an extension of CircularLinkedList of type Integer, so I can have access to the methods in CircularLinkedList to manipulate the ListOfSuitors, which is a LinkedList of ints.
class ListOfSuitors extends CircularLinkedList<Integer>
{

    //  default constructor
    public ListOfSuitors()
    {
    }

    // This method is used to find the next index that needs to be deleted
    private int findIndexOfLoser(int element)
    {
        Node<Integer> current = head;
        int index = 0;
        while (current.element != element)
        {
            current = current.next;
            index++;
        }
        return index;
    }

    //  This method counts 3 spaces over then deletes a suitor by calling the delete method on the deletionIndex
    public void deleteSuitors()
    {
        Node<Integer> current = head;
        while (size != 1)
        {
            for (int i = 1; i < 3; i++)
            {
                current = current.next;
            }
            int deletionIndex = findIndexOfLoser(current.element);
            current = current.next;
            delete(deletionIndex);
        }
    }
}

    //  This is the generic circular linkedList that I extend my ListOfSuitors class from, and which holds the methods needed to manipulate the ListOfSuitors
class CircularLinkedList<E>
{

    //  since these will only be accessed by the subclass listOfSuitors, they are declared protected to increase security.
    protected Node<E> head = null;
    protected Node<E> tail = null;
    protected int size;

    public CircularLinkedList()
    {

    }

    //  method for adding a new end Node in circularLinkedList
    public void addEnd(E element)                                       //  adapted from ch24 PowerPoint
    {
        if (size == 0)
        {
            head = tail = new Node<E>(element, head);
        }
        else
        {
            tail = tail.next = new Node<E>(element, head);
        }
        size++;
    }

    //  Method for deleting a Node at a specified index in the circularLinkedList. May cause IndexOutOfBounds, so that must be handled within the method
    public void delete(int index)
    {
        if (index < 0 || index > size - 1)
            throw new IndexOutOfBoundsException("That's not a correct index.");
        else if (index == 0)
            deleteFirst();
        else if (index == size - 1)
            deleteEnd();
        else
        {
            Node<E> previous = head;
            Node<E> current = head.next;
            for (int i = 1; i < index; i++)
            {
                previous = previous.next;
                current = current.next;
            }
            previous.next = current.next;
            current.next = null;
            size--;
        }
    }

    //  method for deleting the end Node in circularLinkedList
    public void deleteEnd()
    {
        if (size == 1)
        {
            head = tail;
            tail.next = null;
        } else if (size > 1)
        {
            Node<E> current = head;
            while (current.next != tail)
                current = current.next;
            tail.next = null;
            current.next = head;
            tail = current;
        }
        size--;
    }

    //  method for deleting the first Node in circularLinkedList
    public void deleteFirst()
    {
        if (size == 1)
        {
            head = tail;
            tail.next = null;
        } else if (size > 1)
        {
            Node<E> current = head;
            head = head.next;
            current.next = null;
            tail.next = head;
        }
        size--;
    }

    //  In this method, I create my own toString in order to elegantly print the output of the suitorList in an efficient way, using StringBuilder.
    public String toString()
    {
        Node<E> current = head;
        StringBuilder suitorList = new StringBuilder();

        if (size >= 1)
        {
            suitorList.append(current.element);
            current = current.next;
        }
        for (int i = 1; i < size; i++)
        {
            suitorList.append(" ").append(current.element.toString());
            current = current.next;
        }
        return suitorList.toString();
    }
}

//  this class is for the Node, which is what each int suitor is turned into when it is added to the ListOfSuitors
class Node<E>
{

    protected E element = null;
    protected Node<E> next = null;

    //  default constructor
    public Node()
    {

    }

    //  overloaded constructor
    public Node(E element, Node<E> next)
    {
        this.element = element;
        this.next = next;
    }

    public Node(E element)
    {
        this.element = element;
    }

    public Node(Node<E> next)
    {
        this.next = next;
    }
}
公共类诉讼问题
{
公共静态void main(字符串[]args)
{
扫描仪sc=新的扫描仪(System.in);
int TotalSuiters=0;
布尔输入;
System.out.print(“输入求婚者人数:”);
//************************************输入验证***********************************************
做
{
尝试
{
TotalSuiters=sc.nextInt();
while(TotalSuiters 1)
{
节点电流=头;
while(current.next!=tail)
当前=当前。下一步;
tail.next=null;
当前。下一个=头部;
尾=电流;
}
大小--;
}
//删除循环链接列表中第一个节点的方法
public void deleteFirst()
{
如果(大小==1)
{
头=尾;
tail.next=null;
}否则,如果(大小>1)
{
节点电流=头;
head=head.next;
current.next=null;
tail.next=头部;
}
大小--;
}
//在这种方法中,我使用StringBuilder创建自己的toString,以便以高效的方式优雅地打印SuiterList的输出。
公共字符串toString()
{
节点电流=头;
StringBuilder SuiterList=新建StringBuilder();
如果(大小>=1)
{
suiterlist.append(当前的.element);
当前=当前。下一步;
}
对于(int i=1;i
如果它是循环的,你应该对照
头部检查。如果
curr
头部,你已经做了一个循环。我更新了delete()方法。我得到了不同的输出,所以有了进展。
    How many candidates are there?
    6 //user input
    The candidates are: 1 2 3 4 5 6
    5 //output for size()
    1 2 6 //output first time through while loop
    //output for winner still not showing up
public class SuitorProblem
{
    public static void main(String[] args)
    {

        Scanner sc = new Scanner(System.in);
        int totalSuitors = 0;
        boolean goodInput;
        System.out.print("Enter the number of suitors: ");

        //************************************  INPUT VALIDATION  ***********************************************
        do
        {
            try
            {
                totalSuitors = sc.nextInt();
                while (totalSuitors <= 0)
                {
                    System.out.print("Enter a positive integer value greater than 0: ");
                    totalSuitors = sc.nextInt();
                }
                goodInput = true;
            }
            catch (InputMismatchException e)        //  if not integer, prompt the user to go back
            {
                System.out.print("Enter a positive integer value greater than 0: ");
                sc.nextLine();                      //  clear input
                goodInput = false;
            }
        } while (!goodInput);
        //********************************************************************************************************


        ListOfSuitors suitorList = new ListOfSuitors();
        for (int i = 1; i <= totalSuitors; i++)
            suitorList.addEnd(i);

        System.out.print("Before elimination process, the line-up of suitors is: ");
        System.out.print(suitorList.toString());
        System.out.println();

        suitorList.deleteSuitors();
        System.out.print("After  elimination process, the winning suitor is: ");
        System.out.print(suitorList.toString());
    }
}


    //  I use an extension of CircularLinkedList of type Integer, so I can have access to the methods in CircularLinkedList to manipulate the ListOfSuitors, which is a LinkedList of ints.
class ListOfSuitors extends CircularLinkedList<Integer>
{

    //  default constructor
    public ListOfSuitors()
    {
    }

    // This method is used to find the next index that needs to be deleted
    private int findIndexOfLoser(int element)
    {
        Node<Integer> current = head;
        int index = 0;
        while (current.element != element)
        {
            current = current.next;
            index++;
        }
        return index;
    }

    //  This method counts 3 spaces over then deletes a suitor by calling the delete method on the deletionIndex
    public void deleteSuitors()
    {
        Node<Integer> current = head;
        while (size != 1)
        {
            for (int i = 1; i < 3; i++)
            {
                current = current.next;
            }
            int deletionIndex = findIndexOfLoser(current.element);
            current = current.next;
            delete(deletionIndex);
        }
    }
}

    //  This is the generic circular linkedList that I extend my ListOfSuitors class from, and which holds the methods needed to manipulate the ListOfSuitors
class CircularLinkedList<E>
{

    //  since these will only be accessed by the subclass listOfSuitors, they are declared protected to increase security.
    protected Node<E> head = null;
    protected Node<E> tail = null;
    protected int size;

    public CircularLinkedList()
    {

    }

    //  method for adding a new end Node in circularLinkedList
    public void addEnd(E element)                                       //  adapted from ch24 PowerPoint
    {
        if (size == 0)
        {
            head = tail = new Node<E>(element, head);
        }
        else
        {
            tail = tail.next = new Node<E>(element, head);
        }
        size++;
    }

    //  Method for deleting a Node at a specified index in the circularLinkedList. May cause IndexOutOfBounds, so that must be handled within the method
    public void delete(int index)
    {
        if (index < 0 || index > size - 1)
            throw new IndexOutOfBoundsException("That's not a correct index.");
        else if (index == 0)
            deleteFirst();
        else if (index == size - 1)
            deleteEnd();
        else
        {
            Node<E> previous = head;
            Node<E> current = head.next;
            for (int i = 1; i < index; i++)
            {
                previous = previous.next;
                current = current.next;
            }
            previous.next = current.next;
            current.next = null;
            size--;
        }
    }

    //  method for deleting the end Node in circularLinkedList
    public void deleteEnd()
    {
        if (size == 1)
        {
            head = tail;
            tail.next = null;
        } else if (size > 1)
        {
            Node<E> current = head;
            while (current.next != tail)
                current = current.next;
            tail.next = null;
            current.next = head;
            tail = current;
        }
        size--;
    }

    //  method for deleting the first Node in circularLinkedList
    public void deleteFirst()
    {
        if (size == 1)
        {
            head = tail;
            tail.next = null;
        } else if (size > 1)
        {
            Node<E> current = head;
            head = head.next;
            current.next = null;
            tail.next = head;
        }
        size--;
    }

    //  In this method, I create my own toString in order to elegantly print the output of the suitorList in an efficient way, using StringBuilder.
    public String toString()
    {
        Node<E> current = head;
        StringBuilder suitorList = new StringBuilder();

        if (size >= 1)
        {
            suitorList.append(current.element);
            current = current.next;
        }
        for (int i = 1; i < size; i++)
        {
            suitorList.append(" ").append(current.element.toString());
            current = current.next;
        }
        return suitorList.toString();
    }
}

//  this class is for the Node, which is what each int suitor is turned into when it is added to the ListOfSuitors
class Node<E>
{

    protected E element = null;
    protected Node<E> next = null;

    //  default constructor
    public Node()
    {

    }

    //  overloaded constructor
    public Node(E element, Node<E> next)
    {
        this.element = element;
        this.next = next;
    }

    public Node(E element)
    {
        this.element = element;
    }

    public Node(Node<E> next)
    {
        this.next = next;
    }
}