- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
如果我没记错的话,当涉及到2-3-4 树
的破坏时,它应该类似于二叉树,只有 4 个 child (递归)。下面是我的特定于析构函数的代码,带有简单的递归删除。
问题是我仍然漏水。该文件仅包含我的 2-3-4 树。
我相信这是为 2-3-4 树
实现析构函数的正确方法,但我的实现似乎不正确。谁能指出我的逻辑错误?我画了图表,看起来不错。
//Destructor
template < typename KEY , typename T >
Map< KEY , T >::~Map(){
destructCode();
}
//Common code for deallocation
template < typename KEY , typename T >
void Map< KEY , T >::destructCode(){
destruct( _root );
}
//Recursive delete helper
template < typename KEY , typename T >
void Map< KEY , T >::destruct( Elem* node ){
if( node -> cOne )
destruct( node -> cOne );
if( node -> cTwo )
destruct( node -> cTwo );
if( node -> cThree )
destruct( node -> cThree );
if( node -> cFour )
destruct( node -> cFour );
delete node;
}
我的节点设计:
Elem {
KEY k1, k2, k3;
T t1, t2, t3;
//Children
Elem *cOne, *cTwo, *cThree, *cFour;
Elem *parent;
//numChildren = #node type
//Contains numChildren - 1 data items
int _numChildren;
};
我的插入代码。我目前还没有实现删除功能。
//Sorts the keys of the node to include the new keyvalue pairing
template < typename KEY , typename T >
void Map< KEY , T >::keyAdding( KEY k , T t , Elem * node , Elem * smaller , Elem * bigger ){
if( node -> _numChildren == 4 )//3 keys already
cout << "Problem; adding a key to a 4-node" << endl;
else if( node -> _numChildren == 3 ){//2 keys
if( k < node -> k1 ){//Smallest of the three
node -> k3 = node -> k2;
node -> t3 = node -> t2;
node -> k2 = node -> k1;
node -> t2 = node -> t1;
node -> k1 = k;
node -> t1 = t;
node -> cFour = node -> cThree;
node -> cThree = node -> cTwo;
node -> cTwo = bigger;
node -> cOne = smaller;
}
else if( k < node -> k2 ){//Mid
node -> k3 = node -> k2;
node -> t3 = node -> t2;
node -> k2 = k;
node -> t2 = t;
node -> cFour = node -> cThree;
node -> cThree = bigger;
node -> cTwo = smaller;
}
else{//Largest
node -> k3 = k;
node -> t3 = t;
node -> cFour = bigger;
node -> cThree = smaller;
}
node -> _numChildren++;
}
else{//1 key
if( k < node -> k1 ){
node -> k2 = node -> k1;
node -> t2 = node -> t1;
node -> k1 = k;
node -> t1 = t;
node -> cThree = node -> cTwo;
node -> cTwo = bigger;
node -> cOne = smaller;
}
else{
node -> k2 = k;
node -> t2 = t;
node -> cThree = bigger;
node -> cTwo = smaller;
}
node -> _numChildren++;
}
}
//Sorts the keys of the node to include the new keyvalue pairing
template < typename KEY , typename T >
void Map< KEY , T >::keyAdding( KEY k , T t , Elem * node ){
if( node -> _numChildren == 4 )//3 keys already
cout << "Problem; adding a key to a 4-node" << endl;
else if( node -> _numChildren == 3 ){//2 keys
if( k < node -> k1 ){//Smallest of the three
node -> k3 = node -> k2;
node -> t3 = node -> t2;
node -> k2 = node -> k1;
node -> t2 = node -> t1;
node -> k1 = k;
node -> t1 = t;
}
else if( k < node -> k2 ){//Mid
node -> k3 = node -> k2;
node -> t3 = node -> t2;
node -> k2 = k;
node -> t2 = t;
}
else{//Largest
node -> k3 = k;
node -> t3 = t;
}
node -> _numChildren++;
}
else{//1 key
if( k < node -> k1 ){
node -> k2 = node -> k1;
node -> t2 = node -> t1;
node -> k1 = k;
node -> t1 = t;
}
else{
node -> k2 = k;
node -> t2 = t;
}
node -> _numChildren++;
}
}
//Insert, return true if successful.
template < typename KEY , typename T >
bool Map< KEY , T >::insert(KEY k , T t ){
if( _root == 0 ){//Empty
_root = new Elem;
_root -> _numChildren = 2;
_root -> cOne = NULL;
_root -> cTwo = NULL;
_root -> cThree = NULL;
_root -> cFour = NULL;
_root -> k1 = k;
_root -> t1 = t;
_size++;
return true;
}
else
return insert( k , t , _root );
}
//Recursive insert helper
template < typename KEY , typename T >
bool Map< KEY , T >::insert(KEY k , T t , Elem * rRoot ){
Elem * temp = rRoot;
if( temp -> _numChildren == 4 ){//4-node
//Save middle value.
KEY kTemp = temp -> k2;
T tTemp = temp -> t2;
//Remove middle value, making a 3-node.
temp -> k2 = temp -> k3;
temp -> t2 = temp -> t3;
//temp -> k3 = NULL;
//temp -> t3 = NULL;
temp -> _numChildren--;
//Split the (now) 3-node into a pair of 2-nodes
Elem * twoNode1 = new Elem;
twoNode1 -> _numChildren = 2;
twoNode1 -> parent = temp -> parent;
twoNode1 -> cOne = temp -> cOne;
twoNode1 -> cTwo = temp -> cTwo;
twoNode1 -> k1 = temp -> k1;
twoNode1 -> t1 = temp -> t1;
if( twoNode1 -> cOne )
twoNode1 -> cOne -> parent = twoNode1;
if( twoNode1 -> cTwo )
twoNode1 -> cTwo -> parent = twoNode1;
//2-nodes do not have values for these.
twoNode1 -> cThree = NULL;
twoNode1 -> cFour = NULL;
//twoNode1 -> k2 = NULL;
//twoNode1 -> t2 = NULL;
//twoNode1 -> k3 = NULL;
//twoNode1 -> t3 = NULL;
//Second 2-node...
Elem * twoNode2 = new Elem;
twoNode2 -> _numChildren = 2;
twoNode2 -> parent = temp -> parent;
twoNode2 -> cOne = temp -> cThree;
twoNode2 -> cTwo = temp -> cFour;
twoNode2 -> k1 = temp -> k3;
twoNode2 -> t1 = temp -> t3;
if( twoNode2 -> cOne )
twoNode2 -> cOne -> parent = twoNode1;
if( twoNode2 -> cTwo )
twoNode2 -> cTwo -> parent = twoNode1;
//2-Nodes do not have values for these.
twoNode2 -> cThree = NULL;
twoNode2 -> cFour = NULL;
//twoNode2 -> k2 = NULL;
//twoNode2 -> t2 = NULL;
//twoNode2 -> k3 = NULL;
//twoNode2 -> t3 = NULL;
//We're at the root node.
if( temp == _root ){
_root -> _numChildren = 2;
_root -> parent = NULL; //Root has no parent, silly.
_root -> cOne = twoNode1;
_root -> cTwo = twoNode2;
_root -> k1 = kTemp;
_root -> t1 = tTemp;
//2-Nodes do not have values for these.
_root -> cThree = NULL;
_root -> cFour = NULL;
//_root -> k2 = NULL;
//_root -> t2 = NULL;
//_root -> k3 = NULL;
//_root -> t3 = NULL;
//Update split node's parent
twoNode1 -> parent = _root;
twoNode2 -> parent = _root;
//Height has increased.
_height++;
//Ascend to root.
temp = _root;
}
//A generic 4-node somewhere in the tree.
else{
Elem * ntemp = temp;
temp = temp -> parent;
//Update split node's parent
twoNode1 -> parent = temp;
twoNode2 -> parent = temp;
keyAdding( kTemp , tTemp , temp , twoNode1 , twoNode2 );
}
}//4-node end
//Check if leaf
if( temp -> cOne == 0 && temp -> cTwo == 0 && temp -> cThree == 0 && temp -> cFour == 0 ){
keyAdding( k , t , temp );
_size++;
return true;
}
else{
if( temp -> _numChildren == 4 ){
cout << "Should not have a 4-node in leaf-checking.\n";
return -5;
}
else if( temp -> _numChildren == 3 ){
if( k < temp -> k1 )
insert( k , t , temp -> cOne );
else if( k < temp -> k2 )
insert( k , t , temp -> cTwo );
else
insert( k , t , temp -> cThree);
}
else{
if( k < temp -> k1 )
insert( k , t , temp -> cOne );
else
insert( k , t , temp -> cTwo );
}
}
}
瓦尔格林德:
-bash-4.2$ valgrind -v ./a.out
==18357== Memcheck, a memory error detector
==18357== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==18357== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==18357== Command: ./a.out
==18357==
--18357-- Valgrind options:
--18357-- -v
--18357-- Contents of /proc/version:
--18357-- Linux version 3.6.11-1.fc16.i686.PAE (mockbuild@bkernel02) (gcc version 4.6.3 20120306 (Red Hat 4.6.3-2) (GCC) ) #1 SMP Mon Dec 17 21:31:29 UTC 2012
--18357-- Arch and hwcaps: X86, x86-sse1-sse2
--18357-- Page sizes: currently 4096, max supported 4096
--18357-- Valgrind library directory: /usr/lib/valgrind
--18357-- Reading syms from /home/csu/jan99/Documents/CS515/A8/a.out (0x8048000)
--18357-- Reading syms from /usr/lib/valgrind/memcheck-x86-linux (0x38000000)
--18357-- object doesn't have a dynamic symbol table
--18357-- Reading syms from /lib/ld-2.14.90.so (0x463f2000)
--18357-- Considering /usr/lib/debug/.build-id/6f/895b79f95b39ef92d24ff50a16ff774b34b527.debug ..
--18357-- .. build-id is valid
--18357-- Reading suppressions file: /usr/lib/valgrind/default.supp
--18357-- REDIR: 0x4640b610 (strlen) redirected to 0x38052c08 (vgPlain_x86_linux_REDIR_FOR_strlen)
--18357-- REDIR: 0x4640b390 (index) redirected to 0x38052be3 (vgPlain_x86_linux_REDIR_FOR_index)
--18357-- Reading syms from /usr/lib/valgrind/vgpreload_core-x86-linux.so (0x4001000)
--18357-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so (0x4004000)
==18357== WARNING: new redirection conflicts with existing -- ignoring it
--18357-- new: 0x4640b390 (index ) R-> 0x04008270 index
==18357== WARNING: new redirection conflicts with existing -- ignoring it
--18357-- new: 0x4640b610 (strlen ) R-> 0x040086d0 strlen
--18357-- Reading syms from /usr/lib/libstdc++.so.6.0.16 (0x46971000)
--18357-- Considering /usr/lib/debug/.build-id/19/bce624dda8659f770012166d85bc075fb23f1a.debug ..
--18357-- .. build-id is valid
--18357-- Reading syms from /lib/libm-2.14.90.so (0x465e7000)
--18357-- Considering /usr/lib/debug/.build-id/b8/362b3b5d82f212d77d69fff8e503ae6fdcfe9b.debug ..
--18357-- .. build-id is valid
--18357-- Reading syms from /lib/libgcc_s-4.6.3-20120306.so.1 (0x4663f000)
--18357-- Considering /usr/lib/debug/.build-id/4b/65b2ab36082e9552ad2014fac436421c4f65ad.debug ..
--18357-- .. build-id is valid
--18357-- Reading syms from /lib/libc-2.14.90.so (0x46417000)
--18357-- Considering /usr/lib/debug/.build-id/ea/4850e94d2deab52b8469f1e68a98f4d6229e48.debug ..
--18357-- .. build-id is valid
--18357-- REDIR: 0x46498a40 (__GI_strrchr) redirected to 0x40080d0 (__GI_strrchr)
--18357-- REDIR: 0x46498780 (__GI_strlen) redirected to 0x40086b0 (__GI_strlen)
--18357-- REDIR: 0x46497fb0 (strcmp) redirected to 0x40014c0 (_vgnU_ifunc_wrapper)
--18357-- REDIR: 0x46562db0 (__strcmp_ssse3) redirected to 0x4009250 (strcmp)
--18357-- REDIR: 0x46498730 (strlen) redirected to 0x40014c0 (_vgnU_ifunc_wrapper)
--18357-- REDIR: 0x4649f3e0 (__strlen_sse2_bsf) redirected to 0x4008690 (strlen)
--18357-- REDIR: 0x46a24350 (operator new(unsigned int)) redirected to 0x4007820 (operator new(unsigned int))
--18357-- REDIR: 0x46499fa0 (memcpy) redirected to 0x40014c0 (_vgnU_ifunc_wrapper)
--18357-- REDIR: 0x4655ab70 (__memcpy_ssse3) redirected to 0x4009420 (memcpy)
--18357-- REDIR: 0x464994c0 (bcmp) redirected to 0x40014c0 (_vgnU_ifunc_wrapper)
--18357-- REDIR: 0x46565c10 (__memcmp_ssse3) redirected to 0x4009fd0 (bcmp)
1
1
1
1
1
1
1
one
five
ten
twenty
twenty-five
thirty
One-hundred
Delete
--18357-- REDIR: 0x46a221d0 (operator delete(void*)) redirected to 0x4006b10 (operator delete(void*))
Delete
Delete
Delete
--18357-- REDIR: 0x464943e0 (free) redirected to 0x4006e80 (free)
==18357==
==18357== HEAP SUMMARY:
==18357== in use at exit: 86 bytes in 3 blocks
==18357== total heap usage: 12 allocs, 9 frees, 375 bytes allocated
==18357==
==18357== Searching for pointers to 3 not-freed blocks
==18357== Checked 97,132 bytes
==18357==
==18357== LEAK SUMMARY:
==18357== definitely lost: 48 bytes in 1 blocks
==18357== indirectly lost: 38 bytes in 2 blocks
==18357== possibly lost: 0 bytes in 0 blocks
==18357== still reachable: 0 bytes in 0 blocks
==18357== suppressed: 0 bytes in 0 blocks
==18357== Rerun with --leak-check=full to see details of leaked memory
==18357==
==18357== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==18357== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-bash-4.2$
最佳答案
最好的办法是将原始指针替换为 std::unique_ptr< Elem >
.这样你根本不需要析构函数。当心Elem::parent
可能是非拥有指针,因此不应被替换。
关于c++ - 2-3-4 泄漏的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15962556/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!