12

これは課題です。循環リンクリストを作成し、リスト内の3つおきの番号を削除する必要があります。私のプログラムがリストの最後に達すると、先頭に戻り、1つの番号だけが残るまでプロセスを続行する必要があります。

オンラインや他の参考書を検索しましたが、問題を解決できませんでした。私が見つけた参考文献のほとんどは、次のようなことを言っています。

循環リストには終わりがないという事実を除けば、通常のリストとまったく同じです。

または(私の教科書から引用):

最後のノードの後継が最初のノードである場合、単一リンクリストは循環リンクされます

しかし、これらはそれを行う方法を教えていません。このサイトで見つけたコードを使ってみましたが、何もわかりませんでした。

リストを作成して(循環リンクリストかどうかはわかりませんが)表示することはできますが、要素の順序がおかしいです。

  • リストに6つの番号がある場合、リストは1,6,5,4,3,2になります。
  • リストに8つの番号がある場合、リストは1,8,7,6,5,4,3,2になります。

正しいリストを取得しなくても、正しく削除できます。次のコードの何が問題になっていますか。

public class LastNumberDemo {
    public static void main(String[] args) {
        LastNumberNode ll=new LastNumberNode();
        System.out.println("how long is the list: ");
        Scanner keyboard = new Scanner(System.in);
        int input = keyboard.nextInt();

        if(input<=0) {
            System.out.println("no number to creat list");
        }
        if(input==1) {
            System.out.println("The Last number is 1.");
        }
        else {
            String[] n=new String[input];
            for(int index=0; index<n.length; index++)
                n[index]=Integer.toString(index+1);
            for(String e:n)
                ll.add(e);
            System.out.print("The list contains: \n");
            ll.print();
            System.out.print("\nThe last number is: ");
            ll.remove();
            ll.print();
        }
    }
}

//The circular linked list class
class LastNumberNode{
    private class Node{
        String value;  
        Node next;     

        Node(String val, Node n){
            value = val;
            next = n;
        }

        Node(String val){
            value=val;
            next=null;
        }
    } //This brace was missing - Edd

    private Node first;

    public LastNumberNode(){
      first = null;
    }

    public boolean isEmpty(){        
       return first == null;
    }

    public int size(){
        int count = 0;
        Node p = first.next;   
        while (p != first){
            count ++;
            p = p.next;
        }
        return count;
    }

    public void add(String e) {
        Node p=new Node(e);
        if(first==null){
            first=p;
            first.next=first;
        }
        else{
            first.next=new Node(e,first.next);
        }
    }

    public void remove(){
        while(size()>0){
            Node target=first.next.next;   
            Node temp=first;               
            target=target.next;          
            last.next=temp;
            first=target;
        }
    }

    public void print(){
        Node ref=first;
        for(int index=-1; index<size();index++)
            System.out.print(ref.value+" ");
        ref=ref.next;
    }
} //Extra brace removed - Edd
4

2 に答える 2

7

Nodeリストに新しいものを追加するとき、新しいものNodeを 2 番目の位置に追加します (first.next新しく追加されたノードを指します) が、この新しく追加されたノードはfirst次のノードであり、残りのリストは参照されません (したがって、ガベージ コレクションそして破壊された)。このaddままでは、リストに 0、1、または 2 以外のものを含めることはできませNodeん。Nodeリストの真ん中にnew を追加するのは少し奇妙です。それを前に追加するか(newnode.next = first; first = newnode; last.next = first;)、リストの後ろへの参照を保持して(他の人が示唆しているように)、そこに追加します。

個人的にはLastNumberNode、リンクリストを操作するための次のメソッドを持つようにクラスを再構築します。

  • private void addNode(Node node)
  • private void removeNode(Node node)
  • private Node findNode(Node nextNode)

リストの最後のノードへの参照を維持する場合、addNode(Node node)メソッドは次のようになります。

if(isEmpty()) {
    first = node;
    last = node;
}
else {
    Node tail = last;
    tail.next = node;
    node.next = first;
    last = node;
}

removeNode(Node node)以下に基づいています。

Node prevNode = findNode(node);

if(node == first) {
    first = node.next;
    last.next = first;
}
else if(node == last) {
    prevNode.next = first;
    last = prevNode;
}
else {
    prevNode.next = node.next;
}

Nodeこれを実装する場合、おそらく、この種のアプローチを使用してリストを 1 つに減らすでしょう。

public String reduceList() {
    Node curNode = first;
    while(first != last) {
        removeNode(curNode.getNext().getNext());
        curNode = curNode.getNext().getNext();
    }

    return first.getValue();
}

最後のポイントとして、配列に連続した番号を入力してから、リストに要素を追加するためにそれをたどる必要はありません。私は次のようなものにまっすぐ行きます:

for(int i = 1; i <= input; i++) {
    linkedlist.add(new Integer(i).toString());
}
于 2012-09-11T15:35:14.510 に答える
4

firstがすでに設定されている場合add、メソッドは要素を直後に挿入します。first

first.next = new Node(e, first.next);

これは、観察された動作につながります。

リストの最後の要素を追跡し、リストの最後に新しい要素last.nextを追加する場合と同様に、新しい要素を追加する必要があります。firstこれを行う 1 つの方法は、最後の要素への参照をリスト クラスのメンバ変数に単純に保存することです。別の方法は、最後のノードになるリンク先のノードが見つかるまでリストをトラバースすることです。

于 2012-09-09T12:05:40.313 に答える