带计数器的递归有序遍历
Time Complexity: O( N ), N is the number of nodes
Space Complexity: O( 1 ), excluding the function call stack
这个想法类似于@prasadvk 解决方案,但它有一些缺点(见下面的注释),所以我将其作为单独的答案发布。
// Private Helper Macro
#define testAndReturn( k, counter, result ) \
do { if( (counter == k) && (result == -1) ) { \
result = pn->key_; \
return; \
} } while( 0 )
// Private Helper Function
static void findKthSmallest(
BstNode const * pn, int const k, int & counter, int & result ) {
if( ! pn ) return;
findKthSmallest( pn->left_, k, counter, result );
testAndReturn( k, counter, result );
counter += 1;
testAndReturn( k, counter, result );
findKthSmallest( pn->right_, k, counter, result );
testAndReturn( k, counter, result );
}
// Public API function
void findKthSmallest( Bst const * pt, int const k ) {
int counter = 0;
int result = -1; // -1 := not found
findKthSmallest( pt->root_, k, counter, result );
printf("%d-th element: element = %d\n", k, result );
}
注意事项(以及与@prasadvk 解决方案的区别):
if( counter == k ) 需要在 三个 处进行测试:(a) 在左子树之后,(b) 在根之后,和 (c) 在右子树之后。这是为了确保为所有位置检测到第 k 个元素,即不管它位于哪个子树。
需要if( result == -1 ) 测试以确保只打印结果元素,否则打印从第 k 个最小元素到根的所有元素。