C++ 无法在自定义树中插入超过256个节点
我已经在这个问题上纠缠了很长时间,甚至在Ubuntu上测试了64位版本的gcc,在Windows上测试了32位版本的gcc(MinGW) 每当我在二叉树(?)中插入超过256个节点时,它就会停止计算节点数。我仍然可以访问我的所有数据。我有一种感觉,它与我的结构设置方式有关,通过使用字符获取每个字节的每一位,但我不知道如何修复它 ,我有一个结构和一些功能设置,允许我获取对象的单个位 。为了找到存储每个对象的位置,树遍历键的每个字节,然后再次遍历这些字节的每个位。“迭代”函数是给我带来最大困难的;我不知道为什么,但一旦256个节点充满了数据,我的结构就会停止进一步计数,然后开始替换以前的所有数据。我相信这与一个字符只能容纳0-256的事实有关,但我看不出这会是一个问题。由于每个节点的位置由密钥的各个位确定,因此很难确定为什么只能将256个项目放入树中 我的测试程序的URL在文章的底部。所以现在我不会发布超过2条。我希望尽快完成这项工作,因此,任何帮助都将不胜感激 编辑: 为了方便起见,这是一种结构,它为我提供了一个字节的单个位,以及一个辅助函数:C++ 无法在自定义树中插入超过256个节点,c++,c++11,tree,binary-tree,b-tree,C++,C++11,Tree,Binary Tree,B Tree,我已经在这个问题上纠缠了很长时间,甚至在Ubuntu上测试了64位版本的gcc,在Windows上测试了32位版本的gcc(MinGW) 每当我在二叉树(?)中插入超过256个节点时,它就会停止计算节点数。我仍然可以访问我的所有数据。我有一种感觉,它与我的结构设置方式有关,通过使用字符获取每个字节的每一位,但我不知道如何修复它 ,我有一个结构和一些功能设置,允许我获取对象的单个位 。为了找到存储每个对象的位置,树遍历键的每个字节,然后再次遍历这些字节的每个位。“迭代”函数是给我带来最大困难的;我
struct bitMask {
char b1 : 1;
char b2 : 1;
char b3 : 1;
char b4 : 1;
char b5 : 1;
char b6 : 1;
char b7 : 1;
char b8 : 1;
char operator[] ( unsigned i ) const {
switch( i ) {
case 0 : return b1;
case 1 : return b2;
case 2 : return b3;
case 3 : return b4;
case 4 : return b5;
case 5 : return b6;
case 6 : return b7;
case 7 : return b8;
}
return 0; // Avoiding a compiler error
}
};
/******************************************************************************
* Functions shared between tree-type objects
******************************************************************************/
namespace treeShared {
// Function to retrieve the next set of bits at the pointer "key"
template <typename key_t>
inline const bitMask* getKeyByte( const key_t* key, unsigned iter );
/* template specializations */
template <>
inline const bitMask* getKeyByte( const char*, unsigned );
template <>
inline const bitMask* getKeyByte( const wchar_t*, unsigned );
template <>
inline const bitMask* getKeyByte( const char16_t*, unsigned );
template <>
inline const bitMask* getKeyByte( const char32_t*, unsigned );
} // end treeShared namespace
/*
* Tree Bit Mask Function
*/
template <typename key_t>
inline const bitMask* treeShared::getKeyByte( const key_t* k, unsigned iter ) {
return (iter < sizeof( key_t ))
? reinterpret_cast< const bitMask* >( k+iter )
: nullptr;
}
/*
* Tree Bit Mask Specializations
*/
template <>
inline const bitMask* treeShared::getKeyByte( const char* str, unsigned iter ) {
return (str[ iter ] != '\0')
? reinterpret_cast< const bitMask* >( str+iter )
: nullptr;
}
template <>
inline const bitMask* treeShared::getKeyByte( const wchar_t* str, unsigned iter ) {
return (str[ iter ] != '\0')
? reinterpret_cast< const bitMask* >( str+iter )
: nullptr;
}
template <>
inline const bitMask* treeShared::getKeyByte( const char16_t* str, unsigned iter ) {
return (str[ iter ] != '\0')
? reinterpret_cast< const bitMask* >( str+iter )
: nullptr;
}
template <>
inline const bitMask* treeShared::getKeyByte( const char32_t* str, unsigned iter ) {
return (str[ iter ] != '\0')
? reinterpret_cast< const bitMask* >( str+iter )
: nullptr;
}
struct位掩码{
半焦b1:1;
字符b2:1;
字符b3:1;
炭素b4:1;
炭b5:1;
字符b6:1;
字符b7:1;
字符b8:1;
字符运算符[](无符号i)常量{
开关(一){
案例0:返回b1;
案例1:返回b2;
案例2:返回b3;
案例3:返回b4;
案例4:返回b5;
案例5:返回b6;
案例6:返回b7;
案例7:返回b8;
}
返回0;//避免编译器错误
}
};
/******************************************************************************
*树型对象之间共享的函数
******************************************************************************/
命名空间树共享{
//函数检索指针“key”处的下一组位
模板
内联常量位掩码*getKeyByte(常量键*key,无符号iter);
/*模板专门化*/
模板
内联常量位掩码*getKeyByte(常量字符*,无符号);
模板
内联常量位掩码*getKeyByte(常量wchar\u t*,无符号);
模板
内联常量位掩码*getKeyByte(常量char16\u t*,无符号);
模板
内联常量位掩码*getKeyByte(常量char32_t*,无符号);
}//结束树共享命名空间
/*
*树位掩码函数
*/
模板
内联常量位掩码*treeShared::getKeyByte(常量键*k,无符号iter){
返回(iter(k+iter)
:nullptr;
}
/*
*树位掩码专门化
*/
模板
内联常量位掩码*treeShared::getKeyByte(常量字符*str,无符号iter){
返回(str[iter]!='\0')
?重新解释铸件<常数位掩码*>(str+iter)
:nullptr;
}
模板
内联常量位掩码*treeShared::getKeyByte(常量wchar\u t*str,无符号iter){
返回(str[iter]!='\0')
?重新解释铸件<常数位掩码*>(str+iter)
:nullptr;
}
模板
内联常量位掩码*treeShared::getKeyByte(常量char16\u t*str,无符号iter){
返回(str[iter]!='\0')
?重新解释铸件<常数位掩码*>(str+iter)
:nullptr;
}
模板
内联常量位掩码*treeShared::getKeyByte(常量char32_t*str,无符号iter){
返回(str[iter]!='\0')
?重新解释铸件<常数位掩码*>(str+iter)
:nullptr;
}
下面是树类:
template <typename data_t>
struct bTreeNode {
data_t* data = nullptr;
bTreeNode* subNodes = nullptr;
~bTreeNode() {
delete data;
delete [] subNodes;
data = nullptr;
subNodes = nullptr;
}
};
/******************************************************************************
* Binary-Tree Structure Setup
******************************************************************************/
template <typename key_t, typename data_t>
class bTree {
enum node_dir : unsigned {
BNODE_LEFT = 0,
BNODE_RIGHT = 1,
BNODE_MAX
};
protected:
bTreeNode<data_t> head;
unsigned numNodes = 0;
private:
bTreeNode<data_t>* iterate( const key_t* k, bool createNodes );
public:
~bTree() {}
// STL-Map behavior
data_t& operator [] ( const key_t& k );
void push ( const key_t& k, const data_t& d );
void pop ( const key_t& k );
bool hasData ( const key_t& k );
const data_t* getData ( const key_t& k );
unsigned size () const { return numNodes; }
void clear ();
};
/*
* Binary-Tree -- Element iteration
*/
template <typename key_t, typename data_t>
bTreeNode<data_t>* bTree<key_t, data_t>::iterate( const key_t* k, bool createNodes ) {
node_dir dir;
unsigned bytePos = 0;
bTreeNode<data_t>* bNodeIter = &head;
const bitMask* byteIter = nullptr;
while ( byteIter = treeShared::getKeyByte< key_t >( k, bytePos++ ) ) {
for ( int currBit = 0; currBit < HL_BITS_PER_BYTE; ++currBit ) {
// compare the bits of each byte in k
dir = byteIter->operator []( currBit ) ? BNODE_LEFT : BNODE_RIGHT;
// check to see if a new bTreeNode needs to be made
if ( !bNodeIter->subNodes ) {
if ( createNodes ) {
// create and initialize the upcoming sub bTreeNode
bNodeIter->subNodes = new bTreeNode<data_t>[ BNODE_MAX ];
}
else {
return nullptr;
}
}
// move to the next bTreeNode
bNodeIter = &(bNodeIter->subNodes[ dir ]);
}
}
return bNodeIter;
}
/*
* Binary-Tree -- Destructor
*/
template <typename key_t, typename data_t>
void bTree<key_t, data_t>::clear() {
delete head.data;
delete [] head.subNodes;
head.data = nullptr;
head.subNodes = nullptr;
numNodes = 0;
}
/*
* Binary-Tree -- Array Subscript operators
*/
template <typename key_t, typename data_t>
data_t& bTree<key_t, data_t>::operator []( const key_t& k ) {
bTreeNode<data_t>* iter = iterate( &k, true );
if ( !iter->data ) {
iter->data = new data_t();
++numNodes;
}
return *iter->data;
}
/*
* Binary-Tree -- Push
* Push a data element to the tree using a key
*/
template <typename key_t, typename data_t>
void bTree<key_t, data_t>::push( const key_t& k, const data_t& d ) {
bTreeNode<data_t>* iter = iterate( &k, true );
if ( !iter->data ) {
iter->data = new data_t( d );
++numNodes;
}
else {
*iter->data = d;
}
}
/*
* Binary-Tree -- Pop
* Remove whichever element lies at the key
*/
template <typename key_t, typename data_t>
void bTree<key_t, data_t>::pop( const key_t& k ) {
bTreeNode<data_t>* iter = iterate( &k, false );
if ( !iter || !iter->data )
return;
delete iter->data;
iter->data = nullptr;
--numNodes;
}
/*
* Binary-Tree -- Has Data
* Return true if there is a data element at the key
*/
template <typename key_t, typename data_t>
bool bTree<key_t, data_t>::hasData( const key_t& k ) {
bTreeNode<data_t>* iter = iterate( &k, false );
return iter && ( iter->data != nullptr );
}
/*
* Binary-Tree -- Push
* Return a pointer to the data that lies at a key
* Returns a nullptr if no data exists
*/
template <typename key_t, typename data_t>
const data_t* bTree<key_t, data_t>::getData( const key_t& k ) {
bTreeNode<data_t>* iter = iterate( &k, false );
if ( !iter )
return nullptr;
return iter->data;
}
模板
结构B节点{
data_t*data=nullptr;
b绿色节点*子节点=nullptr;
~b绿色节点(){
删除数据;
删除[]个子节点;
数据=空PTR;
子节点=nullptr;
}
};
/******************************************************************************
*二叉树结构设置
******************************************************************************/
模板
B类树{
枚举节点目录:未签名{
BNODE_LEFT=0,
BNODE_RIGHT=1,
BNODE_MAX
};
受保护的:
B三极头;
无符号节点=0;
私人:
bTreeNode*迭代(const key_t*k,bool createNodes);
公众:
~bTree(){}
//STL映射行为
数据和操作员[](常数键和k);
无效推送(常数键t&k、常数数据t&d);
无效pop(常数键t&k);
布尔哈斯达特(康斯特基特和k);
常数数据*getData(常数键&k);
无符号大小()常量{return numNodes;}
无效清除();
};
/*
*二叉树——元素迭代
*/
模板
bTreeNode*bTree::iterate(const key_t*k,bool createNodes){
node_dir;
无符号bytePos=0;
bTreeNode*bNodeer=&head;
常量位掩码*byteIter=nullptr;
while(byteIter=treeShared::getKeyByte(k,bytePos++){
for(int currBit=0;currBitoperator[](currBit)?BNODE_LEFT:BNODE_RIGHT;
//检查是否需要制作新的bTreeNode
如果(!bNoder->子节点){
如果(创建节点){
//创造
template <typename key_t>
inline const bitMask* treeShared::getKeyByte( const key_t* k, unsigned iter ) {
return (iter < sizeof( key_t ))
? reinterpret_cast< const bitMask* >( k+iter )
: nullptr;
}