将未完整的二进制搜索树转换为完整的二进制搜索树

时间:2017-04-27 15:50:47

标签: c++ binary-search-tree

我在完整的二叉搜索树中遇到了麻烦 如何将非完整二叉搜索树转换为完整二叉搜索树,例如:
我在树中有一个Node结构:

struct Node {  
int键;  
节点*左,右;
};

我有一棵二叉树
-------- 18
------ / ---- \
----- 16 --- 19
----- / - \ ---- \
---- 8--17--20
--- / -----------
--7 ------------
它不是一个完整的二叉搜索树,它只是一个二叉树。 我想将此树转换为完整的二叉搜索树,如:
--------- 17
------- / ----- \
------ ------ 8 19
----- / - \ ----- / --- \
---- 7-16--18 --- 20
请帮我解决,非常感谢你!

1 个答案:

答案 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;
}