简体   繁体   English

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

[英]Binary Search tree Array implementation C++

I am in the process of implementing a Binary Search tree that gets represented using the Array implementation. 我正在实现使用Array实现表示的Binary Search树。 This is my code so far: Take note that I have done with the Structure of tree and it is being saved as a Linked List. 到目前为止,这是我的代码: 请注意,我已经完成了树的结构,并且将其保存为链接列表。 I want to convert this linked list into an array. 我想将此链接列表转换为数组。

My thoughts on how to go about this are as followed. 我对如何进行此操作的想法如下。 Make a return_array function. 做一个return_array函数。 Have the Size of the array set to the Max number of nodes( 2^(n-1)+1) and go through the linked list. 将数组的大小设置为最大节点数(2 ^(n-1)+1),然后浏览链接列表。 Root node would be @ position 0 on the array then his L-child = (2*[index_of_parent]+1) and R-child = (2*[index_of_parent]+2). 根节点将是数组上的@位置0,然后是其L子代=(2 * [index_of_parent] +1)和R子代=(2 * [index_of_parent] +2)。 I looked around for a bit and searched to find something that can get me an idea of how I can keep track of each node and how I can go through each one. 我四处张望,寻找可以使我了解如何跟踪每个节点以及如何遍历每个节点的想法。

Am I overthinking this problem? 我是否在考虑这个问题? Can there be a Recursion? 可以递归吗?

Also, I'm considering creating a visual tree instead of an array but have no idea how to space it out correctly. 另外,我正在考虑创建视觉树而不是数组,但不知道如何正确地将其隔开。 If anyone has an idea on how to do that it would be awesome to get a better understanding of that. 如果有人对如何做有一个想法,那么对它有一个更好的了解将是很棒的。

#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)
}

Considering that you want to efficiently store a binary search tree, using 考虑到您想要有效地存储二进制搜索树,请使用

l = 2i + 1
r = 2i + 2

will waste space every time your tree encounters a leaf node that is not occurring at the end of the tree (breadth-first). 每当您的树遇到树末端(宽度优先)未出现的叶子节点时,都会浪费空间。 Consider the following simple example: 考虑以下简单示例:

  2
 / \
1   4
   / \
  3   5

This (when transformed breadth-first into an array) results in 这(将广度优先转换为数组时)导致

[ 2, 1, 4, -, -, 3, 5 ]

And wastes two slots in the array. 并浪费阵列中的两个插槽。

Now if you want to store the same tree in an array without wasting space, just transform it into an array depth-first : 现在,如果要将同一棵树存储在数组中而不浪费空间,只需将其转换为深度优先的数组即可:

[ 2 1 4 3 5 ]

To recover the original tree from this, follow these steps for each node: 要从中恢复原始树,请对每个节点执行以下步骤:

  1. Choose the first node as root 选择第一个节点作为根节点
  2. For each node (including root), choose 对于每个节点(包括根),选择

    a) the left child as the next smaller key from the array after the current key a) 孩子作为当前键之后数组中的下一个较小键

    b) the right child as the next bigger key from the array, being no larger than the smallest parent key encountered when last branching left, and smaller than the direct parent's key when you are currently in it's left branch b) 右边的子项是数组中的下一个较大的键,不大于最后一个分支左移时遇到的最小父键,并且小于当前位于其左分支中的直接父键

Obviously finding the correct b) is slightly more complex, but not too much. 显然,找到正确的b) 稍微复杂一点,但并不过分。 Refer to my code example here . 在这里参考我的代码示例。

If I'm not mistaken, transforming to and from an array will take O(n) in either case. 如果我没记错的话,无论哪种情况,在数组之间来回转换都将花费O(n)。 And as no space is wasted, space complexity is also O(n). 而且由于没有浪费空间,所以空间复杂度也是O(n)。

This works because binary search trees have more structure than ordinary binary trees; 之所以可行,是因为二进制搜索树比普通的二进制树具有更多的结构。 here, I'm just using the binary search tree property of the left child being smaller, and the right child being larger than the current node's key. 在这里,我只是使用左孩子较小的二进制搜索树属性,而右孩子大于当前节点键的二进制搜索树属性。

EDIT: 编辑:

After doing some further research on the topic, I found that reconstructing the tree in preorder traversal order is much simpler. 在对该主题进行了一些进一步的研究之后,我发现以遍历顺序重建树要简单得多。 The recursive function doing that is implemented here and here , respectively. 为此的递归函数分别在此处此处实现。

It basically consists of these steps: 它基本上包括以下步骤:

  • As long as the input array has unseen entries, 只要输入数组中有看不见的条目,
    • If the value to insert is greater than the current branch's minimum value and less than the current branch's maximum allowed, 如果要插入的值大于当前分支的最小值且小于当前分支的允许最大值,
      • Add a node to the tree at the current position and set it's value to the current input value 在树的当前位置添加一个节点并将其值设置为当前输入值
      • Remove current value from input 从输入中删除当前值
    • If there are items left in the input, 如果输入中还有剩余项目,
      • Recurse into the left child 递归到左孩子
      • Recurse into the right child 递归到合适的孩子

The current minimum and maximum values are defined by the position inside the tree (left child: less than parent, right child: greater than parent). 当前的最小值和最大值由树内的位置定义(左子级:小于父级,右子级:大于父级)。

For more elaborate details, please refer to my source code links. 有关更多详细信息,请参阅我的源代码链接。

If you want to store the tree node in a array,you had better to start from 1 position of your array!So the relation between the parent and its children should be simple: 如果要将树节点存储在数组中,则最好从数组的1个位置开始!因此父级及其子级之间的关系应该很简单:

parent = n;
left = 2n;
right = 2n + 1;

you should BFS the tree,and store the node in the array(If the node is null you should also store in the array using a flag ex 0),you should get the very array of the tree! 您应该对树进行BFS,并将节点存储在数组中(如果节点为null,则还应该使用标志ex 0将其存储在数组中),您应该获得树的数组!

To do this you have to follow these steps. 为此,您必须遵循以下步骤。

  1. Create an empty queue. 创建一个空队列。
  2. Make the first node of the list as root, and enqueue it to the queue. 将列表的第一个节点设置为root,并将其排入队列。
  3. Until we reach the end of the list, do the following. 直到我们到达列表的末尾,然后执行以下操作。

    a. 一种。 Dequeue one node from the queue. 从队列中取出一个节点。 This is the current parent. 这是当前的父母。

    b. b。 Traverse two nodes in the list, add them as children of the current parent. 遍历列表中的两个节点,将它们添加为当前父节点的子节点。

    c. C。 Enqueue the two nodes into the queue. 将两个节点排入队列。

Time Complexity: Time complexity of the above solution is O(n) where n is the number of nodes. 时间复杂度:以上解决方案的时间复杂度为O(n),其中n是节点数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM