对于前缀树,JAVA和C++编码不一样的在于节点删除。JAVA有JVM,对new的变量无需手动删除,而C++需手动删除动态分配的堆内存,也就是new delete 得成对出现。
C++ :必须遍历每个节点,手动释放空间,然后回到上级节点,再把位置标空=NULL。
JAVA :删除直接下级节点 标空 ,即=NULL即可。
C++我并没有严格的测试 --destroy---函数,如有不对,还望指正。
JAVA代码:
node->nexts[path] = NULL;
class TrieNodeArr{
public:
int pass;
int end;
TrieNodeArr* nexts[MaxNum]; //此处为指向下一个Node的指针
TrieNodeArr()
{
pass = 0;
end = 0;
for (int i = 0; i < MaxNum; i++) //构造函数不用new
{
nexts[i] = NULL;
}
//如果字符全是小写 nexts 下级对应的路的位置 a-z 26个字母
//0-a ...25-z
//nexts[0]==NULL;表示没有走向a的路。
//nexts[0]!=NULL;表示有走向a的路。
//...
}
};
void Trietree::myDeleteJAVA(string word)
{
cout << "Trietree myDeleteJAVA******************" << endl;
if (mysearch(word)) //如果有这个词
{
char c;
TrieNodeArr* node = root; //2.取得根结点
node->pass--;
int path = 0;
for (int i = 0; i < word.length(); i++) //3.遍历字符串
{
char c = word[i]; //4.得到单个字符
c = c - 'a'; //5.是哪条路
if (--node->nexts[path]->pass == 0) // 6.下级节点的p值为0,
{
node->nexts[path] = NULL; //7.直接让下一节点,比如"d"方向上的路标空
return;
}
node = node->nexts[path];
}
node->end--;
}//9.这个节点上路e值-1
}
C++代码:
对比JAVA node->nexts[path] = NULL; //7.直接让下一节点,比如"d"方向上的路标空
C++就是多了 destroy(node->nexts[path]);
void Trietree::destory(TrieNodeArr* node)
{
if (node == nullptr)
return;
for (int i = 0; i < MaxNum; i++)
{
destory(node->nexts[i]);
}
delete node;
node = nullptr;
}
void Trietree::myDeleteCPP(string word)
{
cout << "Trietree myDeleteCPP******************" << endl;
if (mysearch(word)) //如果有这个词
{
char c;
int path = 0;
TrieNodeArr* node = root; //2.取得根结点
node->pass--;
/delete/
int deleteIndex = -1;
TrieNodeArr* deletenode = NULL;
for (int i = 0; i < word.length(); i++) //3.遍历字符串
{
char c = word[i]; //4.得到单个字符
c = c - 'a'; //5.是哪条路
// if (node->nexts[path]-- == 1) //6 这个节点上路p值-1 node->nexts[path]-- next的前一个
if (--node->nexts[path]->pass == 0) //当前节点p值为0
{
deletenode = deletenode == NULL ? node : deletenode;
deleteIndex = deleteIndex == -1 ? path : deleteIndex;
destory(node->nexts[path]);
}
node = node->nexts[path]; //8.node移到下一个节点
}
node->end--;
deletenode->nexts[deleteIndex] = NULL;
}//9.这个节点上路e值-1
}