Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何映射数组元素以选择二叉树节点?_C++_Arrays_Sorting - Fatal编程技术网

C++ 如何映射数组元素以选择二叉树节点?

C++ 如何映射数组元素以选择二叉树节点?,c++,arrays,sorting,C++,Arrays,Sorting,我有一个长度为n的数组。我想对数组元素进行排序,使我的新数组元素如下 arr[0] = arr[n/2] arr[1] = arr[n/4] arr[2] = arr[3n/4] arr[3] = arr[n/8] arr[4] = arr[3n/8] arr[5] = arr[5n/8] 等等 我尝试过的,使用向量 #include <iostream> #include <algorithm> #include <vector> bool myfun

我有一个长度为n的数组。我想对数组元素进行排序,使我的新数组元素如下

arr[0] = arr[n/2]
arr[1] = arr[n/4]
arr[2] = arr[3n/4]
arr[3] = arr[n/8]
arr[4] = arr[3n/8]
arr[5] = arr[5n/8] 
等等

我尝试过的,使用向量

#include <iostream>
#include <algorithm>
#include <vector>

bool myfunc (int l, int r)
{
        int m = (l+r)/2;
        return m;
}

int main()
{
    std::vector<int> myvector = {3,1,20,9,7,5,6,22,17,14,4};
    std::sort (myvector.begin(), myvector.end(), myfunc);

    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;

}
我的问题是,myfunc的函数定义应该是什么,这样才能得到预期的输出

bool myfunc (int l, int r)
    {
            int m = (l+r)/2;
            //Cant figure out this logic
    }

我尝试过调试器,但这对定义函数毫无帮助!如果有任何线索,我们将不胜感激。

看来您希望以数组形式存储二进制搜索树BST,并使用通常用于存储堆的相同内部表示

预期输出是一个数组,使得基于一的索引形成一棵树,其中对于任何基于一的索引x,x的左节点位于索引2*x,x的右节点位于索引2*x+1。另外,没有空隙,意味着数组的每个成员都使用,直到N。它是一个完整的二叉树,因为C++使用基于零的索引,所以需要小心使用基于这个索引。 这种表示树的方法对于存储堆数据结构非常好,但对于要插入内容的二元搜索树非常糟糕,从而破坏了完整性,并迫使您进行非常昂贵的重新平衡

您要求从排序数组索引映射到此数组格式。我们可以使用递归函数来构建它。此递归函数所需的工作量与构建二叉树所需的工作量完全相同,事实上,它与编写该函数的方式几乎相同,因此这不是一种最佳方法。我们正在尽可能多地解决整个问题,只是为了找到一个中间步骤

这里需要特别注意的是,我们不想要中间值。我们希望确保左子树形成一个完美的二叉树,这样它就可以在数组中没有间隙。因此,它必须具有2的幂,减去1个节点。正确的子树只能是完整的

int log2(int n) {
    if (n > 1)
        return 1 + log2(n / 2);
    return 0;
}

// current_position is the index in bst_indexes
void build_binary_tree_index_mapping(std::vector<int> &bst_indexes, int lower, int upper, int current_position=0) {
    if (current_position >= bst_indexes.size())
        return;

    int power = log2(upper - lower);
    int number = 1 << (power); // left subtree must be perfect
    int root = lower + number - 1;

    // fill current_position
    // std::cout << current_position << " = " << root << std::endl;
    bst_indexes[current_position] = root;

    if (lower < root) {
        // fill left subtree
        int left_node_position = (current_position + 1) * 2 - 1;
        build_binary_tree_index_mapping(bst_indexes, lower, root - 1, left_node_position);
    }

    if (root < upper) {
        // fill right subtree
        int right_node_position = (current_position + 1) * 2 + 1 - 1;
        build_binary_tree_index_mapping(bst_indexes, root + 1, upper, right_node_position);
    }
}
这给了我{7,3,9,1,5,8,10,0,2,4,6}作为索引映射。它与您的不同,因为您在树的左下角留下了空格,并且我正在确保数组已完全填充,因此我必须将最下面一行移过去,然后BST属性需要对所有内容重新排序

作为补充说明,为了使用此映射,首先必须对数据进行排序,这与整个问题的复杂性大致相同


此外,排序向量已经为您提供了一种更好的方法来进行二进制搜索,使用std::binary_search。

您无需提问。使用调试器。使用std::vector而不是new[]。@manni66我已经尝试过调试器。但是我不能理解正确的逻辑。你的程序按照你说的做,它做得正确。您的算法有错误。@S.M.是的,正确。你能给我一个提示吗?我该如何纠正我的算法?看起来你想要执行一对一的映射,这与数组中的数字完全无关,对吗?所以这应该很容易,但和排序无关。实际上,如果你重新开始,除了你想要完成的确切步骤之外,什么都不做,这看起来很容易。
int log2(int n) {
    if (n > 1)
        return 1 + log2(n / 2);
    return 0;
}

// current_position is the index in bst_indexes
void build_binary_tree_index_mapping(std::vector<int> &bst_indexes, int lower, int upper, int current_position=0) {
    if (current_position >= bst_indexes.size())
        return;

    int power = log2(upper - lower);
    int number = 1 << (power); // left subtree must be perfect
    int root = lower + number - 1;

    // fill current_position
    // std::cout << current_position << " = " << root << std::endl;
    bst_indexes[current_position] = root;

    if (lower < root) {
        // fill left subtree
        int left_node_position = (current_position + 1) * 2 - 1;
        build_binary_tree_index_mapping(bst_indexes, lower, root - 1, left_node_position);
    }

    if (root < upper) {
        // fill right subtree
        int right_node_position = (current_position + 1) * 2 + 1 - 1;
        build_binary_tree_index_mapping(bst_indexes, root + 1, upper, right_node_position);
    }
}