二进制搜索树数组实现C++

Con*_*nor 1 c++ arrays binary-search-tree

我正在实现使用Array实现表示的二进制搜索树.这是我到目前为止的代码:请注意我完成了树的结构并将其保存为链接列表.我想将此链表转换为数组.

关于如何解决这个问题的想法如下.创建一个return_array函数.将数组的大小设置为最大节点数(2 ^(n-1)+1)并通过链接列表.根节点将是阵列上的@ postion 0,然后他的L-child =(2*[index_of_parent] +1)并且R-child =(2*[index_of_parent] +2).我环顾四周寻找一些可以让我知道如何保持每个节点的固定以及如何通过每个节点的东西.

我是否在思考这个问题?可以有递归吗?

我也在考虑创建一个可视树而不是一个数组,但不知道如何正确地将它分隔出来.如果有人知道如何做到这一点,那么更好地理解它将是非常棒的.

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>

using namespace std;

struct node { 
    int data; 
    struct node* left; 
    struct node* right; 
};

void inorder(struct node* node){
    if(node){
        inorder(node->left);
        cout << node->data << " ";
        inorder(node->right);
    }
}

void insert(struct node** node, int key){

    if(*node == NULL){
        (*node) = (struct node*)malloc(sizeof(struct node));
        (*node)->data = key;
        (*node)->left = NULL;
        (*node)->right = NULL;
        printf("inserted node with data %d\n", (*node)->data);
    }
    else if ((*node)->data > key){
        insert((&(*node)->left),key);

    }
    else
        insert((&(*node)->right),key);
}

int max_tree(struct node* node){
    int left,right;
    if(node == NULL)
       return 0;
    else
    {
      left=max_tree(node->left);
      right=max_tree(node->right);
      if(left>right)
         return left+1;
      else
         return right+1;
}
}

//This is where i dont know how to keep the parent/children the array.
void return_array(struct node* node, int height){
    int max;
    height = height - 1;
    max = pow(2, height) - 1;
    int arr [height];








}

int main(){
    int h;
    struct node* root = NULL;

    insert(&root, 10);
    insert(&root, 20);
    insert(&root, 5);
    insert(&root, 2);


   inorder(root);
   cout << endl;
   cout << "Height is: ";
   cout << max_tree(root);
   h = max_tree(root)
   return_array(root, h)
}
Run Code Online (Sandbox Code Playgroud)

小智 6

考虑到您想要有效地存储二进制搜索树,请使用

l = 2i + 1
r = 2i + 2
Run Code Online (Sandbox Code Playgroud)

每当您的树遇到树末端(宽度优先)未出现的叶子节点时,都会浪费空间。考虑以下简单示例:

  2
 / \
1   4
   / \
  3   5
Run Code Online (Sandbox Code Playgroud)

这(将广度优先转换为数组时)导致

[ 2, 1, 4, -, -, 3, 5 ]
Run Code Online (Sandbox Code Playgroud)

并浪费阵列中的两个插槽。

现在,如果要将同一棵树存储在数组中而不浪费空间,只需将其转换为深度优先的数组即可:

[ 2 1 4 3 5 ]
Run Code Online (Sandbox Code Playgroud)

要从中恢复原始树,请对每个节点执行以下步骤:

  1. 选择第一个节点作为根节点
  2. 对于每个节点(包括根),选择

    a)孩子作为当前键之后数组中的下一个较小键

    b)右边的孩子作为数组中的下一个更大的键,不大于最后一个分支左移时遇到的最小父键,并且小于当前位于其左分支中的直接父键

显然,找到正确的b)稍微复杂一点,但并不过分。在这里参考我的代码示例。

如果我没记错的话,无论哪种情况,在数组之间来回转换都将花费O(n)。而且由于没有浪费空间,所以空间复杂度也是O(n)。

之所以可行,是因为二进制搜索树比普通的二进制树具有更多的结构。在这里,我只是使用左孩子的二进制搜索树属性较小,而右孩子的二进制搜索树属性大于当前节点的键。

编辑:

在对该主题进行了一些进一步的研究之后,我发现以遍历顺序重建树要简单得多。为此的递归函数分别在此处此处实现。

它基本上包括以下步骤:

  • 只要输入数组中有看不见的条目,
    • 如果要插入的值大于当前分支的最小值且小于当前分支的允许最大值,
      • 在树的当前位置添加一个节点并将其值设置为当前输入值
      • 从输入中删除当前值
    • 如果输入中还有剩余项目,
      • 递归到左孩子
      • 递归到合适的孩子

当前的最小值和最大值由树内的位置定义(左子级:小于父级,右子级:大于父级)。

有关更多详细信息,请参阅我的源代码链接。


min*_*ain 5

如果要将树节点存储在数组中,最好从数组的1个位置开始!所以父节点与子节点之间的关系应该很简单:

parent = n;
left = 2n;
right = 2n + 1;
Run Code Online (Sandbox Code Playgroud)

你应该BFS树,并将节点存储在数组中(如果节点为null,你也应该使用标志ex 0存储在数组中),你应该得到树的数组!