更新:我无法让“平衡”工作,因为我无法让“doAVLBalance”识别成员函数“isBalanced()”,“isRightHeavy()”,“isLeftHeavy” 。我不知道为什么!我完全尝试了Sash的例子(第3个答案),但我得到“减速是不兼容的”我无法解决这个问题......所以我试着按照我的方式去做...它告诉我那些成员函数不存在,当时他们显然做到了。
“错误:类”IntBinaryTree:TreeNode“没有成员”isRightHeavy“。 在尝试了最后4个小时之后我被困了:(。下面更新了代码,非常感谢帮助!!
我正在创建一个基于 String的二进制搜索树,需要将其设为“平衡”树。我该怎么做? * 请帮助!!提前谢谢!
BinarySearchTree.cpp:
bool IntBinaryTree::leftRotation(TreeNode *root)
{
//TreeNode *nodePtr = root; // Can use nodePtr instead of root, better?
// root, nodePtr, this->?
if(NULL == root)
{return NULL;}
TreeNode *rightOfTheRoot = root->right;
root->right = rightOfTheRoot->left;
rightOfTheRoot->left = root;
return rightOfTheRoot;
}
bool IntBinaryTree::rightRotation(TreeNode *root)
{
if(NULL == root)
{return NULL;}
TreeNode *leftOfTheRoot = root->left;
root->left = leftOfTheRoot->right;
leftOfTheRoot->right = root;
return leftOfTheRoot;
}
bool IntBinaryTree::doAVLBalance(TreeNode *root)
{
if(NULL==root)
{return NULL;}
else if(root->isBalanced()) // Don't have "isBalanced"
{return root;}
root->left = doAVLBalance(root->left);
root->right = doAVLBalance(root->right);
getDepth(root); //Don't have this function yet
if(root->isRightHeavy()) // Don't have "isRightHeavey"
{
if(root->right->isLeftheavey())
{
root->right = rightRotation(root->right);
}
root = leftRotation(root);
}
else if(root->isLeftheavey()) // Don't have "isLeftHeavey"
{
if(root->left->isRightHeavey())
{
root->left = leftRotation(root->left);
}
root = rightRotation(root);
}
return root;
}
void IntBinaryTree::insert(TreeNode *&nodePtr, TreeNode *&newNode)
{
if(nodePtr == NULL)
nodePtr = newNode; //Insert node
else if(newNode->value < nodePtr->value)
insert(nodePtr->left, newNode); //Search left branch
else
insert(nodePtr->right, newNode); //search right branch
}
//
// Displays the number of nodes in the Tree
int IntBinaryTree::numberNodes(TreeNode *root)
{
TreeNode *nodePtr = root;
if(root == NULL)
return 0;
int count = 1; // our actual node
if(nodePtr->left !=NULL)
{ count += numberNodes(nodePtr->left);
}
if(nodePtr->right != NULL)
{
count += numberNodes(nodePtr->right);
}
return count;
}
// Insert member function
void IntBinaryTree::insertNode(string num)
{
TreeNode *newNode; // Poitner to a new node.
// Create a new node and store num in it.
newNode = new TreeNode;
newNode->value = num;
newNode->left = newNode->right = NULL;
//Insert the node.
insert(root, newNode);
}
// More member functions, etc.
BinarySearchTree.h:
class IntBinaryTree
{
private:
struct TreeNode
{
string value; // Value in the node
TreeNode *left; // Pointer to left child node
TreeNode *right; // Pointer to right child node
};
//Private Members Functions
// Removed for shortness
void displayInOrder(TreeNode *) const;
public:
TreeNode *root;
//Constructor
IntBinaryTree()
{ root = NULL; }
//Destructor
~IntBinaryTree()
{ destroySubTree(root); }
// Binary tree Operations
void insertNode(string);
// Removed for shortness
int numberNodes(TreeNode *root);
//int balancedTree(string, int, int); // TreeBalanced
bool leftRotation(TreeNode *root);
bool rightRotation(TreeNode *root);
bool doAVLBalance(TreeNode *root); // void doAVLBalance();
bool isAVLBalanced();
int calculateAndGetAVLBalanceFactor(TreeNode *root);
int getAVLBalanceFactor()
{
TreeNode *nodePtr = root; // Okay to do this? instead of just
// left->mDepth
// right->mDepth
int leftTreeDepth = (left !=NULL) ? nodePtr->left->Depth : -1;
int rightTreeDepth = (right != NULL) ? nodePtr->right->Depth : -1;
return(leftTreeDepth - rightTreeDepth);
}
bool isRightheavey() { return (getAVLBalanceFactor() <= -2); }
bool isLeftheavey() { return (getAVLBalanceFactor() >= 2); }
bool isBalanced()
{
int balanceFactor = getAVLBalanceFactor();
return (balanceFactor >= -1 && balanceFactor <= 1);
}
int getDepth(TreeNode *root); // getDepth
void displayInOrder() const
{ displayInOrder(root); }
// Removed for shortness
};
答案 0 :(得分:1)
有很多方法可以做到这一点,但我建议你实际上不要这样做。如果你想存储字符串的BST,有更好的选择:
使用预先编写的二进制搜索树类。 C ++ std :: set类提供与平衡二叉搜索树相同的时间保证,并且通常如此实现。它比使用自己的BST更容易使用。
请改用trie。 trie数据结构比字符串BST更简单,更高效,根本不需要平衡,并且比BST更快。
如果你真的必须写自己的平衡BST,你有很多选择。大多数使用平衡的BST实现都非常复杂,并不适合胆小的人。我建议实现treap或splay树,它们是两个平衡的BST结构,实现起来相当简单。它们都比你上面的代码更复杂,我不能在这个短的空间中提供实现,但维基百科对这些结构的搜索应该会给你很多关于如何继续的建议。
希望这有帮助!
答案 1 :(得分:1)
不幸的是,我们的程序员是字面上的野兽。
将其设为“平衡”树。
“平衡”取决于上下文。当最大深度的节点与最小深度的节点之间的差异最小化时,介绍性数据结构类通常指的是“平衡”的树。但是,正如Templatetypedef先生所提到的,展开树被视为平衡树。这是因为它可以在少数节点频繁访问的情况下很好地平衡树。这是因为在这些情况下,传统的二进制树在映射树中获取数据所需的节点遍历次数较少。另一方面,它在逐个访问的基础上的最坏情况表现可能与链表一样糟糕。
说到链接列表......
因为否则没有“平衡”,它与我阅读的链接列表相同并且无法实现目的。
它可以一样糟糕,但对于随机插入则不然。如果插入已排序的数据,大多数二叉搜索树实现将存储数据,如膨胀和有序链表。但是,这只是因为你不断地构建树的一面。 (想象一下,将1,2,3,4,5,6,7等插入到二叉树中。在纸上试一试,看看会发生什么。)
如果你必须在理论上最坏情况必须保证的意义上保持平衡,我建议你查找红黑树。 (谷歌,第二个链接非常好。)
如果你必须以合理的方式为这个特定场景平衡它,我会使用整数索引和一个不错的散列函数 - 这样平衡将在没有任何额外代码的情况下概率发生。也就是说,使你的比较函数看起来像hash(strA)&lt; hash(strB)而不是你现在拥有的。 (对于这种情况的快速但有效的哈希,查找FNV哈希。首先点击谷歌。直到你看到有用的代码。)如果你愿意,你可以担心实施效率的细节。 (例如,每次比较时都不必执行两个哈希,因为其中一个字符串永远不会更改。)
如果你可以逃脱它,我强烈推荐后者,如果你在时间紧迫并且想要快速的东西。否则,红黑树是值得的,因为当你需要滚动自己的高度平衡二叉树时它们在实践中非常有用。
最后,解决上面的代码,请参阅下面代码中的注释:
int IntBinaryTree::numberNodes(TreeNode *root)
{
if(root = NULL) // You're using '=' where you want '==' -- common mistake.
// Consider getting used to putting the value first -- that is,
// "NULL == root". That way if you make that mistake again, the
// compiler will error in many cases.
return 0;
/*
if(TreeNode.left=null && TreeNode.right==null) // Meant to use '==' again.
{ return 1; }
return numberNodes(node.left) + numberNodes(node.right);
*/
int count = 1; // our actual node
if (left != NULL)
{
// You likely meant 'root.left' on the next line, not 'TreeNode.left'.
count += numberNodes(TreeNode.left);
// That's probably the line that's giving you the error.
}
if (right != NULL)
{
count += numberNodes(root.right);
}
return count;
}
答案 2 :(得分:1)
程序员使用AVL Tree概念来平衡二叉树。这很简单。更多信息可以在网上找到。快速维基link
下面是使用AVL算法进行树平衡的示例代码。
Node *BinarySearchTree::leftRotation(Node *root)
{
if(NULL == root)
{
return NULL;
}
Node *rightOfTheRoot = root->mRight;
root->mRight = rightOfTheRoot->mLeft;
rightOfTheRoot->mLeft = root;
return rightOfTheRoot;
}
Node *BinarySearchTree::rightRotation(Node *root)
{
if(NULL == root)
{
return NULL;
}
Node *leftOfTheRoot = root->mLeft;
root->mLeft = leftOfTheRoot->mRight;
leftOfTheRoot->mRight = root;
return leftOfTheRoot;
}
Node *BinarySearchTree::doAVLBalance(Node *root)
{
if(NULL == root)
{
return NULL;
}
else if(root->isBalanced())
{
return root;
}
root->mLeft = doAVLBalance(root->mLeft);
root->mRight = doAVLBalance(root->mRight);
getDepth(root);
if(root->isRightHeavy())
{
if(root->mRight->isLeftHeavy())
{
root->mRight = rightRotation(root->mRight);
}
root = leftRotation(root);
}
else if(root->isLeftHeavy())
{
if(root->mLeft->isRightHeavy())
{
root->mLeft = leftRotation(root->mLeft);
}
root = rightRotation(root);
}
return root;
}
班级定义
class BinarySearchTree
{
public:
// .. lots of methods
Node *getRoot();
int getDepth(Node *root);
bool isAVLBalanced();
int calculateAndGetAVLBalanceFactor(Node *root);
void doAVLBalance();
private:
Node *mRoot;
};
class Node
{
public:
int mData;
Node *mLeft;
Node *mRight;
bool mHasVisited;
int mDepth;
public:
Node(int data)
: mData(data),
mLeft(NULL),
mRight(NULL),
mHasVisited(false),
mDepth(0)
{
}
int getData() { return mData; }
void setData(int data) { mData = data; }
void setRight(Node *right) { mRight = right;}
void setLeft(Node *left) { mLeft = left; }
Node * getRight() { return mRight; }
Node * getLeft() { return mLeft; }
bool hasLeft() { return (mLeft != NULL); }
bool hasRight() { return (mRight != NULL); }
bool isVisited() { return (mHasVisited == true); }
int getAVLBalanceFactor()
{
int leftTreeDepth = (mLeft != NULL) ? mLeft->mDepth : -1;
int rightTreeDepth = (mRight != NULL) ? mRight->mDepth : -1;
return(leftTreeDepth - rightTreeDepth);
}
bool isRightHeavy() { return (getAVLBalanceFactor() <= -2); }
bool isLeftHeavy() { return (getAVLBalanceFactor() >= 2); }
bool isBalanced()
{
int balanceFactor = getAVLBalanceFactor();
return (balanceFactor >= -1 && balanceFactor <= 1);
}
};