我有一个长度为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;
}
因此,对于长度为11的数组,我希望
myvector[0] = arr[5]
myvector[1] = arr[2]
myvector[2] = arr[8]
myvector[3] = arr[0]
myvector[4] = arr[3]
myvector[5] = arr[6]
myvector[6] = arr[9]
myvector[7] = arr[1]
myvector[8] = arr[4]
myvector[9] = arr[7]
myvector[10] = arr[10]
我的问题是,myfunc的函数定义应该是什么,这样我得到预期的输出
bool myfunc (int l, int r)
{
int m = (l+r)/2;
//Cant figure out this logic
}
我尝试过调试器,但这绝对没有帮助定义函数!任何线索都会受到赞赏。
答案 0 :(得分:1)
看起来你想要一个以数组形式存储的二叉搜索树(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 http://en.cppreference.com/w/cpp/algorithm/binary_search,已排序的向量已经为您提供了进行二进制搜索的更好方法。