题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
leetcode对应题目:230. 二叉搜索树中第K小的元素 题目解答
总结:
- 二叉搜索树所以想到用中序遍历。
- 如果这个树涉及到频繁的插入和删除怎么办?我们应该修改原树结点的结构(在题目解答里面有),使其保存包括当前结点和其左右子树所有结点的个数。这样我们使用的时候就可以快速得到任何左子树结点总数来帮我们快速定位目标值了。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if(!pRoot || k<=0) return nullptr;
stack<TreeNode*> s;
TreeNode* p = pRoot;
while(p || !s.empty()){
if(p){
s.push(p);
p = p->left;
}
else{
p = s.top();s.pop();
k--;
if(k == 0) return p;
p = p->right;
}
}
return nullptr;
}
};
如果不用中序遍历怎么做?
计算左子树的结点个数,等于k-1就表示root为需要的结点,小于,则在右边继续查找k-n,大于,则在左子树继续找第k个节点。
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
if(!root || k<=0) return -1;
int n = getTreeNode(root->left);
if(n == k-1) return root->val;
else if(n > k-1) return kthSmallest(root->left,k);
else return kthSmallest(root->right,k-n-1);
}
int getTreeNode(TreeNode* node){
if(!node) return 0;
return (getTreeNode(node->left) + getTreeNode(node->right))+1;
}
};