找出BST中第k大的数:
如果中序遍历BST(左子树->根节点->右子树)可以得到从小到大的数字序列。要求第k大的元素,得到从大到小的数字序列最好了。根据前面的提示访问顺序为右子树->根节点->左子树时得到从大到小的数字序列。
不过为了求取第k大的数,可以在访问完之后,将计数器自增 count++,如果count等于k输出这个数。大于k时返回错误。
struct Node {
int val;
struct Node *left;
struct Node *right;
} Node;
int kth_largest(Node *root, unsigned int k);
下边是树的递归遍历了,不过我们不用输出一个节点,只要计数就行了。
int count = 0;
int kth_largest(Node root,int k)
{
if (root)
{
kth_largest(root->right,k);
// (*visit)(root); 这里本来是输出遍历的节点的 不过不做要求
//下面用计数器来统计第count大的数
count++;
if(count == k){
printf("%d",root->val);
return 1;
}
kth_largest(root->left,k);
}
//遍历完毕之后发现数字的总数小于k 报错
if(count<k)
return -1;
}
以上是递归的方法,还有非递归的方法。其实前一篇文章中已经涉及到了:http://blog.csdn.net/f81892461/article/details/8639289
简单说下思路:从根节点到最右端的节点,逐个入栈,此时出栈的第一个节点肯定为最大值,k--,若k为0,输出这个值后退出,否则继续看从大到小的序列中第一个比b小的节点(在左子树非空情况下,b的左子树入栈,左子树的右节点全部入栈。如果为空,继续出栈,重复以上操作。)
int Node * kth_largest(Node *root, unsigned int k){
Node *b = root;
while (b)
{
bstack.push(b);
b = b->right;
}
while (!bstack.empty())
{
b = bstack.pop();
k--;
if (k == 0){
printf("%d",b->val);
return 1;
}
if (b->left){
b = b->left;
while (b)
{
bstack.push(b);
b = b->right;
}
}
}
return -1;
}
如果要返回该节点,只要在k==0时返回b即可。