使用C++模板的通用分段树实现
Generic Segment Tree implementation using C++ Templates
我正在尝试为更新和范围查询创建一个通用的分段树类。
我希望用户提供元素的类型T和一个函数,我将其命名为compose。
此函数接受两个类型为T的参数,并返回一个相同类型T的值。此返回值是在2个元素的范围内执行所需操作时的结果,我可以使用2个元素在任意数量的元素的范围上执行相同的操作。
类别如下:
#include <functional>
template<class T>
class SegmentTree {
public:
class binary_function_unitype: public std::binary_function<T,T,T> {
public:
virtual T operator() (T arg1, T arg2) {};
};
private:
class Node {
public:
T value;
int seg_start, seg_end;
Node* left;
Node* right;
Node (T value, int seg_start, int seg_end, Node* left=0, Node* right=0) {
this->value = value;
this->seg_start = seg_start;
this->seg_end = seg_end;
this->left = left;
this->right = right;
}
};
// Not expecting the compose function to be robust enough.
T composeUtil (T arg1, T arg2) {
if (arg1!=0 && arg2!=0)
return compose(arg1,arg2);
else if (arg1!=0)
return arg1;
else if (arg2!=0)
return arg2;
}
// Creating the Segment Tree.
Node* createTree (T leaves[], int start, int end) {
// base case - leaf of tree.
if (start==end)
return new Node(leaves[start],start,start,0,0);
// general case.
int mid = start + (end-start)/2;
Node* left = createTree(leaves,start,mid);
Node* right = createTree(leaves,mid+1,end);
T retValue = composeUtil(left->value,right->value);
return new Node(retValue,start,end,left,right);
}
// Range Query helper.
T queryUtil (Node* root, int start, int end) {
int seg_start = root->seg_start, seg_end = root->seg_end;
if (seg_start>end || seg_end<start)
return 0;
else if (seg_start>=start && seg_end<=end)
return root->value;
else
return compose( queryUtil(root->left,start,end), queryUtil(root->right,start,end));
}
// Helper function for Updating the Segment Tree.
void updateUtil (Node* root, int position, T updatedValue) {
int seg_start = root->seg_start, seg_end = root->seg_end;
if(seg_start>position || seg_end<position)
return;
else if(seg_start==seg_end)
root->value = updatedValue;
else
root->value = composeUtil(root->left->value,root->right->value);
}
// Freeing the memory allocated to the Segment Tree.
void destroyTree(Node* root) {
if (root->left!=0)
destroyTree(root->left);
if (root->right!=0)
destroyTree(root->right);
delete root;
}
Node* root;
binary_function_unitype compose;
public:
SegmentTree (T leaves[], binary_function_unitype compose, int start, int end) {
this->compose = compose;
this->root = createTree(leaves, start, end);
}
T query (int start, int end) {
return queryUtil(root, start, end);
}
void update (int position, T updatedValue) {
updateUtil(root, position, updatedValue);
}
~SegmentTree () {
destroyTree(root);
}
};
当我尝试使用这个类时,发现没有使用我作为参数使用的compose函数,相反,正在使用类binary_function_unitype中的函数。
我希望用户的函数定义会覆盖类binary_function_unitype中的函数定义,我的工作就会完成。但这并没有发生。使用此类的程序如下:
#include <iostream>
#include "SegmentTree.h"
using namespace std;
class Compose: public SegmentTree<int>::binary_function_unitype {
public:
int operator() (int arg1, int arg2) {
return arg1+arg2;
}
};
int main()
{
int num;
cin>>num;
int arr[num];
for(int i=0;i<num;i++)
cin>>arr[i];
Compose compose;
SegmentTree<int> segTree(arr, compose, 0, num-1);
int s,e;
cin>>s>>e;
cout<<segTree.query(s-1,e-1);
return 0;
}
有人能告诉我我的方法有什么缺陷吗?或者我是否误解了在C++中使用继承或模板的一些基本概念?
谢谢。
构造函数按值获取binary_function_unitype
,因此它将切片。
相关文章:
- 在 c++ 中实现 Trie 时出现分段错误
- 实现 DFS 在较短的输入下工作正常,但在较大的输入下会抛出分段错误
- 分段 排序函数实现中的错误
- 在我的trie实现中出现分段错误
- 在 c++ 中实现链表时出现分段错误
- 实现 BST 时出现分段错误
- 在C++中实现 DFS 时出现分段错误
- 编译时条件包含.分段标头与包括整个实现
- 树实现给出分段错误(核心转储)错误 c++ 11
- 获取分段错误,用于在 protobuffer 的 C++ 中实现 ByteSize()
- 我的 std::strcopy 实现有什么问题?(分段错误)
- 使用导致分段错误的类C++中的堆栈实现
- 链接的列表在类C 中实现,显示分段故障
- 模板实现分段错误;
- 为什么这种类型的擦除实现(简化的 boost:any)会出现分段错误
- 实现导致分段错误的 avl 树
- 尝试实现二叉树时的分段错误
- 如何在特征中实现高性能分段线性传递函数
- C++链表实现分段错误(核心转储)错误
- 分段错误(核心转储)实现联合查找C++