给定二叉搜索树(BST),找到第二大元素。
例子:
Input: Root of below BST
10
/
5
Output: 5
Input: Root of below BST
10
/ \
5 20
\
30
Output: 20
资料来源:微软访谈
这个想法类似于下面的帖子。
不允许修改BST时BST中的第K个最大元素
第二大元素是有序遍历的倒数第二个元素,而反向有序遍历的倒数第二个元素。我们以相反的顺序遍历给定的二叉搜索树,并跟踪访问的节点数。一旦计数变为2,我们将打印该节点。
以下是上述想法的实现。
C++
// C++ program to find 2nd largest element in BST
#include
using namespace std;
struct Node
{
int key;
Node *left, *right;
};
// A utility function to create a new BST node
Node *newNode(int item)
{
Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
// A function to find 2nd largest element in a given tree.
void secondLargestUtil(Node *root, int &c)
{
// Base cases, the second condition is important to
// avoid unnecessary recursive calls
if (root == NULL || c >= 2)
return;
// Follow reverse inorder traversal so that the
// largest element is visited first
secondLargestUtil(root->right, c);
// Increment count of visited nodes
c++;
// If c becomes k now, then this is the 2nd largest
if (c == 2)
{
cout << "2nd largest element is "
<< root->key << endl;
return;
}
// Recur for left subtree
secondLargestUtil(root->left, c);
}
// Function to find 2nd largest element
void secondLargest(Node *root)
{
// Initialize count of nodes visited as 0
int c = 0;
// Note that c is passed by reference
secondLargestUtil(root, c);
}
/* A utility function to insert a new node with given key in BST */
Node* insert(Node* node, int key)
{
/* If the tree is empty, return a new node */
if (node == NULL) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
/* return the (unchanged) node pointer */
return node;
}
// Driver Program to test above functions
int main()
{
/* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
Node *root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
secondLargest(root);
return 0;
}
Java
// Java code to find second largest element in BST
// A binary tree node
class Node {
int data;
Node left, right;
Node(int d)
{
data = d;
left = right = null;
}
}
class BinarySearchTree {
// Root of BST
Node root;
// Constructor
BinarySearchTree()
{
root = null;
}
// function to insert new nodes
public void insert(int data)
{
this.root = this.insertRec(this.root, data);
}
/* A utility function to insert a new node with given
key in BST */
Node insertRec(Node node, int data)
{
/* If the tree is empty, return a new node */
if (node == null) {
this.root = new Node(data);
return this.root;
}
/* Otherwise, recur down the tree */
if (data < node.data) {
node.left = this.insertRec(node.left, data);
} else {
node.right = this.insertRec(node.right, data);
}
return node;
}
// class that stores the value of count
public class count {
int c = 0;
}
// Function to find 2nd largest element
void secondLargestUtil(Node node, count C)
{
// Base cases, the second condition is important to
// avoid unnecessary recursive calls
if (node == null || C.c >= 2)
return;
// Follow reverse inorder traversal so that the
// largest element is visited first
this.secondLargestUtil(node.right, C);
// Increment count of visited nodes
C.c++;
// If c becomes k now, then this is the 2nd largest
if (C.c == 2) {
System.out.print("2nd largest element is "+
node.data);
return;
}
// Recur for left subtree
this.secondLargestUtil(node.left, C);
}
// Function to find 2nd largest element
void secondLargest(Node node)
{
// object of class count
count C = new count();
this.secondLargestUtil(this.root, C);
}
// Driver function
public static void main(String[] args)
{
BinarySearchTree tree = new BinarySearchTree();
/* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
tree.insert(50);
tree.insert(30);
tree.insert(20);
tree.insert(40);
tree.insert(70);
tree.insert(60);
tree.insert(80);
tree.secondLargest(tree.root);
}
}
// This code is contributed by Kamal Rawal
Python3
# Python3 code to find second largest
# element in BST
class Node:
# Constructor to create a new node
def __init__(self, data):
self.key = data
self.left = None
self.right = None
# A function to find 2nd largest
# element in a given tree.
def secondLargestUtil(root, c):
# Base cases, the second condition
# is important to avoid unnecessary
# recursive calls
if root == None or c[0] >= 2:
return
# Follow reverse inorder traversal so that
# the largest element is visited first
secondLargestUtil(root.right, c)
# Increment count of visited nodes
c[0] += 1
# If c becomes k now, then this is
# the 2nd largest
if c[0] == 2:
print("2nd largest element is",
root.key)
return
# Recur for left subtree
secondLargestUtil(root.left, c)
# Function to find 2nd largest element
def secondLargest(root):
# Initialize count of nodes
# visited as 0
c = [0]
# Note that c is passed by reference
secondLargestUtil(root, c)
# A utility function to insert a new
# node with given key in BST
def insert(node, key):
# If the tree is empty, return a new node
if node == None:
return Node(key)
# Otherwise, recur down the tree
if key < node.key:
node.left = insert(node.left, key)
elif key > node.key:
node.right = insert(node.right, key)
# return the (unchanged) node pointer
return node
# Driver Code
if __name__ == '__main__':
# Let us create following BST
# 50
# / \
# 30 70
# / \ / \
# 20 40 60 80
root = None
root = insert(root, 50)
insert(root, 30)
insert(root, 20)
insert(root, 40)
insert(root, 70)
insert(root, 60)
insert(root, 80)
secondLargest(root)
# This code is contributed by PranchalK
C#
using System;
// C# code to find second largest element in BST
// A binary tree node
public class Node
{
public int data;
public Node left, right;
public Node(int d)
{
data = d;
left = right = null;
}
}
public class BinarySearchTree
{
// Root of BST
public Node root;
// Constructor
public BinarySearchTree()
{
root = null;
}
// function to insert new nodes
public virtual void insert(int data)
{
this.root = this.insertRec(this.root, data);
}
/* A utility function to insert a new node with given
key in BST */
public virtual Node insertRec(Node node, int data)
{
/* If the tree is empty, return a new node */
if (node == null)
{
this.root = new Node(data);
return this.root;
}
/* Otherwise, recur down the tree */
if (data < node.data)
{
node.left = this.insertRec(node.left, data);
}
else
{
node.right = this.insertRec(node.right, data);
}
return node;
}
// class that stores the value of count
public class count
{
private readonly BinarySearchTree outerInstance;
public count(BinarySearchTree outerInstance)
{
this.outerInstance = outerInstance;
}
public int c = 0;
}
// Function to find 2nd largest element
public virtual void secondLargestUtil(Node node, count C)
{
// Base cases, the second condition is important to
// avoid unnecessary recursive calls
if (node == null || C.c >= 2)
{
return;
}
// Follow reverse inorder traversal so that the
// largest element is visited first
this.secondLargestUtil(node.right, C);
// Increment count of visited nodes
C.c++;
// If c becomes k now, then this is the 2nd largest
if (C.c == 2)
{
Console.Write("2nd largest element is " + node.data);
return;
}
// Recur for left subtree
this.secondLargestUtil(node.left, C);
}
// Function to find 2nd largest element
public virtual void secondLargest(Node node)
{
// object of class count
count C = new count(this);
this.secondLargestUtil(this.root, C);
}
// Driver function
public static void Main(string[] args)
{
BinarySearchTree tree = new BinarySearchTree();
/* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
tree.insert(50);
tree.insert(30);
tree.insert(20);
tree.insert(40);
tree.insert(70);
tree.insert(60);
tree.insert(80);
tree.secondLargest(tree.root);
}
}
// This code is contributed by Shrikant13
输出:
2nd largest element is 70
上述解决方案的时间复杂度为O(h),其中h是BST的高度。