链表 2.2

实现一个算法,找出单向链表中倒数第k个结点。

分析:使用相差k个位置的两个指针,以相同的速度遍历链表,当快指针为空时,慢指针刚好指向链表的倒数第k个结点。时间复杂度O(n),空间复杂度O(1)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <assert.h>
 4 
 5 using namespace std;
 6 
 7 struct Node {
 8     Node(): val(0), next(0) {}
 9     Node( int aval ): val(aval), next(0) {}
10     int val;
11     Node *next;
12 };
13 
14 Node* findLastKth( Node *node, int k );
15 
16 int main( int argc, char *argv[] ) {
17     string data_file = "./2.2.txt";
18     ifstream ifile( data_file.c_str(), ios::in );
19     if( !ifile.is_open() ) {
20         fprintf( stderr, "cannot open file: %s
", data_file.c_str() );
21         return -1;
22     }
23     int n = 0, k = 0;
24     while( ifile >>n >>k ) {
25         assert( n >= 0 );
26         Node guard, *node = &guard;
27         for( int i = 0; i < n; ++i ) {
28             node->next = new Node();
29             node = node->next;
30             ifile >>node->val;
31             cout <<node->val <<" ";
32         }
33         cout <<endl;
34         node = findLastKth( guard.next, k );
35         if( node ) {
36             printf( "last %dth node is: %d
", k, node->val );
37         } else {
38             printf( "last %dth node is: null", k );
39         }
40         node = guard.next;
41         while( node ) {
42             Node *next = node->next;
43             delete node;
44             node = next;
45         }
46         cout <<endl <<endl;
47     }
48     ifile.close();
49     return 0;
50 }
51 
52 Node* findLastKth( Node *node, int k ) {
53     Node *slow = node, *fast = node;
54     for( int i = 0; i < k; ++i ) {
55         if( !fast ) { return 0; }
56         fast = fast->next;
57     }
58     while( fast ) {
59         slow = slow->next;
60         fast = fast->next;
61     }
62     return slow;
63 }

测试文件

0 0

0 1

1 0
1

1 1
1

1 2
1

2 0
1 3

2 1
1 3

2 2
1 3

2 3
1 3

7 1
14 54 96 23 45 12 45

7 2
14 54 96 23 45 12 45

7 7
14 54 96 23 45 12 45
原文地址:https://www.cnblogs.com/moderate-fish/p/3980126.html