二叉树
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
- 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
- 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
- 它的左右子树也分别为二叉搜索树
template<class T>
struct BSTNode
{
BSTNode(const T& data = T())
: _pLeft(nullptr)
, _pRight(nullptr)
, _data(data)
{}
BSTNode<T>* _pLeft;
BSTNode<T>* _pRight;
T _data;
};
template<class T>
class BSTree
{
typedef BSTNode<T> Node;
typedef Node* PNode;
public:
BSTree()
: _pRoot(nullptr)
{}
~BSTree()
{
_Destroy(_pRoot);
}
PNode Find(const T& data)
{
PNode pCur = _pRoot;
while (pCur)
{
if (data == pCur->_data)
return pCur;
else if (data < pCur->_pLeft)
pCur = pCur->_pLeft;
else
pCur = pCur->_pRight;
}
return nullptr;
}
bool Insert(const T& data)
{
// 如果树为空,直接插入
if (nullptr == _pRoot)
{
_pRoot = new Node(data);
return true;
}
// 按照二叉搜索树的性质查找data在树中的插入位置
PNode pCur = _pRoot;
// 记录pCur的双亲,因为新元素终插入在pCur双亲左右孩子的位置
PNode pParent = nullptr;
while (pCur)
{
pParent = pCur;
if (data < pCur->_data)
pCur = pCur->_pLeft;
else if (data > pCur->_data)
pCur = pCur->_pRight;
// 元素已经在树中存在
else
return false;
}
// 插入元素
pCur = new Node(data);
if (data < pParent->_data)
pParent->_pLeft = pCur;
else
pParent->_pRight = pCur;
return true;
}
bool Erase(const T& data)
{
// 如果树为空,删除失败
if (nullptr == _pRoot)
return false;
// 查找在data在树中的位置
PNode pCur = nullptr;
PNode pParent = nullptr;
while (pCur)
{
if (data == pCur->_data)
break;
else if (data < pCur->_data)
{
pParent = pCur;
pCur = pCur->_pLeft;
}
else
{
pParent = pCur;
pCur = pCur->_pRight;
}
}
if(pCur == nullptr)
return false;
if(pCur->pRight == nullptr)
{
if(pCur == pParent->pLeft)
pParent->pLeft = pCur->pLeft;
else
pParent->pRight = pCur->pLeft;
}
if(pCur->pLeft == nullptr)
{
if(pCur == pParent->pLeft)
pParent->pLeft = pCur->pRight;
else
pParent->pRight = pCur->pRight;
}
else
{
pNode pTmp = pNode->Right;
while(pTmp->pLeft)
pTmp = pTmp->pLeft;
T tmp = pTmp->_data;
pTmp->_data = pCur->_data;
pCur->_data = tmp;
pCur = pTmp;
}
pCur = nullptr;
return true;
}
void InOrder()
{
_InOrder(_pRoot);
}
private:
void _InOrder(PNode pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << pRoot->_data << " ";
_InOrder(pRoot->_pRight);
}
}
void _Destroy(PNode& pRoot)
{
if (pRoot)
{
_Destroy(pRoot->_pLeft);
_Destroy(pRoot->_pRight);
pRoot = nullptr;
}
}
private:
PNode _pRoot;
};
AVL树
具有以下特点的二叉搜索树就是AVL数
- 它的左右子树都是AVL树
- 左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)
即可降低树的高度,从而减少平均搜索长度
二叉树的简单实现:
#include<iostream>
using namespace std;
template<class K, class V>
struct AVLTreeNode //节点结构
{
AVLTreeNode<K, V>* _left;
AVLTreeNode<K, V>* _right;
AVLTreeNode<K, V>* _parent; //父节点
K _key;
V _value;
int _bf; // 平衡因子:右子树与左子树的高度差
AVLTreeNode(const K& key, const V& value)
:_left(NULL)
, _right(NULL)
, _parent(NULL)
, _key(key)
, _value(value)
, _bf(0)
{}
};
template<class K, class V>
class AVLTree
{
typedef AVLTreeNode<K, V> Node;
public:
//构造函数
AVLTree()
:_root(NULL)
{}
//插入
bool Insert(const K& key, const V& value)
{
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}
//先把节点插入对应的位置
//调整树的结构,使树平衡
//更新平衡因子
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new Node(key, value);
if (key < parent->_key)
{
parent->_left = cur;
cur->_parent = parent;
}
else
{
parent->_right = cur;
cur->_parent = parent;
}
// 如果平衡因子在-1~1 之间,继续向上更新
while (parent)
{
if (cur == parent->_left)
parent->_bf--;
else
parent->_bf++;
if (parent->_bf == 0)
{
break;
}
else if (parent->_bf == -1 || parent->_bf == 1)
{
cur = parent;
parent = parent->_parent;
}
// -2 或 +2 的情况 不满足平衡条件 进行旋转
else
{
if (parent->_bf == 2)
{
if (cur->_bf == 1) // 左单旋
{
_RotateL(parent);
}
else // -1 右左双旋
{
_RotateRL(parent);
}
}
// parent == -2
else
{
if (cur->_bf == -1) // 右单旋
{
_RotateR(parent);
}
else // cur = 1 左右双旋
{
_RotateLR(parent);
}
}
break;
}
}
return true;
}
//查找
Node* Find(const K& key)
{
return _Find(_root, key);
}
//树的高度
int Height()
{
return _Height(_root);
}
// 检查是否是 平衡二叉树
bool IsBalance()
{
return _IsBalance(_root);
}
//输出
void PrintAVLTree()
{
_PrintAVLTree(_root);
cout << endl;
}
protected:
Node* _Find(Node* root, const K& key)
{
if (root == NULL)
{
return NULL;
}
if (key < root->_key)
{
return _Find(root->_left, key);
}
else if (key > root->_key)
{
return _Find(root->_right, key);
}
else
{
return root;
}
}
void _RotateL(Node* parent) // 左单旋转
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
Node* pp = parent->_parent;
subR->_parent = pp;
subR->_left = parent;
parent->_parent = subR;
if (pp) // 不是根节点
{
if (pp->_left == parent)
{
pp->_left = subR;
}
else
{
pp->_right = subR;
}
}
else
{
_root = subR;
}
// 更新平衡因子
parent->_bf = subR->_bf = 0;
}
void _RotateR(Node* parent) // 右单旋转
{
Node* SubL = parent->_left;
Node* SubLR = SubL->_right;
Node* pp = parent->_parent;
parent->_left = SubLR;
if (SubLR)
{
SubLR->_parent = parent;
}
SubL->_right = parent;
parent->_parent = SubL;
SubL->_parent = pp;
if (pp) // 判断是否为根节点
{
if (parent == pp->_left)
{
pp->_left = SubL;
}
else
{
pp->_right = SubL;
}
}
else
{
_root = SubL;
}
// 更新平衡因子
parent->_bf = SubL->_bf = 0;
}
void _RotateLR(Node* parent) // 左右旋转
{
// 记录结点指针 后面修正 平衡因子
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
_RotateL(parent->_left);
_RotateR(parent);
// 根据subLR的平衡因子修正其他结点的平衡因子
if (bf == -1)
{
//subL->_bf = 0;
parent->_bf = 1;
}
else if (bf == 1)
{
subL->_bf = -1;
//parent->_bf = 0;
}
}
void _RotateRL(Node* parent) // 右左旋转
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
int bf = subRL->_bf;
_RotateR(parent->_right);
_RotateL(parent);
// 修正平衡因子
if (bf == 1)
{
parent->_bf = -1;
}
else if (bf == -1)
{
subR->_bf = 1;
}
}
int _Height(Node* root)
{
if (root == NULL)
{
return 0;
}
int leftHeight = _Height(root->_left);
int rightHeight = _Height(root->_right);
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
bool _IsBalance(Node* root)
{
if (root == NULL)
{
return true;
}
int left = _Height(root->_left);
int right = _Height(root->_right);
if (right - left != root->_bf || abs(right - left) > 1)
{
cout << "结点的平衡因子有问题:" << root->_key << endl;
return false;
}
return _IsBalance(root->_left) && _IsBalance(root->_right);
}
void _PrintAVLTree(Node* root)
{
if (root == NULL)
{
return;
}
_PrintAVLTree(root->_left);
cout << root->_key << " ";
_PrintAVLTree(root->_right);
}
protected:
Node* _root;
};
红黑树
红黑树的性质:
- 每个结点不是红色就是黑色
- 根节点是黑色的
- 如果一个节点是红色的,则它的两个孩子结点是黑色的 (没有连续的红节点)
- 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点
- 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
红黑树的插入:
- 新插节点一定是红色的,破坏连续红节点
如果是空数,插入黑节点做根节点
如果不是空数。插入红节点,如果父亲是黑色,则满足条件 - 如果父亲也是红色,则违反规则,
- 情况一:cur为红,parent是红,uncle存在且为红:parent,uncle变为黑,祖父变为红,cur变为祖父,再看uncle。如果祖父是根节点,就把祖父变黑
- 情况二:cur为红,parent是红,uncle不存在或者uncle为黑(这种情况是情况一变来的)单旋:parent变黑,祖父变红,单旋转(祖父旋下来,parent做根)
- 情况三:cur为红,parent是红,uncle不存在或者uncle为黑(这种情况是情况一变来的)双旋:左单旋完了右单旋,或者右单旋完了左单旋;进行完了第一次旋转就变成了情况二
旋转完就结束了
enum Color
{
RED,
BLACK,
};
template<class Value>
struct RBTreeNode
{
RBTreeNode<Value>* _left;
RBTreeNode<Value>* _right;
RBTreeNode<Value>* _parent;
Value _value;
Color _color;
RBTreeNode(const Value& value)
: _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _value(value)
{}
};
template<class Value>
struct RBTreeIterator
{
typedef RBTreeNode<Value> Node;
//typedef RBTreeIterator<Value> Self;
Node* _node;
RBTreeIterator(Node* node)
:_node(node)
{}
Value& operator*()
{
return _node->_value;
}
Value* operator->()
{
return &_node->_value;
}
RBTreeIterator<Value> operator++()
{
if (_node->_right != nullptr)
{
_node = _node->_right;
while (_node->_left != nullptr)
{
_node = _node->_left;
}
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_right)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
bool operator!= (const RBTreeIterator<Value>& s)
{
return _node != s._node;
}
};
template<class K, class Value, class KeyOfValue>
class RBTree
{
typedef RBTreeNode<Value> Node;
public:
typedef RBTreeIterator<Value> iterator;
RBTree()
:_root(nullptr)
{}
~RBTree()
{}
iterator begin()
{
Node* cur = _root;
while (cur && cur->_left != nullptr)
{
cur = cur->_left;
}
return iterator(cur);
}
iterator end()
{
return iterator(nullptr);
}
pair<iterator, bool> Insert(const Value& v)
{
// 1.按搜索树的规则进行插入
if (_root == nullptr)
{
_root = new Node(v);
_root->_color = BLACK;
return make_pair(iterator(_root), true);
}
Node* parent = nullptr;
Node* cur = _root;
KeyOfValue kov;
while (cur)
{
if (kov(cur->_value) < kov(v))
{
parent = cur;
cur = cur->_right;
}
else if (kov(cur->_value) > kov(v))
{
parent = cur;
cur = cur->_left;
}
else
{
//return false;
return make_pair(iterator(cur), false);
}
}
cur = new Node(v);
Node* newnode = cur;
cur->_color = RED;
if (kov(parent->_value) < kov(cur->_value))
{
parent->_right = cur;
cur->_parent = parent;
}
else
{
parent->_left = cur;
cur->_parent = parent;
}
while (parent && parent->_color == RED)
{
Node* grandfather = parent->_parent;
if (parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
// 1.u存在且为红->变色->继续向上
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
grandfather->_color = RED;
cur = grandfather;
parent = cur->_parent;
}
else // u存在且为黑 or 不存在
{
// 双旋->单旋
if (cur == parent->_right)
{
RotateL(parent);
swap(parent, cur);
}
parent->_color = BLACK;
grandfather->_color = RED;
RotateR(grandfather);
break;
}
}
else // parent == grandfather->_right
{
Node* uncle = grandfather->_left;
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
grandfather->_color = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_left)
{
RotateR(parent);
swap(parent, cur);
}
grandfather->_color = RED;
parent->_color = BLACK;
RotateL(grandfather);
break;
}
}
}
_root->_color = BLACK;
//return true;
return make_pair(iterator(newnode), true);
}
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
subL->_right = parent;
Node* ppNode = parent->_parent;
parent->_parent = subL;
if (parent == _root)
{
_root = subL;
}
else
{
if (parent == ppNode->_left)
ppNode->_left = subL;
else
ppNode->_right = subL;
}
subL->_parent = ppNode;
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
subR->_left = parent;
Node* ppNode = parent->_parent;
parent->_parent = subR;
if (parent == _root)
{
_root = subR;
_root->_parent = nullptr;
}
else
{
if (parent == ppNode->_left)
ppNode->_left = subR;
else
ppNode->_right = subR;
subR->_parent = ppNode;
}
}
private:
Node* _root;
};