给定二叉树,将其转换为二叉搜索树。转换必须采用保留二叉树原始结构的方式进行。
例子。
Example 1
Input:
10
/ \
2 7
/ \
8 4
Output:
8
/ \
4 10
/ \
2 7
Example 2
Input:
10
/ \
30 15
/ \
20 5
Output:
15
/ \
10 20
/ \
5 30
解决方案
以下是将二进制树转换为二进制搜索树的3个步骤的解决方案。
1)创建一个临时数组arr [],用于存储树的有序遍历。此步骤需要O(n)时间。
2)对临时数组arr []进行排序。此步骤的时间复杂度取决于排序算法。在以下实现中,使用了快速排序,需要花费(n ^ 2)的时间。可以使用堆排序或合并排序在O(nLogn)时间完成此操作。
3)再次进行树的有序遍历,并将数组元素一一复制到树节点。此步骤需要O(n)时间。
以下是上述方法的C实现。以下代码突出显示了要转换的主要函数。
C
/* A program to convert Binary Tree to Binary Search Tree */
#include
#include
/* A binary tree node structure */
struct node {
int data;
struct node* left;
struct node* right;
};
/* A helper function that stores inorder traversal of a tree rooted
with node */
void storeInorder(struct node* node, int inorder[], int* index_ptr)
{
// Base Case
if (node == NULL)
return;
/* first store the left subtree */
storeInorder(node->left, inorder, index_ptr);
/* Copy the root's data */
inorder[*index_ptr] = node->data;
(*index_ptr)++; // increase index for next entry
/* finally store the right subtree */
storeInorder(node->right, inorder, index_ptr);
}
/* A helper function to count nodes in a Binary Tree */
int countNodes(struct node* root)
{
if (root == NULL)
return 0;
return countNodes(root->left) + countNodes(root->right) + 1;
}
// Following function is needed for library function qsort()
int compare(const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
/* A helper function that copies contents of arr[] to Binary Tree.
This function basically does Inorder traversal of Binary Tree and
one by one copy arr[] elements to Binary Tree nodes */
void arrayToBST(int* arr, struct node* root, int* index_ptr)
{
// Base Case
if (root == NULL)
return;
/* first update the left subtree */
arrayToBST(arr, root->left, index_ptr);
/* Now update root's data and increment index */
root->data = arr[*index_ptr];
(*index_ptr)++;
/* finally update the right subtree */
arrayToBST(arr, root->right, index_ptr);
}
// This function converts a given Binary Tree to BST
void binaryTreeToBST(struct node* root)
{
// base case: tree is empty
if (root == NULL)
return;
/* Count the number of nodes in Binary Tree so that
we know the size of temporary array to be created */
int n = countNodes(root);
// Create a temp array arr[] and store inorder traversal of tree in arr[]
int* arr = new int[n];
int i = 0;
storeInorder(root, arr, &i);
// Sort the array using library function for quick sort
qsort(arr, n, sizeof(arr[0]), compare);
// Copy array elements back to Binary Tree
i = 0;
arrayToBST(arr, root, &i);
// delete dynamically allocated memory to avoid meory leak
delete[] arr;
}
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data)
{
struct node* temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Utility function to print inorder traversal of Binary Tree */
void printInorder(struct node* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
printf("%d ", node->data);
/* now recur on right child */
printInorder(node->right);
}
/* Driver function to test above functions */
int main()
{
struct node* root = NULL;
/* Constructing tree given in the above figure
10
/ \
30 15
/ \
20 5 */
root = newNode(10);
root->left = newNode(30);
root->right = newNode(15);
root->left->left = newNode(20);
root->right->right = newNode(5);
// convert Binary Tree to BST
binaryTreeToBST(root);
printf("Following is Inorder Traversal of the converted BST: \n");
printInorder(root);
return 0;
}
Python
# Program to convert binary tree to BST
# A binary tree node
class Node:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Helper function to store the inroder traversal of a tree
def storeInorder(root, inorder):
# Base Case
if root is None:
return
# First store the left subtree
storeInorder(root.left, inorder)
# Copy the root's data
inorder.append(root.data)
# Finally store the right subtree
storeInorder(root.right, inorder)
# A helper funtion to count nodes in a binary tree
def countNodes(root):
if root is None:
return 0
return countNodes(root.left) + countNodes(root.right) + 1
# Helper function that copies contents of sorted array
# to Binary tree
def arrayToBST(arr, root):
# Base Case
if root is None:
return
# First update the left subtree
arrayToBST(arr, root.left)
# now update root's data delete the value from array
root.data = arr[0]
arr.pop(0)
# Finally update the right subtree
arrayToBST(arr, root.right)
# This function converts a given binary tree to BST
def binaryTreeToBST(root):
# Base Case: Tree is empty
if root is None:
return
# Count the number of nodes in Binary Tree so that
# we know the size of temporary array to be created
n = countNodes(root)
# Create the temp array and store the inorder traveral
# of tree
arr = []
storeInorder(root, arr)
# Sort the array
arr.sort()
# copy array elements back to binary tree
arrayToBST(arr, root)
# Print the inorder traversal of the tree
def printInorder(root):
if root is None:
return
printInorder(root.left)
print root.data,
printInorder(root.right)
# Driver program to test above function
root = Node(10)
root.left = Node(30)
root.right = Node(15)
root.left.left = Node(20)
root.right.right = Node(5)
# Convert binary tree to BST
binaryTreeToBST(root)
print "Following is the inorder traversal of the converted BST"
printInorder(root)
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)
输出:
Following is Inorder Traversal of the converted BST:
5 10 15 20 30
复杂度分析:
- 时间复杂度: O(nlogn)。
这是我们在第一次有序遍历后使用的排序算法的复杂性,其余操作在线性时间内进行。 - 辅助空间: O(n)。
使用数据结构“数组”存储有序遍历。
我们将介绍针对此问题的另一种方法,该方法使用O(树的高度)多余的空间来转换树。