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);
}