// 顔質問22:ノード最後から二番目のkのリンクリスト // タイトル:入力リンクリスト、リンクリスト出力の逆数k番目のノード。ほとんどの人々の習慣を満たすために、 // この質問は、リストのエンドノードが最後から二番目のノードであること、1からカウント。例えば、リンクされたリストは、6つのノードを有し、 // スクラッチノードは、それらの値を順次1,2,3,4,5,6である開始します。このリストの3最後から二番目のノードである // ノード4の値。 書式#include <cstdioを> の#include " List.h " ListNode * FindKthToTail(ListNode * pListHead、符号なしのint型のk) { // 堅牢性試験1 0 2.k空リスト(無意味な) IF(pListHead nullptr A || K == == 0 ) リターンnullptr。 ListNode * pListAhead = pListHead。 ListNode * pListAfter = pListHead; // 移動するステップK-1ポインタに先行する ため(INT I = 0、I <K - 1。 ; ++ I) { もし(pListAhead-> m_pNext!= nullptr) pListAhead = pListAhead-> m_pNext。 それ以外 の戻りnullptr; } // 保つために、その後リアポインタ しばらく(pListAhead-> m_pNext!= Nullptr A) { pListAhead = pListAhead-> m_pNext。 pListAfter = pListAfter-> m_pNext。 } 返すpListAfterを。 }
// ==================== ====================テストコード // 探しtest're中間ノードリスト のボイドのTest1() { printf(" =====のTest1が開始:===== \ N " ); ListNode * pNode1 = CreateListNode(1 )。 ListNode * pNode2 = CreateListNode(2 )。 ListNode * pNode3 = CreateListNode(3 )。 ListNode * pNode4 = CreateListNode(4 )。 ListNode * pNode5 = CreateListNode(5 )。 ConnectListNodes(pNode1、pNode2)。 ConnectListNodes(pNode2、pNode3)。 ConnectListNodes(pNode3、pNode4)。 ConnectListNodes(pNode4、pNode5)。 printf(" 期待される結果:4 \ N " ); ListNode * PNODE = FindKthToTail(pNode1、2 )。 PrintListNode(PNODE)。 DestroyList(pNode1)。 } // ノードを探しているテストは、リンクリストの最後のノードで 無効にTest2() { printf(" ===== Test2をが始まる:===== \ N " ); ListNode * pNode1 = CreateListNode(1 )。 ListNode * pNode2 = CreateListNode(2 )。 ListNode * pNode3 = CreateListNode(3 )。 ListNode * pNode4 = CreateListNode(4 )。 ListNode * pNode5 = CreateListNode(5 )。 ConnectListNodes(pNode1、pNode2)。 ConnectListNodes(pNode2、pNode3)。 ConnectListNodes(pNode3、pNode4)。 ConnectListNodes(pNode4、pNode5)。 printf(" 期待される結果:5 \ N " ); ListNode * PNODE = FindKthToTail(pNode1、1 )。 PrintListNode(PNODE)。 DestroyList(pNode1)。 } // ノードを探しているテストは、リスト内の最初のノードで のボイド)Test3は( { printf(" ===== Test3はを開始します。===== \ N " ); ListNode * pNode1 = CreateListNode(1 )。 ListNode * pNode2 = CreateListNode(2 )。 ListNode * pNode3 = CreateListNode(3 )。 ListNode * pNode4 = CreateListNode(4 )。 ListNode * pNode5 = CreateListNode(5 )。 ConnectListNodes(pNode1、pNode2)。 ConnectListNodes(pNode2、pNode3)。 ConnectListNodes(pNode3、pNode4)。 ConnectListNodes(pNode4、pNode5)。 printf(" 期待される結果:1。\ n個" ); ListNode * PNODE = FindKthToTail(pNode1、5 )。 PrintListNode(PNODE)。 DestroyList(pNode1)。 } // テストリストの空 のボイドTEST4() { printf(" ===== TEST4が開始:===== \ N " ); printf(" 期待される結果:nullptr \ N " ); ListNode * PNODE = FindKthToTail(nullptr、100 )。 PrintListNode(PNODE)。 } // 二番目のパラメータの数は、テスト入力ノードリストよりも大きい 空隙TEST5が行われるべきです() { printf(" ===== TEST5が開始:===== \ N " ); ListNode * pNode1 = CreateListNode(1 )。 ListNode * pNode2 = CreateListNode(2 )。 ListNode * pNode3 = CreateListNode(3 )。 ListNode * pNode4 = CreateListNode(4 )。 ListNode * pNode5 = CreateListNode(5 )。 ConnectListNodes(pNode1、pNode2)。 ConnectListNodes(pNode2、pNode3)。 ConnectListNodes(pNode3、pNode4)。 ConnectListNodes(pNode4、pNode5)。 printf(" 期待される結果:nullptr \ N " ); ListNode * PNODE = FindKthToTail(pNode1、6 )。 PrintListNode(PNODE)。 DestroyList(pNode1)。 } // 第二のテスト入力パラメータが0である ボイド)(TEST6 { printf(" ===== TEST6が開始:===== \ N " ); ListNode * pNode1 = CreateListNode(1 )。 ListNode * pNode2 = CreateListNode(2 )。 ListNode * pNode3 = CreateListNode(3 )。 ListNode * pNode4 = CreateListNode(4 )。 ListNode * pNode5 = CreateListNode(5 )。 ConnectListNodes(pNode1、pNode2)。 ConnectListNodes(pNode2、pNode3)。 ConnectListNodes(pNode3、pNode4)。 ConnectListNodes(pNode4、pNode5)。 printf(" 期待される結果:nullptr \ N " ); ListNode * PNODE = FindKthToTail(pNode1、0 ); PrintListNode(PNODE)。 DestroyList(pNode1)。 } INTメイン(int型 ARGC、CHAR * ARGV []) { TEST1(); TEST2(); TEST3(); TEST4(); TEST5(); TEST6(); リターン 0 ; }
分析:2つのポインタが一度数を減らして行きます。
/ * 構造体ListNode { int型のval; 次のstruct ListNode *; ListNode(int型x)は: ヴァル(x)は、次の(NULL){ } }。* / クラスソリューション{ パブリック: ListNode * FindKthToTail(ListNode * pListHead、符号なし整数のK){ もし(pListHead == nullptr || K == 0 ) 戻りnullptr。 ListNode * pListAhead = pListHead。 ListNode * pListAfter = pListHead。 用(INT iは= 0 ; I <K- 1 ; ++ I) { もし(pListAhead->次の!= nullptr) pListAhead = pListAhead-> 次。 それ以外 の戻りnullptr; } しばらく(pListAhead->次の!= nullptr) { pListAhead = pListAhead-> 次。 pListAfter = pListAfter-> 次。 } 返すpListAfterを。 } }。