所以我一直在研究这种自平衡的AVL树,我觉得它的工作正常,但是有一些内存泄漏。我搜索并经历了一百万次,感觉就像想弄清楚我做错了什么,但我对这个整个内存泄漏事情感到陌生,显然需要了解更多。如果有人可以帮助我,或者可以看到哪些漏洞可能会很棒,这里是我的AVL树的代码:
#pragma once
#include <algorithm>
#include <fstream>
#include "LinkedList.h"
template <typename ItemType>
class AVLTreeSet {
private:
struct Node {
ItemType info;
Node* left;
Node* right;
int height;
};
Node* root;
int size;
public:
AVLTreeSet()
{
root = NULL;
size = 0;
}
~AVLTreeSet()
{
clear();
}
void clear()
{
Node* n = root;
if(n != NULL)
{
clearTree(n->left);
clearTree(n->right);
delete n;
}
root = NULL;
}
void clearTree(Node* n)
{
if(n != NULL)
{
clearTree(n->left);
clearTree(n->right);
delete n;
}
}
void print(std::ofstream &out)
{
//cout << "HERE" << endl;
LinkedList<Node*> list;
int level = 0;
int levelSize;
int count = 0;
Node* n = root;
if (n == NULL)
{
return;
}
list.insert(n);
levelSize = list.getSize();
while(list.getSize() != 0)
{
count = 0;
out << "level " << level << ": ";
for (unsigned i = levelSize; i > 0; i--)
{
count++;
if (count > 8)
{
out << std::endl;
out << "level " << level << ": ";
count = 0;
}
n = list.getInfo();
out <<n->info << "(" << getHeight(n) << ") ";
if (n->left != NULL)
{
//cout << "left is not null" << endl;
list.insert(n->left);
}
if (n->right != NULL)
{
list.insert(n->right);
//cout << "right is not null" << endl;
}
list.remove();
}
levelSize = list.getSize();
level++;
out << std::endl;
//levelSize = list.getSize();
}
}
void insert(const ItemType& item)
{
//cout << "Insert FUNCTION" << endl;
Node* current = root;
if (current == NULL)
{
//cout << "ADD FUNCTION NULL" << endl;
current = new Node;
current->info = item;
current->left = NULL;
current->right = NULL;
current->height = 0;
root = current;
size++;
//cout << current->info << endl;
//cout << current->height << endl;
return;
}
if (current->info > item)
{
current->left = add(item, current->left);
}
if (current->info < item)
{
current->right = add(item, current->right);
}
current = balance(current);
root = current;
}
Node* add(const ItemType& item, Node* current)
{
if (current == NULL)
{
current = new Node;
current->info = item;
current->left = NULL;
current->right = NULL;
current->height = 0;
size++;
}
if (current->info > item)
{
current->left = add(item, current->left);
}
if (current->info < item)
{
current->right = add(item, current->right);
}
return current;
}
void remove(const ItemType& item)
{
Node* current = root;
if (current == NULL)
{
//cout << "NULL" << endl;
return;
}
if (current->info == item)
{
//cout << "FOUND" << endl;
current = removeNext(item, current);
current = balance(current);
root = current;
return;
}
if (current->info > item)
{
//cout << "LEFT" << endl;
current->left = removeNext(item, current->left);
if (current == root)
{
root = balance(current);
}
return;
}
if (current->info < item)
{
//cout << "RIGHT" << endl;
current->right = removeNext(item, current->right);
if (current == root)
{
root = balance(current);
}
return;
}
}
Node* removeNext(const ItemType& item, Node* current)
{
Node* temp;
if (current != NULL)
{
if (current->info > item)
{
//cout << "REMOVENEXT LEFT" << endl;
current->left = removeNext(item, current->left);
return current;
}
if (current->info < item)
{
//cout << "REMOVENEXT RIGHT" << endl;
current->right = removeNext(item, current->right);
return current;
}
//cout << "FOUND" << endl;
if (current->left != NULL && current->right != NULL)
{
//cout << "LEFT AND RIGHT CHILDREN" << endl;
temp = current;
current = CTR(current->right);
current->left = temp->left;
//cout << current->info << endl;
//looker = removeNext(current->info, temp->right);
delete temp;
size--;
current = balance(current);
return current;
}
else if (current->right != NULL)
{
//cout << "RIGHT ONE CHILD" << endl;
temp = current;
current = current->right;
delete temp;
size--;
current = balance(current);
return current;
}
else if (current->left != NULL)
{
//cout << "LEFT ONE CHILD" << endl;
temp = current;
current = current->left;
delete temp;
size--;
current = balance(current);
return current;
}
//cout << "CURRENT NODE" << endl;
delete current;
size--;
return NULL;
}
//cout << "NOT FOUND" << endl;
return current;
}
Node* CTR(Node* current)
{
while(current->left != NULL)
{
//cout << "ENTERED LOOP" << endl;
current = current->left;
}
//cout << current->info << endl;
return current;
}
bool find(const ItemType& item)
{
Node* current = root;
bool find = false;
if (current == NULL)
{
return find;
}
if (item == current->info)
{
find = true;
return find;
}
if (current->info > item && current->left != NULL)
{
find = findLeft(item, current->left);
}
if (current->info < item && current->right != NULL)
{
find = findRight(item, current->right);
}
return find;
}
bool findLeft(const ItemType& item, Node* current)
{
bool find = false;
if (item == current->info)
{
find = true;
return find;
}
if (current->info > item && current->left != NULL)
{
find = findLeft(item, current->left);
}
if (current->info < item && current->right != NULL)
{
find = findRight(item, current->right);
}
return find;
}
bool findRight(const ItemType& item, Node* current)
{
bool find = false;
if (item == current->info)
{
find = true;
return find;
}
if (current->info > item && current->left != NULL)
{
find = findLeft(item, current->left);
}
if (current->info < item && current->right != NULL)
{
find = findRight(item, current->right);
}
return find;
}
int getHeight(Node* temp)
{
int h = 0;
if (temp != NULL)
{
int l_height = getHeight(temp->left);
int r_height = getHeight(temp->right);
int max_height = std::max(l_height, r_height);
h = max_height + 1;
}
return h;
}
void setHeight(Node* n)
{
n->height = std::max(getHeight(n->right), getHeight(n->left)) + 1;
}
Node* balance(Node* n)
{
if (size == 1)
{
return n;
}
else if(getHeight(n->left) - getHeight(n->right) > 1) //n is out of balance
{
//cout << "BALANCE RIGHT" << endl;
n = balanceToRight(n);
}
else if(getHeight(n->right) - getHeight(n->left) > 1)
{
//cout << "BALANCE LEFT" << endl;
n = balanceToLeft(n);
}
return n;
}
Node* balanceToRight(Node* n)
{
if(getHeight(n->left->right) > getHeight(n->left->left))
{
n->left = rotateLeft(n->left); //<--- extra step for double rotate
}
n = rotateRight(n); //<--- this is for single
return n;
}
Node* balanceToLeft(Node* n)
{
if(getHeight(n->right->left) > getHeight(n->right->right))
{
n->right = rotateRight(n->right); //<--- extra step for double rotate
}
n = rotateLeft(n); //<--- this is for single
return n;
}
Node* rotateRight(Node* n)
{
Node* temp = n->left;
n->left = temp->right;
temp->right = n;
setHeight(n); //<--- set first
setHeight(temp);
return temp;
}
Node* rotateLeft(Node* n)
{
Node* temp = n->right;
n->right = temp->left;
temp->left = n;
setHeight(n); //<--- set first
setHeight(temp);
return temp;
}
};
我通过读取一个调用我的AVLtree命令的main.cpp文件来运行程序。我知道很多代码,但我强调,因为我无法找到可能发生的地方。感谢。
答案 0 :(得分:0)
你怎么知道有内存泄漏?
除非您使用某种工具来查找内存泄漏,例如@jsantander建议的valgrind,否则请尝试以下操作:
避免代码重复。目前的形式存在太多重复。例如,只需调用clear()
即可简化cleartree(root)
。类似于insert()
。
打印/记录每个内存分配(new
)和解除分配(delete
)
始终保持增加计数器newCount
和deleteCount
。在重要方法结束时,添加一个断言assert( newCount - deleteCount == size );
。在第一次发生内存泄漏时,assert()
会爆炸。请参阅http://accu.org/var/uploads/journals/overload102.pdf,第7页,&#34;其他体验&#34;