码迷,mamicode.com
首页 > 其他好文 > 详细

红黑树

时间:2016-07-20 19:49:49      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:红黑树

红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。

  • 红黑树是满足下面红黑性质的二叉搜索树

  1. 每个节点,不是红色就是黑色的

  2. 根节点是黑色的

  3. 如果一个节点是红色的,则它的两个子节点是黑色的(没有连续的红节点)

  4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。(每条路径的黑色节点的数量相等

  5. 每个叶子节点都是黑色的(这里的叶子节点是指的NIL节点(空节点))

  • 插入的几种情况

ps:cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点

1.第一种情况

cur为红,p为红,g为黑,u存在且为红

则将p,u改为黑,g改为红,然后把g当成cur,继续向上调整。

技术分享

2.第二种情况

cur为红,p为红,g为黑,u不存在/u为黑

p为g的左孩子,cur为p的左孩子,则进行右单旋转;相反,p为g的右孩子,cur为p的右孩子,则进行左单旋转

p、g变色--p变黑,g变红

技术分享

3.第三种情况

cur为红,p为红,g为黑,u不存在/u为黑

p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转

则转换成了情况2

技术分享

#pragma once

#include<iostream>

using namespace std;


enum Colour

{

RED,

BLACK,

};

template<class K,class V>

struct RBTreeNode

{

RBTreeNode<K, V>* _left;

RBTreeNode<K, V>* _right;

RBTreeNode<K, V>* _parent;

K _key;

V _value;

Colour _col;

RBTreeNode(const K& key, const V& value)

:_key(key)

, _value(value)

, _left(NULL)

, _right(NULL)

, _parent(NULL)

, _col(RED)

{}

};

template<class K, class V>

class RBTree

{

typedef RBTreeNode<K, V> Node;

public:

RBTree()

:_root(NULL)

{}

bool Insert(const K& key, const V& value)

{

if (_root == NULL)

{

_root = new Node(key, value);

_root->_col = BLACK;

return true;

}

Node* parent = NULL;

Node* cur = _root;

while (cur)

{

if (cur->_key > key)

{

parent = cur;

cur = cur->_left;

}

else if (cur->_key < key)

{

parent = cur;

cur = cur->_right;

}

else

{

return false;

}

}

cur = new Node(key, value);

if (parent->_key < key)

{

parent->_right = cur;

cur->_parent = parent;

}

else

{

parent->_left = cur;

cur->_parent = parent;

}

while (cur != _root && parent->_col == RED)//grandfather肯定不为空,根节点的颜色为黑色

{

Node* grandfather = parent->_parent;

if (grandfather->_left == parent)//parent为的grandfather左孩子

{

Node* uncle = grandfather->_right;

if (uncle && uncle->_col == RED)//uncle存在并且为红色的

{

parent->_col = uncle->_col = BLACK;

grandfather->_col = RED;

cur = grandfather;

parent = cur->_parent;

}

else

{

if (cur = parent->_right)//cur为parent的右孩子,先把它左单旋为左孩子

{

RotateL(parent);

swap(parent, cur);

}

parent->_col = BLACK;

grandfather->_col = RED;

RotateR(grandfather);

break;

}

}

else

{

Node* uncle = grandfather->_left;

if (uncle && uncle->_col == RED)

{

parent->_col = uncle->_col = BLACK;

grandfather->_col = RED;

cur = grandfather;

parent = cur->_parent;

}

else

{

if (parent->_left == cur)

{

RotateR(parent);

swap(parent, cur);

}

parent->_col = BLACK;

grandfather->_col = RED;

RotateL(grandfather);

break;

}

}

}

_root->_col = BLACK;

}

void Inorder()

{

_Inorder(_root);

cout << endl;

}

bool IsBalance()

{

if (_root == NULL)

{

return true;

}

if (_root->_col == RED)//根节点必须是黑色的

{

return false;

}

Node* cur = _root;

int k = 0;

while (cur)

{

if (cur->_col == BLACK)

{

k++;

}

cur = cur->_left;

}

int count = 0;

return _IsBalance(_root, k, count);

}

Node* Find(const K& key)

{

if (_root == NULL)

{

return NULL;

}

Node* cur = _root;

while (cur)

{

if (cur->_key > key)

{

cur = cur->_left;

}

else if (cur->_key < key)

{

cur = cur->_right;

}

else

{

return cur;

}

}

return NULL;

}

protected:

bool _IsBalance(Node* root, const int k, int count)

{

if (root == NULL)

{

return true;

}

if (root->_col == RED && root->_parent->_col == RED)

{

cout << "出现连续的红色节点" << root->_key << endl;

return false;

}

if (root->_col == BLACK)

{

++count;

}

if (root->_left == NULL && root->_right == NULL && count != k)

{

cout << "黑色节点个数不相等" << root->_key << endl;

return false;

}

return _IsBalance(root->_left, k, count) && _IsBalance(root->_right, k, count);

}

void _Inorder(Node* root)

{

if (root == NULL)

{

return;

}

_Inorder(root->_left);

cout << root->_key << " ";

_Inorder(root->_right);

}

void RotateL(Node* parent)

{

Node* subR = parent->_right;

Node* subRL = subR->_left;

parent->_right = subRL;

if (subRL)

{

subRL->_parent = parent;

}

Node* ppNode = parent->_parent;

subR->_left = parent;

parent->_parent = subR;

if (ppNode == NULL)

{

_root = subR;

}

else

{

if (ppNode->_left == parent)

{

ppNode->_left = subR;

}

else

{

ppNode->_right = subR;

}

}

subR->_parent = ppNode;

}

void RotateR(Node* parent)

{

Node* subL = parent->_left;

Node* subLR = subL->_right;

parent->_left = subLR;

if (subLR)

{

subLR->_parent = parent;

}

Node* ppNode = parent->_parent;

subL->_right = parent;

parent->_parent = subL;

if (ppNode == NULL)

{

_root = subL;

}

else

{

if (ppNode->_left == parent)

{

ppNode->_left = subL;

}

else

{

ppNode->_right = subL;

}

}

subL->_parent = ppNode;

}

protected:

Node* _root;

};


红黑树

标签:红黑树

原文地址:http://10548202.blog.51cto.com/10538202/1828109

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!