JAVAデータ構造-04一方向循環リンクリストはジョセフの問題を解決します

JAVAデータ構造-04一方向循環リンクリストはジョセフの問題を解決します

問題の説明:num人の個人が円を形成し、最初から数え始め、k番目に円を終了し、円の順序を見つけます。

一方向の循環リンクリストを作成する

アイデア

  • 最初に最初のノードを作成し、このノードの次のポインターフィールドがそれ自体を指すようにして、リングを形成します
  • 後で新しいノードを作成するときに、そのノードを既存の循環リストに追加します。
  • トラバースするときは、トラバースサークルの終わりの条件を決定します。temp.next==最初に

データノード

class Child{
    
    
    public int no;
    public Child next;

    public Child(int no) {
    
    
        this.no = no;
    }
    @Override
    public String toString() {
    
    
        return "Child{" +
                "no=" + no +
                '}';
    }
}

一方向の循環リンクリスト構造を構築します。

class CircleSingleLinkedList{
    
    
    //创建第一个节点
    Child first;
    //添加指定个数的节点
    public void addChile(int num){
    
    
        if(num <1 ){
    
    
            System.out.println("num 错误");
            return ;
        }
        //创建一个单节点环形链表
        first = new Child(1);
        first.next = first;
        //添加指定个数的元素
        Child temp = first;
        for (int i = 2; i <= num ; i++) {
    
    
            Child child = new Child(i);
            temp.next = child;
            child.next = first;
            temp = temp.next;
        }
    }

    //遍历一圈
    public void showList(){
    
    
        if(first == null){
    
    
            System.out.println("链表为空");
            return ;
        }
        Child temp = first;
        while (true){
    
    
            System.out.println(temp);
            if(temp.next == first) break;
            temp = temp.next;
        }
    }
}

kの値に従って、ラップを終了するシーケンスを完了します

アイデア

  • 単一リンクリストが(円の外の)ノードを削除する場合、削除するノードの前の位置へのポインターを指す必要があるためです。
  • したがって、カウントを報告する子の前の位置を指す補助ポインターtempを作成する必要があります。したがって、初期化中に、tempは最初のポインター(循環キューの最後の要素)の前の位置を指します。
    • 次に、tempをstart-1の位置に移動し、数値の報告を開始する要素の前の位置に移動します。
  • 子供がカウントを報告したら、一時ポインタをk-1単位前方に移動して、事前に削除されたノードの前の位置に到達させてから、ノードを円の外に出します。
    • temp.next = temp.next.next;
  • リンクリストにノードが1つしかない場合、この時点でtemp = temp.nextの場合、サイクルはこの時点で終了し、キューの最後のノードは円の外にあります。
/**
 *
 * @param start 从第几个位置开始
 * @param k    数几下
 * @param num   有多少小孩
 */
public void excuteJosephu(int start,int k,int num){
    
    
    //添加小孩
    addChile(num);
    //
    System.out.println("出圈前队列:");
    showList();
    //初始化:让temp指向 start的前一个位置(队列末尾)
    Child temp = first;
    while (temp.next != first){
    
    
        temp = temp.next;
    }
    for (int i = 0; i < start-1 ; i++) {
    
    
        temp = temp.next;
    }
    //
    System.out.println("开始出圈:");
    while(true){
    
    
        if(temp.next == temp) break; //当链表中只有一个值时结束寻新欢
        for (int i = 0; i <k-1 ; i++) {
    
    
            temp = temp.next;
        }
        //将temp节点的下一个节点出圈
        Child out = temp.next;
        temp.next = temp.next.next;
        System.out.println("出圈节点"+out);
    }
    //将循环链表中最后一个元素出圈
    System.out.println("最后出圈节点"+temp);
}

おすすめ

転載: blog.csdn.net/weixin_44634197/article/details/108430655