您的位置:首页 > Web前端

剑指offer-二叉搜索树的第K个节点

2017-04-11 11:21 399 查看

剑指offer-二叉搜索树的第K个节点

题目描述

给定一颗二叉搜索树,请找出按序排列的第K个的节点。

输入:

5
/ \
3   7
/ \ / \
2  4 6  8


输出:

若K=3,则输出4


解题思路

二叉搜索树性质可知,左子树所有节点均小于当前节点,右子树节点均大于当前节点。可以根据左子树数量确定第K个节点位置。

1、若左子树节点数为K,则第K个节点为左子树的最右节点。
2、若左子树节点数为K-1,则第K个节点为当前节点。
3、若左子树节点数大于K,则第K个加点在左子树中,递归求左子树第K个节点即可。
4、若左子树节点数小于K-1,假设为S,则第K个节点为右子树第K-S-1个节点, 递归求右子树第K-S-1个节点即可。


基于以上思路,代码实现如下:

//根据先序遍历求二叉树节点总数
int NodesOfTree(TreeNode *node) {
if (NULL == node) {
return 0;
}

int res = 1;
res += NodesOfTree(node->left);
res += NodesOfTree(node->right);
return res;
}

//求取二叉树最大子节点
TreeNode *GetMaxNodeOfTree(TreeNode *root) {
if (NULL == root) {
return NULL;
}

while (NULL != root->right) {
root = root->right;
}

return root;
}

//主程序
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if (NULL == pRoot) {
return NULL;
}

int leftCounts = NodesOfTree(pRoot->left); //获取左子树节点数
if (leftCounts == k-1) { //若左子树节点数为K-1
return pRoot;
} else if (leftCounts == k) { //若左子树节点数为K
return GetMaxNodeOfTree(pRoot->left);
} else if (leftCounts > k) { //若左子树节点数大于K
return KthNode(pRoot->left, k);
} else { //若左子树节点数小于K-1
return KthNode(pRoot->right, k-leftCounts-1);
}
}


TreeNode定义如下:

struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}


========================================================

另附上大神思路:

由于二叉树中序遍历所得到的节点顺序即为大小排序,故可以按中序遍历方式求解。代码如下:

int count = 0; //全局变量记录当前遍历至第几个节点,**其实可以作为引用参数传递给函数
TreeNode *KthNode(TreeNode *pRoot, int k) {
if (NULL != pRoot) {
TreeNode *res = KthNode(pRoot->left, k);
if(NULL != res) {
return res;
}

if (++count == k) {
return pRoot;
}

return KthNode(pRoot->right, k);
}

return NULL;
}


大神代码就是精简,还需要继续学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  剑指offer