問題
入口リングリングが得られたとしても、単環リンクリストが存在するか否かを検出するアルゴリズムを実行します。
分析
(また、「ウサギとカメ」と呼ばれる)ポインター方法の速度、それぞれが速い2つずつ、リングがある場合、彼らは会う予定ポインターを移動、遅いポインタを移動:リングがかどうかを確認します。
エントリを求めてリング:到着位置、ポインタのヘッドブロックポインタの移動位置、移動局が、位置の両方が再び流入環を満たすされるたびに満たします。
なぜ?
(第一「借りた」マップ
初めて出会う、ポインタの$ X +のk $、速い歩行ポインタの$ X + K + MR $($ R $は、ループの長さであり、$ Mは\のGEQ 1 $)が遅く、
そして、ポインタの速い速度が二倍遅くポインタであるため、$ 2(X + K)= X + K +ミスター$。
、$ X = MR-k個の$($ Mが\のGEQ 1 $)を即
遅いポインタは$ K $を有する、ブロックポインタが$ Xの$上にさらに一歩、0に設定されている、彼らは、入口リングを満たします。
する#include <stdio.hに> する#include <stdbool.h> のtypedef 構造体ノード{ int型の値。 構造体のノード* 次の; }ノード。 ブール ll_has_cycle(ノード* ヘッド){ 場合(ヘッド== NULL) を返す 偽。 ノード * HAR = ヘッド。 ノード * TOR = ヘッド。 一方、(1 ) { 場合(!tor->次= NULL)TOR = tor-> ;次 それ以外の 返し はfalse ; もし(!har->次= NULL && har->ネクスト>次= NULL)HAR = har->ネクスト> 次; それ以外の 返し はfalse ; もし(TOR == HAR) を返す 真。 } } int型 find_cycle_entrance(ノード* ヘッド){ 場合(ヘッド== NULL) リターン - 1 。 ノード * HAR = ヘッド。 ノード * TOR = ヘッド。 一方、(1 ) { 場合(!tor->次= NULL)TOR = tor-> ;次 他の リターン - 1; もし(!har->次= NULL && har->ネクスト>次= NULL)HAR = har->ネクスト> 次; 他の リターン - 1 。 もし(TOR == HAR) { HAR = ヘッド。 一方、(HAR =!TOR) { HAR = har-> 次。 TOR = tor-> 次。 } 戻り har-> 値。 } } } ボイド test_ll_has_cycle(ボイド){ int型私; ノードノード[ 25 ]。// 我々のテストを実行するのに十分な ため(i = 0 ; iが< はsizeof(ノード)/ はsizeof(ノード); iが++ ){ ノード[i]は.next = 0 。 ノード[i]は.VALUE = I。 } ノード[ 0 ] .next =&ノード[ 1 ]。 ノード[ 1 ] .next =&ノード[ 2 ]。 ノード[ 2 ] .next =&ノード[ 3 ]。 printf("サイクルの最初のリストを確認します。どれもあってはならない、ll_has_cycleは、%sのサイクル\ nを持っていると言う"ll_has_cycleを(&ノード[ 0 ])?" ":" いいえ" ); のprintf(" Entranc:%dは\ nを"、find_cycle_entrance(&ノード[ 0 ] )); ノード[ 4 ] .next =&ノード[ 5 ]、 ノード[ 5 ] .next =&ノード[ 6 ]、 ノード[ 6 ] .next =&ノード[ 7 ]、 ノード[ 7 ] .next =&ノード[ 8 ] ; 8 ] .next =&ノード[ 9 ]。 ノード[ 9 ] .next =&ノード[ 10 ]。 ノード[ 10 ] .next =&ノード[ 4 ]。 printf関数は、(" サイクルの第二のリストを確認するサイクルがあるはず、ll_has_cycleは、%sのサイクル\ nを持っていると言い、"(&、ll_has_cycleをノード[ 4 ])?" ":" いいえ" ); printf(" Entranc:%Dを\ n "、find_cycle_entrance(&ノード[ 4 ]))。 ノード[ 11 ] .next =&ノード[ 12 ノード[ 12 ] .next =&ノード[ 13 ]。 ノード[ 13 ] .next =&ノード[ 14 ]。 ノード[ 14 ] .next =&ノード[ 15 ]。 ノード[ 15 ] .next =&ノード[ 16 ]。 ノード[ 16 ] .next =&ノード[ 17 ]。 ノード[ 17 ] .next =&ノード[ 14 ]。 printf(" サイクルのための第三のリストを確認する。サイクルがあるはず、ll_has_cycleは、それが%sのサイクル\ nを持っていると言う"、ll_has_cycle(&ノード[ 11 ])?" A ":" いいえ" ); printf(" Entranc:%Dを\ n "、find_cycle_entrance(&ノード[ 11 ]))。 ノード[ 18 ] .next =&ノード[ 18 ]。 printf(" サイクルのための第四のリストを確認するサイクルがあるはず、ll_has_cycleは、それが%sのサイクル\ nを持っていると言います。"、ll_has_cycle(&ノード[ 18 ])?" A ":" いいえ" ); printf(" Entranc:%Dを\ n "、find_cycle_entrance(&ノード[ 18 ]))。 ] .next =&ノード[ 20 ]。 ノード[ 20 ] .next =&ノード[ 21 ]。 ノード[ 21 ] .next =&ノード[ 22 ]。 ノード[ 22 ] .next =&ノード[ 23 ]。 printf関数は、(" サイクルの第五のリストを確認するどれがあってはならない、ll_has_cycleは、%sのサイクル\ nを持っていると言い、"(&、ll_has_cycleをノード[ 19 ])?" ":" いいえ" ); printf(" Entranc:%Dを\ n "、find_cycle_entrance(&ノード[ 19 ]))。 printf(" サイクルの長さゼロのリストを確認する何があってはならない、ll_has_cycleは、%sのサイクル\ nを持っていると言う"?、ll_has_cycle(NULL)" A ":" なしの" ); printf(" Entranc:%Dを\ n " 、find_cycle_entrance(NULL))。 } int型のmain(){ test_ll_has_cycle()。 リターン 0 ; }
参考リンク:https://blog.csdn.net/qq_36781505/article/details/91401474