红黑树C#算法。

在线javascript演示地址:http://sandbox.runjs.cn/show/2nngvn8w

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Collections; namespace ConsoleApplication2
{
public class Program
{
public static void Main()
{
int[] a = {,,,,,,,,}; RBTree<int> rbTree = new RBTree<int>();
foreach (var item in a)
{
rbTree.Insert(item);
}
rbTree.Remove(); rbTree.PreOrder(t => Console.Write(t.ToString()+" ")); Console.Read();
}
} #region 实体
public enum NodeColor
{
Black,
Red
} public class RBTreeNode<T> where T : IComparable
{
public T Key { get; set; }
public NodeColor Color { get; set; }
public RBTreeNode<T> Parent { get; set; }
public RBTreeNode<T> LeftNode { get; set; }
public RBTreeNode<T> RightNode { get; set; } public RBTreeNode(T key, NodeColor color, RBTreeNode<T> parent, RBTreeNode<T> leftNode, RBTreeNode<T> rightNode)
{
this.Key = key;
this.Color = color;
this.Parent = parent;
this.LeftNode = leftNode;
this.RightNode = rightNode;
} public override string ToString()
{
return this.Key + "(" + Color.ToString() + ")";
}
}
#endregion public class RBTree<T> where T : IComparable
{
public RBTreeNode<T> RootNode { get; set; }//根节点 #region 插入
public void Insert(T key)
{
if (this.RootNode == null)
{
this.RootNode = new RBTreeNode<T>(key, NodeColor.Black, null, null, null);
}
else
{
var newNode = Inserts(key);
InsertFixUp(newNode);
}
} private RBTreeNode<T> Inserts(T key)
{
var node = RootNode; var newNode = new RBTreeNode<T>(key, NodeColor.Red, null, null, null);
while (true)
{
if (key.CompareTo(node.Key) > )
{
if (node.RightNode == null)
{
newNode.Parent = node;
node.RightNode = newNode;
break;
}
node = node.RightNode;
}
else if (key.CompareTo(node.Key) < )
{
if (node.LeftNode == null)
{
newNode.Parent = node;
node.LeftNode = newNode;
break;
}
node = node.LeftNode;
}
else
{
break;
}
}
return newNode;
} private void InsertFixUp(RBTreeNode<T> node)
{
var parentNode = node.Parent;
if (parentNode != null && NodeColor.Red == parentNode.Color)
{
var gparentNode = parentNode.Parent;
if (parentNode == gparentNode.LeftNode)
{
var uncleNode = gparentNode.RightNode;
if (uncleNode != null && NodeColor.Red == uncleNode.Color)//case1
{
parentNode.Color = NodeColor.Black;
uncleNode.Color = NodeColor.Black;
gparentNode.Color = NodeColor.Red;
InsertFixUp(gparentNode);
}
else
{
if (parentNode.RightNode == node)//case2
{
LeftRotation(parentNode);
InsertFixUp(parentNode);
}
else if (parentNode.LeftNode == node)//case3
{
parentNode.Color = NodeColor.Black;
gparentNode.Color = NodeColor.Red;
RightRotion(gparentNode);
}
}
}
else
{
var uncleNode = gparentNode.LeftNode;
if (uncleNode != null && NodeColor.Red == uncleNode.Color)//case1
{
parentNode.Color = NodeColor.Black;
uncleNode.Color = NodeColor.Black;
gparentNode.Color = NodeColor.Red;
InsertFixUp(gparentNode);
}
else
{
if (parentNode.LeftNode == node)//case2
{
RightRotion(parentNode);
InsertFixUp(parentNode);
}
else if (parentNode.RightNode == node)//case3
{
parentNode.Color = NodeColor.Black;
gparentNode.Color = NodeColor.Red;
LeftRotation(gparentNode);
}
}
}
}
RootNode.Color = NodeColor.Black; //直接将根节点设置为黑色
}
#endregion #region 旋转
private void LeftRotation(RBTreeNode<T> node)
{
RBTreeNode<T> temp = node.RightNode; node.RightNode = temp.LeftNode;
if (temp.LeftNode != null)
{
temp.LeftNode.Parent = node;
} temp.Parent = node.Parent; if (node.Parent == null)
{
RootNode = temp;
}
else
{
if (node.Parent.LeftNode == node)
{
node.Parent.LeftNode = temp;
}
else
{
node.Parent.RightNode = temp;
}
}
temp.LeftNode = node;
node.Parent = temp;
} private void RightRotion(RBTreeNode<T> node)
{
RBTreeNode<T> temp = node.LeftNode; node.LeftNode = temp.RightNode;
if (temp.RightNode != null)
{
temp.RightNode.Parent = node;
} temp.Parent = node.Parent; if (node.Parent == null)
{
RootNode = temp;
}
else
{
if (node == node.Parent.RightNode)
{
node.Parent.RightNode = temp;
}
else
{
node.Parent.LeftNode = temp;
}
}
temp.RightNode = node;
node.Parent = temp;
}
#endregion #region 删除
public void Remove(T key)
{
RBTreeNode<T> node = Search(key);
if (node == null)
{
return;
}
else
{
Remove(node);
}
} private void Remove(RBTreeNode<T> itWasDeletedNode)
{
RBTreeNode<T> child;
RBTreeNode<T> parent;
NodeColor nodeColor; if (itWasDeletedNode.LeftNode != null && itWasDeletedNode.RightNode != null)
{
var tempNode = this.FindMin(itWasDeletedNode.RightNode);
if (itWasDeletedNode.Parent == null)
{
this.RootNode = tempNode;
}
else
{
if (itWasDeletedNode.Parent.LeftNode.Key.CompareTo(itWasDeletedNode.Key) == )
{
itWasDeletedNode.Parent.LeftNode = tempNode;
}
else
{
itWasDeletedNode.Parent.RightNode = tempNode;
}
} child = tempNode.RightNode;
parent = tempNode.Parent;
nodeColor = tempNode.Color; if (parent.Key.CompareTo(itWasDeletedNode.Key) == )
{
parent = tempNode;
}
else
{
if (child != null)
{
child.Parent = parent;
}
parent.LeftNode = child; tempNode.RightNode = itWasDeletedNode.RightNode;
itWasDeletedNode.RightNode.Parent = tempNode;
} tempNode.Parent = itWasDeletedNode.Parent;
tempNode.Color = itWasDeletedNode.Color;
tempNode.LeftNode = itWasDeletedNode.LeftNode;
itWasDeletedNode.LeftNode.Parent = tempNode; if (nodeColor == NodeColor.Black)
{
RemoveFixUp(child, parent);
} itWasDeletedNode = null;
return;
} if (itWasDeletedNode.LeftNode != null)
{
child = itWasDeletedNode.LeftNode;
}
else
{
child = itWasDeletedNode.RightNode;
} parent = itWasDeletedNode.Parent;
nodeColor = itWasDeletedNode.Color; if (child != null)
{
child.Parent = parent;
} if (parent != null)
{
if (parent.LeftNode != null && parent.LeftNode.Key.CompareTo(itWasDeletedNode.Key) == )
{
parent.LeftNode = child;
}
else
{
parent.RightNode = child;
}
}
else
{
this.RootNode = child;
} if (nodeColor == NodeColor.Black)
{
RemoveFixUp(child, parent);
}
itWasDeletedNode = null;
} private void RemoveFixUp(RBTreeNode<T> node, RBTreeNode<T> parentNode)
{
RBTreeNode<T> otherNode; while ((node == null || node.Color == NodeColor.Black) && (node != this.RootNode))
{
if (parentNode.LeftNode == node)
{
otherNode = parentNode.RightNode;
if (otherNode.Color == NodeColor.Red)
{
otherNode.Color = NodeColor.Black;
parentNode.Color = NodeColor.Red;
LeftRotation(parentNode);
otherNode = parentNode.RightNode;
} if ((otherNode.LeftNode == null || otherNode.LeftNode.Color == NodeColor.Black) &&
(otherNode.RightNode == null || otherNode.RightNode.Color == NodeColor.Black))
{
otherNode.Color = NodeColor.Red;
node = parentNode;
parentNode = node.Parent;
}
else
{
if (otherNode.RightNode == null || otherNode.RightNode.Color == NodeColor.Black)
{
otherNode.LeftNode.Color = NodeColor.Black;
otherNode.Color = NodeColor.Red;
RightRotion(otherNode);
otherNode = parentNode.RightNode;
} otherNode.Color = parentNode.Color;
parentNode.Color = NodeColor.Black;
otherNode.RightNode.Color = NodeColor.Black;
LeftRotation(parentNode);
node = this.RootNode;
break;
}
}
else
{
otherNode = parentNode.LeftNode;
if (otherNode.Color == NodeColor.Red)
{
otherNode.Color = NodeColor.Black;
parentNode.Color = NodeColor.Red;
RightRotion(parentNode);
otherNode = parentNode.LeftNode;
} if ((otherNode.LeftNode == null || otherNode.LeftNode.Color == NodeColor.Black) &&
(otherNode.RightNode == null || otherNode.RightNode.Color == NodeColor.Black))
{
otherNode.Color = NodeColor.Red;
node = parentNode;
parentNode = node.Parent;
}
else
{
if (otherNode.LeftNode == null || otherNode.LeftNode.Color == NodeColor.Black)
{
otherNode.RightNode.Color = NodeColor.Black;
otherNode.Color = NodeColor.Red;
LeftRotation(otherNode);
otherNode = parentNode.LeftNode;
} otherNode.Color = parentNode.Color;
parentNode.Color = NodeColor.Black;
otherNode.LeftNode.Color = NodeColor.Black;
RightRotion(parentNode);
node = this.RootNode;
break;
}
}
} if (node != null)
{
node.Color = NodeColor.Black;
}
}
#endregion #region 查找
public RBTreeNode<T> Search(T key)
{
return Search(RootNode, key);
} private RBTreeNode<T> Search(RBTreeNode<T> node, T key)
{
if (node == null)
{
return null;
} if (node.Key.CompareTo(key) > )
{
return Search(node.LeftNode, key);
}
else if (node.Key.CompareTo(key) < )
{
return Search(node.RightNode, key);
}
else
{
return node;
}
} public RBTreeNode<T> FindMin()
{
return FindMin(RootNode);
} private RBTreeNode<T> FindMin(RBTreeNode<T> node)
{
if (node.LeftNode == null)
{
return node;
}
return FindMin(node.LeftNode);
} public RBTreeNode<T> FindMax()
{
return FindMax(RootNode);
} private RBTreeNode<T> FindMax(RBTreeNode<T> node)
{
if (node.RightNode == null)
{
return node.RightNode;
} return FindMax(node.RightNode);
} public List<RBTreeNode<T>> SearchRange(T minKey, T maxKey)
{
return SearchRange(minKey,maxKey,this.RootNode,new List<RBTreeNode<T>>());
} private List<RBTreeNode<T>> SearchRange(T minKey, T maxKey, RBTreeNode<T> node,List<RBTreeNode<T>> nodeList)
{
if (node == null)
{
return nodeList;
} if (node.Key.CompareTo(minKey) > )
{
SearchRange(minKey,maxKey,node.LeftNode,nodeList);
} if (node.Key.CompareTo(minKey) >= && node.Key.CompareTo(maxKey) <= )
{
nodeList.Add(node);
} if (node.Key.CompareTo(maxKey) < )
{
SearchRange(minKey,maxKey,node.RightNode,nodeList);
} return nodeList;
}
#endregion #region 遍历
public void LevelOrder(Action<RBTreeNode<T>> action)
{
LevelOrder(RootNode, action);
} private void LevelOrder(RBTreeNode<T> note, Action<RBTreeNode<T>> action)
{
Queue<RBTreeNode<T>> queue = new Queue<RBTreeNode<T>>();
queue.Enqueue(note); while (queue.Count > )
{
var temp = queue.Dequeue(); action(temp); if (temp.LeftNode != null)
{
queue.Enqueue(temp.LeftNode);
} if (temp.RightNode != null)
{
queue.Enqueue(temp.RightNode);
}
}
} public void PreOrder(Action<RBTreeNode<T>> action)
{
TreeOrder(RootNode, preOrderAction: action);
} public void InOrder(Action<RBTreeNode<T>> action)
{
TreeOrder(RootNode, inOrderAction: action);
} public void PostOrderAction(Action<RBTreeNode<T>> action)
{
TreeOrder(RootNode, postOrderAction: action);
} private void TreeOrder(RBTreeNode<T> node, Action<RBTreeNode<T>> preOrderAction = null, Action<RBTreeNode<T>> inOrderAction = null, Action<RBTreeNode<T>> postOrderAction = null)
{
if (preOrderAction != null)
{
preOrderAction(node);
} if (node.LeftNode != null)
{
TreeOrder(node.LeftNode, preOrderAction, inOrderAction, postOrderAction);
} if (inOrderAction != null)
{
inOrderAction(node);
} if (node.RightNode != null)
{
TreeOrder(node.RightNode, preOrderAction, inOrderAction, postOrderAction);
} if (postOrderAction != null)
{
postOrderAction(node);
}
}
#endregion }
}

算法参考:http://www.cnblogs.com/skywang12345/p/3603935.html

红黑树(C#)的更多相关文章

  1. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  2. jdk源码分析红黑树——插入篇

    红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...

  3. 谈c++ pb_ds库(二) 红黑树大法好

    厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...

  4. 定时器管理:nginx的红黑树和libevent的堆

    libevent 发生超时后, while循环一次从堆顶del timer——直到最新调整的最小堆顶不是超时事件为止,(实际是del event),但是会稍后把这个timeout的 event放到ac ...

  5. 从2-3-4树到红黑树(下) Java与C的实现

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处   http://www.cnblogs.com/nullzx/ 相关博客: 从2-3-4树到红黑树(上) 从2-3-4树到红黑树(中) 1. 实现技 ...

  6. 红黑树/B+树/AVL树

    RB Tree 红黑树  :http://blog.csdn.net/very_2/article/details/5722682 Nginx的RBTree实现   :http://blog.csdn ...

  7. 论AVL树与红黑树

    首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...

  8. DataStructure——红黑树学习笔记

    1.前言 本文伪码和解释参考: http://blog.csdn.net/v_JULY_v/article/details/6105630 C实现的源码本文未贴出,请见: http://blog.cs ...

  9. 红黑树(Red-Black tree)

    红黑树又称红-黑二叉树,它首先是一颗二叉树,它具体二叉树所有的特性.同时红黑树更是一颗自平衡的排序二叉树.我们知道一颗基本的二叉树他们都需要满足一个基本性质–即树中的任何节点的值大于它的左子节点,且小 ...

  10. map,hash_map, hash_table, 红黑树 的原理和使用

    在刷算法题的时候总是碰到好多题,号称可以用hash table来解题.然后就蒙圈了. 1.首先,map和hash_map的区别和使用: (1)map底层用红黑树实现,hash_map底层用hash_t ...

随机推荐

  1. Vim常用命令【转载】

    下面基本是vim的基本用法,刚开始学习可能有些不习惯.但贵在坚持,即使不习惯,也要坚持使用,做到不经过思考就能操作,你会发现真的很方便.很多操作可以通过不同的命令达到,我这里只列出常用的. 基础命令 ...

  2. 纯CSS做的一个Silder

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  3. mongodb 慢SQL查询

    在 MySQL中,慢查询日志是经常作为我们优化数据库的依据,那在MongoDB中是否有类似的功能呢?答案是肯定的,那就是Mongo Database Profiler.不仅有,而且还有一些比MySQL ...

  4. MVC动态生成表单

    1*书写方式 一.using语句可以不写结束标记,自动加上 服务端 客户端 默认提交当前控制器和操作方法 二.开始与结束代码都写 服务端 客户端 三.一些常用的重载方法 (1)要提交的控制器,和操作方 ...

  5. C#中partial关键字

    1. 什么是局部类型? C# 2.0 引入了局部类型的概念.局部类型允许我们将一个类.结构或接口分成几个部分,分别实现在几个不同的.cs文件中. 局部类型适用于以下情况: (1) 类型特别大,不宜放在 ...

  6. Debian下VIM的安装和配置

    1.安装 apt-get install vim 2.配置 这是我的vim 配饰文件,基本的功能都能实现,在这里做一个备份,省的以后重装系统还要到处找这个配置文件(/etc/vim/vimrc) : ...

  7. jquery 功能强大的下拉菜单

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org ...

  8. 在windows系统用odbc连接

    当连接的数据出现失败时,出现数据库别名仍然存在,但还是要用这个别名重新建立连接 在windows客户端,用输入db2cmd输入c:\Users\yexuxia>db2 list db direc ...

  9. C++builder编译别人工程报错

    编译时遇到错误,信息如下: [C++ Error] NVRAMEditor.h(83): E2209 Unable to open include file 'CONTROLSLib_OCX.h'[C ...

  10. java synchronized内置锁的可重入性和分析总结

    最近在读<<Java并发编程实践>>,在第二章中线程安全中降到线程锁的重进入(Reentrancy) 当一个线程请求其它的线程已经占有的锁时,请求线程将被阻塞.然而内部锁是可重 ...