构建一颗红黑树

作者:追风剑情 发布于:2017-7-22 13:14 分类:Algorithms

红黑树是一种自平衡搜索树。通过对节点进行着色和旋转,红黑树很容易保持树的平衡。

我们需要在二叉搜索树上增加一个额外的颜色信息,树中的节点可以涂成红色或黑色。如果一棵二叉搜索树满足下面的全部5条性质,则称为红黑树:

(1) 任一节点要么是红色,要么是黑色;
(2) 根节点为黑色;
(3) 所有叶节点(NIL节点)为黑色;
(4) 如果一个节点为红色,则它的两个子节点都是黑色;
(5) 对任一节点,从它出发到所有叶子节点的路径上包含相同数量的黑色节点。

为什么这5条性质能保证红黑树的平衡呢?因为它们有一个关键的特性:从根节点出发到达叶节点的所有路径中,最长路径不会超过最短路径的两倍。

注意第(4)条性质,它意味着不存在两个连续的红色节点。因此,最短的路径只含有黑色节点,任何比最短路径长的路径上都分散有一些红色节点。根据性质(5),从根节点出发的所有路径都含有相同数量的黑色节点,这就最终保证了没有任何路径超过最短路径长度的两倍。

红黑树沿用所有二叉搜索树中不改变树结构的操作,包括查找、获取最大值、最小值等;只有插入和删除操作是特殊的。

示例: C#

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace RedBlackTree1
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. int[] keys = new int[] { 13, 8, 1, 11, 6, 17, 15, 25, 22, 27};
  14. Console.Write("测试数据为: ");
  15. for (int i = 0; i < keys.Length; i++)
  16. {
  17. Console.Write(keys[i] + " ");
  18. }
  19. Console.WriteLine();
  20.  
  21. //根节点
  22. Node root = null;
  23. //录入10个节点
  24. for (int i = 0; i < keys.Length; i++)
  25. {
  26. Node node = new Node();
  27. node.key = keys[i];
  28. if (null == root)
  29. root = node;
  30. else
  31. Insert(root, node);
  32. }
  33. Console.Write("构建的二叉搜索树为: ");
  34. Print(root);
  35.  
  36. Console.WriteLine();
  37. Console.WriteLine("给二叉搜索树染色: ");
  38. Coloring(root, Color.Black);//根节点为黑色
  39. Print(root, true);
  40.  
  41. Console.ReadKey();
  42. }
  43.  
  44. static void Insert(Node root, Node child)
  45. {
  46. if(root.key >= child.key)
  47. {
  48. if (null == root.left)
  49. root.left = child;
  50. else
  51. Insert(root.left, child);
  52. }
  53. else
  54. {
  55. if (null == root.right)
  56. root.right = child;
  57. else
  58. Insert(root.right, child);
  59. }
  60. }
  61.  
  62. static void Coloring(Node root, Color color)
  63. {
  64. if (null == root)
  65. return;
  66. root.color = color;
  67. color = (color == Color.Black) ? Color.Red : Color.Black;
  68. Coloring(root.left, color);
  69. Coloring(root.right, color);
  70. }
  71.  
  72. static void Print(Node root, bool outputColor = false)
  73. {
  74. if (null != root.left)
  75. Print(root.left, outputColor);
  76.  
  77. if (outputColor)
  78. Console.Write("{0}({1}) ", root.key, root.color);
  79. else
  80. Console.Write("{0} ", root.key);
  81.  
  82. if (null != root.right)
  83. Print(root.right, outputColor);
  84. }
  85. }
  86.  
  87. public enum Color
  88. {
  89. Black,
  90. Red
  91. }
  92.  
  93. public class Node
  94. {
  95. public Color color;
  96. public int key;
  97. public Node parent;
  98. public Node left;
  99. public Node right;
  100. }
  101.  
  102.  
  103. }

运行测试

1111.png

染色后对应的树状图为 (通常插图都省略了NIL节点)

rdtree.png

标签: Algorithms

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号