题目
给定一颗二叉搜索树,请找出其中的第k大的结点。
思路
如果中序遍历一棵二叉搜索树,遍历序列的数值则是递增排序,因此只需中序遍历一个二叉搜索树即可。
中序遍历用递归实现比较容易,但要想清楚的是遍历到一个根结点的时候要做的是什么?中序遍历二叉树打印的时候我们在递归完左子树之后打印根结点,本题目要求的当然不是打印,如果左子结点不是要找的结点,才会访问根结点,所以访问到根结点的时候要做的操作是将k减去1,因为左子结点已经证实不是要找的结点了,排除左子结点。这个过程可以看成目标移位的过程,每移过一个结点,K减1,直到K等于1时,当前结点就是要求的结点。
#include <iostream> using namespace std; struct tree { double data; struct tree *left,*right; tree(int d=0):data(d) { left=right=nullptr; } }; class Solution { public: void create(tree *&root); tree *kth_node(tree * root,unsigned int k); tree *kth_node_core(tree *root,unsigned int &k); tree *root; }; void Solution::create(tree *&root) { double x; cin>>x; if(x==0) root=nullptr; else { root=new tree(); root->data=x; create(root->left); create(root->right); } } tree *Solution::kth_node(tree *node,unsigned int k) { if(!node||k<=0) return nullptr; return kth_node_core(node,k); } tree *Solution::kth_node_core(tree *node,unsigned int &k) { tree *target=nullptr; if(node->left)//遍历左子树 target=kth_node_core(node->left,k); if(!target) { if(k==1) target=node; --k; } if(!target&&node->right)//右子树 target=kth_node_core(node->right,k); return target; } int main() { Solution s; s.create(s.root); tree *node=s.kth_node(s.root,4); if(node) cout<<node->data<<endl; return 0; }