[英]Binary Search tree Array implementation C++
我正在实现使用Array实现表示的Binary Search树。 到目前为止,这是我的代码: 请注意,我已经完成了树的结构,并且将其保存为链接列表。 我想将此链接列表转换为数组。
我对如何进行此操作的想法如下。 做一个return_array函数。 将数组的大小设置为最大节点数(2 ^(n-1)+1),然后浏览链接列表。 根节点将是数组上的@位置0,然后是其L子代=(2 * [index_of_parent] +1)和R子代=(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)
}
考虑到您想要有效地存储二进制搜索树,请使用
l = 2i + 1
r = 2i + 2
每当您的树遇到树末端(宽度优先)未出现的叶子节点时,都会浪费空间。 考虑以下简单示例:
2
/ \
1 4
/ \
3 5
这(将广度优先转换为数组时)导致
[ 2, 1, 4, -, -, 3, 5 ]
并浪费阵列中的两个插槽。
现在,如果要将同一棵树存储在数组中而不浪费空间,只需将其转换为深度优先的数组即可:
[ 2 1 4 3 5 ]
要从中恢复原始树,请对每个节点执行以下步骤:
对于每个节点(包括根),选择
a) 左孩子作为当前键之后数组中的下一个较小键
b) 右边的子项是数组中的下一个较大的键,不大于最后一个分支左移时遇到的最小父键,并且小于当前位于其左分支中的直接父键
显然,找到正确的b) 稍微复杂一点,但并不过分。 在这里参考我的代码示例。
如果我没记错的话,无论哪种情况,在数组之间来回转换都将花费O(n)。 而且由于没有浪费空间,所以空间复杂度也是O(n)。
之所以可行,是因为二进制搜索树比普通的二进制树具有更多的结构。 在这里,我只是使用左孩子较小的二进制搜索树属性,而右孩子大于当前节点键的二进制搜索树属性。
编辑:
在对该主题进行了一些进一步的研究之后,我发现以预遍历顺序重建树要简单得多。 为此的递归函数分别在此处和此处实现。
它基本上包括以下步骤:
当前的最小值和最大值由树内的位置定义(左子级:小于父级,右子级:大于父级)。
有关更多详细信息,请参阅我的源代码链接。
如果要将树节点存储在数组中,则最好从数组的1个位置开始!因此父级及其子级之间的关系应该很简单:
parent = n;
left = 2n;
right = 2n + 1;
您应该对树进行BFS,并将节点存储在数组中(如果节点为null,则还应该使用标志ex 0将其存储在数组中),您应该获得树的数组!
为此,您必须遵循以下步骤。
直到我们到达列表的末尾,然后执行以下操作。
一种。 从队列中取出一个节点。 这是当前的父母。
b。 遍历列表中的两个节点,将它们添加为当前父节点的子节点。
C。 将两个节点排入队列。
时间复杂度:以上解决方案的时间复杂度为O(n),其中n是节点数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.