我在完整的二叉搜索树中遇到了麻烦
如何将非完整二叉搜索树转换为完整二叉搜索树,例如:
我在树中有一个Node结构:
struct Node
{
int键;
节点*左,右;
};
我有一棵二叉树
-------- 18
------ / ---- \
----- 16 --- 19
----- / - \ ---- \
---- 8--17--20
--- / -----------
--7 ------------
它不是一个完整的二叉搜索树,它只是一个二叉树。
我想将此树转换为完整的二叉搜索树,如:
--------- 17
------- / ----- \
------ ------ 8 19
----- / - \ ----- / --- \
---- 7-16--18 --- 20
请帮我解决,非常感谢你!
答案 0 :(得分:0)
一种方法,如果二叉树中的节点数有足够的节点来构造完整的树,即节点数等于1或3或7或15或...... 2 ^ n -1,则有效正整数n,是将树读入矢量并对其进行排序。然后可以将已排序的矢量传递给所描述的here所熟知的算法。这个想法是BST的根位于向量的中间,而根节点的左子节点是左子树的根,它将位于有序向量的左半部分的中间(同样适用于正确的节点和向量的右半部分。)
请注意:如果二叉树中的节点数(您的输入)不等于2 ^ n -1那么就无法构建完整二进制(搜索)树,因为您没有正确数量的节点可用。但是,如果允许添加其他节点,即不在二叉树中的节点(您在问题中没有说明这一点),下面的代码也可以工作,但是您需要向已排序的节点添加其他节点向量(例如,最后逐渐增长的数字)。
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct Node {
int key;
Node* left,*right;
};
/*
* Construct a tree like this and return a pointer
* to the root node
*/
//--------18
//------/----\
//-----16---19
//-----/-\----\
//----8--17--20
//---/-----------
//--7------------
Node* constructExampleTree();
/*
* Place all nodes which are part of the tree
* mounted under 'node' (including 'node') into 'vec'.
*/
void placeIntoVector(vector<int>& vec, Node* node);
/*
* Print the tree rooted under 'node' in order
*/
void printInOder(Node* node);
/*
* Delete all nodes rooted under 'node' in post order
*/
void deleteInPostOrder(Node* node);
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
Node* newNode(int data);
/* A function that constructs Balanced Binary Search Tree from a sorted array
*
* Algorithm taken from: http://www.geeksforgeeks.org/sorted-array-to-balanced-bst/
* */
Node* sortedArrayToBST(vector<int>& arr, int start, int end)
{
/* Base Case */
if (start > end)
return NULL;
/* Get the middle element and make it root */
int mid = (start + end)/2;
Node *root = newNode(arr[mid]);
/* Recursively construct the left subtree and make it
left child of root */
root->left = sortedArrayToBST(arr, start, mid-1);
/* Recursively construct the right subtree and make it
right child of root */
root->right = sortedArrayToBST(arr, mid+1, end);
return root;
}
int main (){
Node* root = constructExampleTree();
vector<int> vec;
placeIntoVector(vec, root);
sort(vec.begin(),vec.end());
int counter = static_cast<int>( vec.size());
Node *bstRoot = sortedArrayToBST(vec, 0, counter -1);
// Printing a BST in order will give us a sorted output
printInOder(bstRoot);
deleteInPostOrder(root);
deleteInPostOrder(bstRoot);
return 0;
}
Node* constructExampleTree() {
/*
* Level 1 and 2
*/
Node* eighteen = new Node();
eighteen->key = 18;
eighteen->left = NULL;
eighteen->right= NULL;
Node* sixteen = new Node();
sixteen->key = 16;
sixteen->left = NULL;
sixteen->right= NULL;
Node* nineteen = new Node();
nineteen->key = 19;
nineteen->left = NULL;
nineteen->right= NULL;
eighteen->left = sixteen;
eighteen->right = nineteen;
/*
* Level 3
*/
Node* eight = new Node();
eight->key = 8;
eight->left = NULL;
eight->right= NULL;
Node* seventeen = new Node();
seventeen->key = 17;
seventeen->left = NULL;
seventeen->right= NULL;
Node* twenty = new Node();
twenty->key = 20;
twenty->left = NULL;
twenty->right= NULL;
sixteen->left = eight;
sixteen->right = seventeen;
nineteen->right = twenty;
/*
* Level 4
*/
Node* seven = new Node();
seven->key = 7;
seven->left = NULL;
seven->right= NULL;
eight->left = seven;
return eighteen;
}
void placeIntoVector(vector<int>& vec, Node* node){
if (node == NULL)
return;
placeIntoVector(vec, node->left);
vec.push_back(node->key);
placeIntoVector(vec, node->right);
}
void printInOder(Node* node){
if (node == NULL)
return;
printInOder(node->left);
cout << node->key << " ";
printInOder(node->right);
}
void deleteInPostOrder(Node* node){
if (node == NULL)
return;
deleteInPostOrder(node->left);
deleteInPostOrder(node->right);
delete node;
}
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
Node* newNode(int data)
{
Node* node = new Node();
node->key = data;
node->left = NULL;
node->right = NULL;
return node;
}