概念:
二叉树是最多只有左右两个节点的树;
二叉搜索树是在二叉树的基础上,加入了限制:根节点的值大于左子树上的所有值;根节点的值小于右字树上的所有值;左右节点拆分的两个二叉树同时也是二叉搜索树。
平衡树:平衡树是在二叉搜索树的基础上,加入了限制:每个节点的高度差不超过1.
红黑树:平衡树是在二叉搜索树的基础上,加入了限制:每个节点有红或黑颜色;root必须是黑色的;所有叶子节点都是黑色的,是空节点;红色节点必须有两个黑色的子节点,或者说红色是不能连续的;从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
二叉搜索树:
相关的代码如下:
template<typename T>
class BST
{
public:
struct Node;
BST() :_root(nullptr) {}
void nonremove(const T &val)
{
Node * cur = _root;
Node * par = nullptr;
while (cur)
{
if (cur->_data > val)
{
par = cur;
cur = cur->_left;
}
else if (cur->_data < val)
{
par = cur;
cur = cur->_right;
}
else
{
break;
}
}
if (cur == nullptr)
{
return;
}
if (cur->_left != nullptr&&cur->_right != nullptr)
{
par = cur;
Node* p = cur->_left;
while (p->_right)
{
par = p;
p = p->_right;
}
cur->_data = p->_data;
cur = p;
}
Node *child = cur->_left;
if (child == nullptr)
{
child = cur->_right;
}
if (par == nullptr) // 删除的是根节点
{
_root = child;
}
else
{
if (cur == par->_left)
{
par->_left = child; // 修改父节点的左孩子
}
else
{
par->_right = child; // 修改父节点的右孩子
}
}
delete cur; // 删除节点
}
void remove(const T &val)
{
remove(_root, val);
}
Node* remove(Node* node, const T &val)
{
if (node == nullptr)
{
return node;
}
if (node->_data > val)
{
node->_left = remove(node->_left, val);
}
else if (node->_data < val)
{
node->_right = remove(node->_right, val);
}
else
{
if (node->_left != nullptr&&node->_right != nullptr)
{
Node* pre = node->_left;
while (pre->_right != nullptr)
{
pre = pre->_right;
}
node->_data = pre->_data;
node->_left = remove(node->_left, pre->_data);
}
else
{
if (node->_left != nullptr)
{
Node* p = node->_left;
delete node;
return p;
}
if (node->_right != nullptr)
{
Node* p = node->_right;
delete node;
return p;
}
delete node;
return nullptr;
}
}
return node;
}
void noninsert(const T &val)
{
if (_root == nullptr)
{
_root = new Node(val);
return;
}
Node * tmp = _root;
while (tmp)
{
if (tmp->_data == val)
{
return;
}
else if (tmp->_data > val)
{
if (tmp->_left)
{
tmp = tmp->_left;
}
else
{
Node * tmp1 = new Node(val);
tmp->_left = tmp1;
return;
}
}
else if (tmp->_data < val)
{
if (tmp->_right)
{
tmp = tmp->_right;
}
else
{
Node * tmp1 = new Node(val);
tmp->_right = tmp1;
return;
}
}
}
}
void insert(const T &val)
{
this->_root=insert(_root, val);
}
Node* insert(Node* node, const T &val)
{
if (node == nullptr)
{
return new Node(val);
}
if (node->_data > val)
{
node->_left = insert(node->_left, val);
}
else if (node->_data < val)
{
node->_right = insert(node->_right, val);
}
return node;
}
void levelOrder()
{
int n = level();
cout << "层次遍历" << endl;
for (int i = 0; i < n; i++)
{
levelOrder(_root, i);
}
cout << endl;
}
void levelOrder(Node* p, int level)
{
if (p == nullptr)
{
return;
}
if (level == 0)
{
cout << p->_data << " ";
return;
}
levelOrder(p->_left, level - 1);
levelOrder(p->_right, level - 1);
}
void nonlevelOrder()
{
cout << "非递归层次遍历" << endl;
nonlevelOrder(_root);
cout << endl;
}
void nonlevelOrder(Node *_root)
{
list<Node> list;
if (_root)
{
list.push_back(*_root);
}
while (!list.empty())
{
Node p = list.front();
list.pop_front();
cout << p._data << " ";
if (p._left)
{
list.push_back(*(p._left));
}
if (p._right)
{
list.push_back(*(p._right));
}
}
}
void preOrder()
{
cout << "前序遍历" << endl;
preOrder(_root);
cout << endl;
}
void preOrder(Node * p)
{
if (p)
{
cout << p->_data << " ";
preOrder(p->_left);
preOrder(p->_right);
}
}
void nonpreOrder()
{
cout << "非递归前序遍历" << endl;
nonpreOrder(_root);
cout << endl;
}
void nonpreOrder(Node * p)
{
list<Node> node;
if (p)
{
node.push_front(*p);
}
while (!node.empty())
{
Node tmp = node.front();
node.pop_front();
cout << tmp._data<<" ";
if (tmp._right)
{
node.push_front(*tmp._right);
}
if (tmp._left)
{
node.push_front(*tmp._left);
}
}
return;
}
void inOrder()
{
cout << "中序遍历" << endl;
inOrder(_root);
cout << endl;
}
void inOrder(Node * p)
{
if (p)
{
inOrder(p->_left);
cout << p->_data<<" ";
inOrder(p->_right);
}
}
void noninOrder()
{
cout << "非递归中序遍历" << endl;
noninOrder(_root);
cout << endl;
}
void noninOrder(Node * p)
{
/*
if (nullptr == _root)
return;
stack<Node*> s;
Node *pcur = _root;
while (!s.empty() || pcur != nullptr)
{
if (pcur != nullptr) // L