C++ 如何在没有父指针的情况下实现AVL树的插入?
我看到了一些关于AVL的C++ 如何在没有父指针的情况下实现AVL树的插入?,c++,algorithm,data-structures,tree,avl-tree,C++,Algorithm,Data Structures,Tree,Avl Tree,我看到了一些关于AVL的rebalance()函数实现的文章。 每次插入后,我们都应该检查插入节点的祖先节点是否平衡。 所以我认为,为了检查祖先的平衡,我了解了插入节点的父节点 但是,我想知道有没有其他方法可以不用使用父指针来实现这一点? e、 例如,节点结构: struct Node { int data; struct Node *lchild, *rchild; //*parent; }; 在遍历树时,可以维护当前节点的堆栈 stack<Node*> node
rebalance()
函数实现的文章。每次插入后,我们都应该检查插入节点的祖先节点是否平衡。
所以我认为,为了检查祖先的平衡,我了解了插入节点的父节点 但是,我想知道有没有其他方法可以不用使用父指针来实现这一点?
e、 例如,节点结构:
struct Node {
int data;
struct Node *lchild, *rchild; //*parent;
};
在遍历树时,可以维护当前节点的堆栈
stack<Node*> nodeStack;
创建子对象时,请按以下方式执行:
node.children = new Node[2]; or node.children = malloc(sizeof(Node) * 2);
node.children[0].parent = node;
node.children[1].parent = node;
使用双指针(或对C++所要求的指针的引用)应该完全消除对父指针的需要
typedef struct Node {
int value;
int height;
struct Node *left;
struct Node *right;
} Node;
int height(Node *node) {
return (node == NULL) ? -1 : node->height;
}
void insert(Node * & node, int value) {
if (node == NULL) {
node = new Node();
node->value = value;
} else if (value < node->value) {
insert(node->left, value);
if (height(node->left) - height(node->right) == 2) {
if (value < note->left->value) {
singleRotateWithLeftChild(node);
} else {
doubleRotateWithLeftChild(node);
}
}
} else if (value > node->value) {
// Symmetric case
}
node->height = 1 + max(height(node->left), height(node->right));
}
typedef结构节点{
int值;
内部高度;
结构节点*左;
结构节点*右;
}节点;
整数高度(节点*节点){
返回(node==NULL)?-1:节点->高度;
}
无效插入(节点*&节点,int值){
if(node==NULL){
node=新节点();
节点->值=值;
}else if(值<节点->值){
插入(节点->左,值);
如果(高度(节点->左侧)-高度(节点->右侧)==2){
如果(值<注释->左->值){
singleRotateWithLeftChild(节点);
}否则{
doubleRotateWithLeftChild(节点);
}
}
}else if(值>节点->值){
//对称情况
}
节点->高度=1+最大值(高度(节点->左侧)、高度(节点->右侧));
}
如果我正确地记住了我的数据结构作业:
您要做的是将节点本身中的平衡因子存储为int,即:
- -1:节点的左子树比右子树高一级(左重)
- 0节点处于平衡状态;或
- 1右子树较高(右重)李>
如果插入到子树中,并且插入(…)返回false:
如果当前节点的平衡因子为0,则插入到左侧的子树中,插入(lchild)返回true:
如果当前节点的平衡因子为-1,则插入到左侧的子树中,插入(lchild)返回true:
平衡因子将更改为-2,这意味着您必须通过执行适当的旋转来重新平衡节点。我承认,我对四次旋转对平衡因子的影响以及insert(current)将返回的内容都是空白,希望前面的示例能够充分解释跟踪节点平衡的方法。我的编码方式是,当您在树中搜索要删除的元素时,临时将您遍历的子链接(左或右)更改为已遍历节点堆栈中的链接(实际上是临时父指针)。然后从堆栈中弹出每个节点,恢复子指针,然后重新平衡 <>对于C++编码,请参见./p>中的删除成员函数(当前行882) 对于C编码,请参阅中的宏调用L__;(remove)生成其名称的函数 我认为有一个父指针对插入没有任何用处
如果要删除由节点指针而不是唯一键标识的节点,那么我认为使用父指针可能会更快。由于这个问题没有完整的实现,我决定添加一个。这可以通过使用递归的
insert
返回当前节点来完成。下面是代码:
typedef struct Node {
int value;
int height;
struct Node *left;
struct Node *right;
} Node;
int height(Node *node) {
return (node == NULL) ? -1 : node->height;
}
void insert(Node * & node, int value) {
if (node == NULL) {
node = new Node();
node->value = value;
} else if (value < node->value) {
insert(node->left, value);
if (height(node->left) - height(node->right) == 2) {
if (value < note->left->value) {
singleRotateWithLeftChild(node);
} else {
doubleRotateWithLeftChild(node);
}
}
} else if (value > node->value) {
// Symmetric case
}
node->height = 1 + max(height(node->left), height(node->right));
}
typedef struct node
{
int val;
struct node* left;
struct node* right;
int ht;
} node;
int height(node* current) {
return current == nullptr ? -1 : current->ht;
}
int balanceFactor(node* root) {
int leftHeight = height(root->left);
int rightHeight = height(root->right);
return leftHeight - rightHeight;
}
int calcHeight(node* n) {
int leftHeight = height(n->left);
int rightHeight = height(n->right);
return max(leftHeight, rightHeight) + 1;
}
node* insert(node * root,int val) {
/**
First, recusively insert the item into the tree
*/
if (root == nullptr) {
root = new node();
root->val = val;
} else if (root->val < val) {
root->right = insert(root->right, val);
//the height can increase only because of the right node
root->ht = std::max(root->ht, root->right->ht + 1);
} else {
root->left = insert(root->left, val);
//the height can increase only because of the left node
root->ht = std::max(root->ht, root->left->ht + 1);
}
//after insertion on this depth is complete check if rebalancing is required
// the right subtree must be rebalanced
if (balanceFactor(root) == -2) {
node* r = root->right;
node* rl = r->left;
// it's a right right case
if (balanceFactor(r) == -1) {
r->left = root;
root->right = rl;
root->ht = calcHeight(root);
r->ht = calcHeight(r);
//return new root
return r;
} else { // it's a right left case
node* rlr = rl->right;
node* rll = rl->left;
rl->left = root;
root->right = rll;
rl->right = r;
r->left = rlr;
root->ht = calcHeight(root);
r->ht = calcHeight(r);
rl->ht = calcHeight(rl);
return rl;
}
} else if (balanceFactor(root) == 2) {
node* l = root->left;
node* lr = l->right;
// it's a left left case
if (balanceFactor(l) == 1) {
l->right = root;
root->left = lr;
root->ht = calcHeight(root);
l->ht = calcHeight(l);
//return new root
return l;
} else { // it's a left right case
node* lrl = lr->left;
node* lrr = lr->right;
lr->right = root;
lr->left = l;
root->left = lrr;
l->right = lrl;
root->ht = calcHeight(root);
l->ht = calcHeight(l);
lr->ht = calcHeight(lr);
return lr;
}
}
return root;
}
typedef结构节点
{
int-val;
结构节点*左;
结构节点*右;
int-ht;
}节点;
整数高度(节点*当前){
返回电流==nullptr?-1:电流->电流;
}
整数平衡因子(节点*根){
int leftHeight=高度(根->左);
int rightHeight=高度(根->右);
返回leftHeight-rightHeight;
}
int calcHeight(节点*n){
int leftHeight=高度(n->left);
int rightHeight=高度(n->right);
返回最大值(leftHeight,rightHeight)+1;
}
节点*插入(节点*根,int val){
/**
首先,重复地将项目插入到树中
*/
if(root==nullptr){
根=新节点();
根->val=val;
}else if(root->valright=插入(root->right,val);
//高度只能因右侧节点而增加
root->ht=std::max(root->ht,root->right->ht+1);
}否则{
根->左=插入(根->左,val);
//高度可以用英寸表示