AVL樹-平衡二叉樹
阿新 • • 發佈:2018-11-15
平衡二叉樹是高度平衡的二叉樹:
1 左右子樹的高度差最多為1.
2 主要的實現地方是插入平衡和刪除平衡。
3 為了實現平衡,每個節點儲存了一個高度h成員。
4 當插入和刪除破壞了平衡的時候需要進行旋轉;
5 根據左右子樹高度差的不同進行四中不同的旋轉:左左、右右、左右、右左
百度雲下載sln檔案:https://pan.baidu.com/s/1pxPGQDYhbcG-E6sE26WfuA
下面是插入和刪除的核心程式碼:
插入:
//Insert void CAVLTree::InsertPri(CTreeNode*& _pNode, CTreeNode*& _pParentNode, const int _key, const CEntry& _entry) { if (_pNode == nullptr)//如果節點為空,就在此節點處加入_entry資訊 { //Counter::AddCount(CounterType::AVLInsert); _pNode = new CTreeNode(); _pNode->key = _key; _pNode->value = _entry; _pNode->parent = _pParentNode; CTreeNode::UpdateParentHeight(_pNode); return; } if (_pNode->value < _entry) { //Counter::AddCount(CounterType::AVLInsert); InsertPri(_pNode->rchild, _pNode, _key, _entry); int rHight = CTreeNode::GetHeight(_pNode->rchild); int lHight = CTreeNode::GetHeight(_pNode->lchild); int height = std::max(lHight, rHight) - std::min(lHight, rHight); if (2 == height) { if (_entry >= _pNode->rchild->value)//儘量使用單旋轉== { RightRightRotate(_pNode); } else { DoubleRotateRL(_pNode); } } } else if (_entry < _pNode->value)//如果_entry小於節點的值,就繼續在節點的左子樹中插入_entry { //Counter::AddCount(CounterType::AVLInsert); InsertPri(_pNode->lchild, _pNode, _key, _entry); int rHight = CTreeNode::GetHeight(_pNode->rchild); int lHight = CTreeNode::GetHeight(_pNode->lchild); int height = std::max(lHight, rHight) - std::min(lHight, rHight); if (2 == height) { if (_entry <= _pNode->lchild->value)//儘量使用單旋轉== { LeftLeftRotate(_pNode); } else { DoubleRotateLR(_pNode); } } } }
刪除:
void CAVLTree::DeletePri(CTreeNode* &_pNode, const CEntry& _entry) { if (_pNode == nullptr) { return; } if (_entry < _pNode->value) { DeletePri(_pNode->lchild, _entry); int rHight = CTreeNode::GetHeight(_pNode->rchild); int lHight = CTreeNode::GetHeight(_pNode->lchild); int height = std::max(lHight, rHight) - std::min(lHight, rHight); if (2 == height) { if (_pNode->rchild->lchild != nullptr && _pNode->rchild->lchild->height > _pNode->rchild->rchild->height) { DoubleRotateRL(_pNode); } else { RightRightRotate(_pNode); } } } else if (_entry > _pNode->value) { DeletePri(_pNode->rchild, _entry); int rHight = CTreeNode::GetHeight(_pNode->rchild); int lHight = CTreeNode::GetHeight(_pNode->lchild); int height = std::max(lHight, rHight) - std::min(lHight, rHight); if (2 == height) { if (_pNode->lchild->rchild != nullptr && (_pNode->lchild->rchild->height > _pNode->lchild->lchild->height)) { DoubleRotateLR(_pNode); } else { LeftLeftRotate(_pNode); } } } else { if (_pNode->lchild&&_pNode->rchild)//this node has two childs { CTreeNode* temp = _pNode->rchild; while (temp->lchild != nullptr) { temp = temp->lchild;//find min in rchild } _pNode->value = temp->value; DeletePri(_pNode->rchild, temp->value); int rHight = CTreeNode::GetHeight(_pNode->rchild); int lHight = CTreeNode::GetHeight(_pNode->lchild); int height = std::max(lHight, rHight) - std::min(lHight, rHight); if (2 == height) { if (_pNode->lchild->rchild != nullptr && (_pNode->lchild->rchild->height > _pNode->lchild->lchild->height)) { DoubleRotateLR(_pNode); } else { LeftLeftRotate(_pNode); } } } else//this node has 1 or 0 child { CTreeNode* temp = _pNode; if (_pNode->lchild == nullptr) { _pNode = _pNode->rchild; } else if (_pNode->rchild == nullptr) { _pNode = _pNode->lchild; } delete(temp); temp = nullptr; } } if (_pNode == nullptr) { return; } return; }
輸出: