数据结构与算法[1]-平衡二叉树-C#版

来源:互联网 发布:做淘宝创业家破人亡 编辑:程序博客网 时间:2024/04/30 01:23

平衡二叉树 
  形态匀称的二叉树称为平衡二叉树 (Balanced binary tree) ,其严格定义是:
  一棵空树是平衡二叉树;若 T 是一棵非空二叉树,其左、右子树为 TL 和 TR ,令 hl 和 hr 分别为左、右子树的深度。当且仅当
   ①TL 、 TR 都是平衡二叉树; 
   ② | hl - hr |≤ 1;
时,则 T 是平衡二叉树。
【例】如图 8.4 所示。
         
             (a)平衡二叉树           (b)非平衡二叉树
                      图8.3 平衡二叉树与非平衡二叉树
相应地定义 hl - hr 为二叉平衡树的平衡因子 (balance factor) 。因此,平衡二叉树上所有结点的平衡因子可能是 -1 , 0 , 1 。换言之,若一棵二叉树上任一结点的平衡因子的绝对值都不大于 1 ,则该树是就平衡二叉树。
动态平衡技术 
1.动态平衡技术
Adelson-Velskii 和 Landis 提出了一个动态地保持二叉排序树平衡的方法,其基本思想是:
  在构造二叉排序树的过程中,每当插入一个结点时,首先检查是否因插入而破坏了树的平衡性,如果是因插入结点而破坏了树的平衡性,则找出其中最小不平衡子树,在保持排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,以达到新的平衡。通常将这样得到的平衡二叉排序树简称为 AVL 树
2.最小不平衡子树
  以离插入结点最近、且平衡因子绝对值大于 1 的结点作根结点的子树。为了简化讨论,不妨假设二叉排序树的最小不平衡子树的根结点为 A ,则调整该子树的规律可归纳为下列四种情况:
(1) LL 型:
  新结点 X 插在 A 的左孩子的左子树里。调整方法见图 8.5(a) 。图中以 B 为轴心,将 A 结点从 B 的右上方转到 B 的右下侧,使 A 成为 B 的右孩子。
      
          图8.5 平衡调整的4种基本类型(结点旁的数字是平衡因子)
(2)RR 型:
  新结点 X 插在 A 的右孩子的右子树里。调整方法见图 8.5(b) 。图中以 B 为轴心,将 A 结点从 B 的左上方转到 B 的左下侧,使 A 成为 B 的左孩子。
(3)LR 型:
  新结点 X 插在 A 的左孩子的右子树里。调整方法见图 8.5(c) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的左上方转到 X 的左下侧,使 B 成为 X 的左孩子, X 成为 A 的左孩子。第二步跟 LL 型一样处理 ( 应以 X 为轴心 ) 。 
(4)RL 型:
  新结点 X 插在 A 的右孩子的左子树里。调整方法见图 8.5(d) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的右上方转到 X 的右下侧,使 B 成为 X 的右孩子, X 成为 A 的右孩子。第二步跟 RR 型一样处理 ( 应以 X 为轴心 ) 。

 

 

 

 

实现代码:

  1. /// <summary>
  2.     /// balance binary node
  3.     /// </summary>
  4.     class AVLBinaryNode
  5.     {
  6.         //field
  7.         private AVLBinaryNode lChild;
  8.         private AVLBinaryNode rChild;
  9.         private AVLBinaryNode parent;
  10.         private int data;
  11.         //property
  12.         /// <summary>
  13.         /// get or set left child of node
  14.         /// </summary>
  15.         public AVLBinaryNode LChild
  16.         {
  17.             get
  18.             {
  19.                 return lChild;
  20.             }
  21.             set 
  22.             { 
  23.                 lChild = value; 
  24.             }
  25.         }
  26.         /// <summary>
  27.         /// get or set right child of node
  28.         /// </summary>
  29.         public AVLBinaryNode RChild
  30.         {
  31.             get 
  32.             { 
  33.                 return rChild; 
  34.             }
  35.             set
  36.             {
  37.                 rChild = value;
  38.             }
  39.         }
  40.         /// <summary>
  41.         /// get or set parent of node
  42.         /// </summary>
  43.         public AVLBinaryNode Parent
  44.         {
  45.             get 
  46.             { 
  47.                 return parent; 
  48.             }
  49.             set 
  50.             { 
  51.                 parent = value;
  52.             }
  53.         }
  54.         /// <summary>
  55.         /// get or set date of node
  56.         /// </summary>
  57.         public int Data
  58.         {
  59.             get 
  60.             {
  61.                 return data;
  62.             }
  63.             set 
  64.             { 
  65.                 data = value; 
  66.             }
  67.         }
  68.         /// <summary>
  69.         /// create new AVLBinaryNode instance
  70.         /// </summary>
  71.         public AVLBinaryNode(AVLBinaryNode lChild,AVLBinaryNode rChild,AVLBinaryNode parent,int data)
  72.         {
  73.             this.lChild = lChild;
  74.             this.rChild = rChild;
  75.             this.parent = parent;
  76.             this.data = data;
  77.         }
  78.     }
  79. //-------------------------------------------------------------
  80.     /// <summary>
  81.     /// balance binary of tree
  82.     /// </summary>
  83.     class AVLBinaryTree
  84.     {
  85.         private AVLBinaryNode rootHead;
  86.         /// <summary>
  87.         /// create balance of binary
  88.         /// </summary>
  89.         /// <param name="dates">ordered datas</param>
  90.         public AVLBinaryTree(int[] datas)
  91.         {
  92.             //load first node
  93.             rootHead = new AVLBinaryNode(nullnullnull, datas[0]);
  94.             for (int i = 1; i < datas.Length; i++)
  95.             {
  96.                 InsertNode(datas[i]);
  97.             }
  98.         }
  99.         /// <summary>
  100.         /// insert new node
  101.         /// </summary>
  102.         /// <param name="newNode">new node</param>
  103.         public void InsertNode(int data)
  104.         {
  105.             AVLBinaryNode pTemp = this.rootHead;
  106.             AVLBinaryNode previousNode = null;
  107.             bool isLeft = true;
  108.             while (pTemp != null)
  109.             {
  110.                 if (pTemp.Data > data)
  111.                 {
  112.                     if (pTemp.LChild == null)
  113.                     {
  114.                         previousNode = pTemp;
  115.                         isLeft = true;
  116.                     }
  117.                     pTemp = pTemp.LChild;
  118.                     
  119.                 }
  120.                 else if (pTemp.Data < data)
  121.                 {
  122.                     if (pTemp.LChild == null)
  123.                     {
  124.                         previousNode = pTemp;
  125.                         isLeft = false;
  126.                     }
  127.                     pTemp = pTemp.RChild;
  128.                 }
  129.                 else
  130.                 {
  131.                     return;
  132.                 }
  133.             }
  134.             if (isLeft)
  135.             {
  136.                 previousNode.LChild = new AVLBinaryNode(nullnull, previousNode, data);
  137.             }
  138.             else
  139.             {
  140.                 previousNode.LChild = new AVLBinaryNode(nullnull, previousNode, data);
  141.             }
  142.             int leftDepth = GetDepthOfTree(rootHead.LChild);
  143.             int rightDepth = GetDepthOfTree(rootHead.RChild);
  144.             if ((leftDepth - rightDepth)  > 1 || (leftDepth - rightDepth) < -1)//judge for whether convert
  145.             {
  146.                 //judge convert type
  147.                 int iType = GetConvertType(previousNode.Parent);
  148.                 switch (iType)
  149.                 {
  150.                     case 1:
  151.                         this.LLConvert(previousNode.Parent);
  152.                         break;
  153.                     case 2:
  154.                         this.RRConvert(previousNode.Parent);
  155.                         break;
  156.                     case 3:
  157.                         this.LRConvert(previousNode.Parent);
  158.                         break;
  159.                     case 4:
  160.                         this.RLConvert(previousNode.Parent);
  161.                         break;
  162.                     default:
  163.                         break;
  164.                 }
  165.             }
  166.            
  167.         }
  168.         /// <summary>
  169.         /// will "LL" convert validate VAL tree
  170.         /// </summary>
  171.         /// <param name="rootnNode">root node of sub unbalance/param>
  172.         public void LLConvert(AVLBinaryNode rootNode)
  173.         {
  174.             AVLBinaryNode nTemp = rootNode.Parent;
  175.             rootNode.Parent = rootNode.LChild;
  176.             rootNode.LChild.RChild = rootNode;
  177.             if (nTemp.LChild == rootNode)
  178.             {
  179.                 nTemp.LChild = rootNode.LChild;
  180.             }
  181.             else
  182.             {
  183.                 nTemp.RChild = rootNode.LChild;
  184.             }
  185.             rootNode.LChild.Parent = nTemp;
  186.             rootNode.LChild = null;
  187.             
  188.         }
  189.         /// <summary>
  190.         /// will "RR" convert validate VAL tree
  191.         /// </summary>
  192.         /// <param name="rootnNode">root node of sub unbalance</param>
  193.         public void RRConvert(AVLBinaryNode rootNode)
  194.         {
  195.             AVLBinaryNode nTemp = rootNode.Parent;
  196.             rootNode.Parent = rootNode.RChild;
  197.             rootNode.RChild.LChild = rootNode;
  198.             if (nTemp.LChild == rootNode)
  199.             {
  200.                 nTemp.LChild = rootNode.RChild;
  201.             }
  202.             else
  203.             {
  204.                 nTemp.RChild = rootNode.RChild;
  205.             }
  206.             rootNode.RChild.Parent = nTemp;
  207.             rootNode.RChild = null;
  208.         }
  209.         /// <summary>
  210.         /// will "LR" convert validate VAL tree
  211.         /// </summary>
  212.         /// <param name="rootnNode">root node of sub unbalance</param>
  213.         public void LRConvert(AVLBinaryNode rootNode)
  214.         {
  215.             AVLBinaryNode nTemp = rootNode.Parent;
  216.             rootNode.Parent = rootNode.LChild.RChild;//设置1结点的父结点
  217.             rootNode.LChild.Parent = rootNode.LChild.RChild;//设定2结点的父结点
  218.             rootNode.LChild.RChild.LChild = rootNode.LChild;//设置3结点的左孩子
  219.             rootNode.LChild.RChild.RChild = rootNode;//设置3结点的右孩子
  220.             rootNode.LChild.RChild.RChild.Parent = nTemp;//设置第3个结点的父结点
  221.             
  222.             if (nTemp.LChild == rootNode)//设置3结点在父结点的左孩子还是右孩子 
  223.             {
  224.                 nTemp.LChild = rootNode.LChild.RChild.RChild;
  225.             }
  226.             else
  227.             {
  228.                 nTemp.RChild = rootNode.LChild.RChild.RChild;
  229.             }
  230.             rootNode.LChild.RChild = null;
  231.             rootNode.LChild = null;
  232.             
  233.         }
  234.         /// <summary>
  235.         /// will "RL" convert validate VAL tree
  236.         /// </summary>
  237.         /// <param name="rootnNode">root node of sub unbalance</param>
  238.         public void RLConvert(AVLBinaryNode rootNode)
  239.         {
  240.             AVLBinaryNode nTemp = rootNode.Parent;
  241.             rootNode.Parent = rootNode.RChild.LChild;//设置1结点的父结点
  242.             rootNode.RChild.Parent = rootNode.RChild.LChild;//设定2结点的父结点
  243.             rootNode.RChild.LChild.RChild = rootNode.RChild;//设置3结点的左孩子
  244.             rootNode.RChild.LChild.LChild = rootNode;//设置3结点的右孩子
  245.             rootNode.RChild.LChild.LChild.Parent = nTemp;//设置第3个结点的父结点
  246.             if (nTemp.LChild == rootNode)//设置3结点在父结点的左孩子还是右孩子 
  247.             {
  248.                 nTemp.LChild = rootNode.RChild.LChild.LChild;
  249.             }
  250.             else
  251.             {
  252.                 nTemp.RChild = rootNode.RChild.LChild.LChild;
  253.             }
  254.             rootNode.RChild.LChild = null;
  255.             rootNode.RChild = null;
  256.         }
  257.         /// <summary>
  258.         /// check convert Type (1 is LL,2 is RR,3 is LR,4 is RL,0 is other)
  259.         /// </summary>
  260.         /// <param name="rootNode"></param>
  261.         /// <returns></returns>
  262.         private int GetConvertType(AVLBinaryNode rootNode)
  263.         {
  264.             int iType = 0; 
  265.             if (rootNode != null)
  266.             {
  267.                 if (rootNode.LChild != null && rootNode.RChild == null)
  268.                 {
  269.                     if (rootNode.LChild.LChild != null && rootNode.LChild.RChild == null)
  270.                     {
  271.                         iType = 1;
  272.                     }
  273.                     else if (rootNode.LChild.LChild == null && rootNode.LChild.RChild != null)
  274.                     {
  275.                         iType = 3;
  276.                     }
  277.                 }
  278.                 else if (rootNode.RChild != null && rootNode.LChild == null)
  279.                 {
  280.                     if (rootNode.RChild.RChild != null && rootNode.RChild.LChild == null)
  281.                     {
  282.                         iType = 2;
  283.                     }
  284.                     else if (rootNode.RChild.LChild != null && rootNode.RChild.RChild == null)
  285.                     {
  286.                         iType = 4;
  287.                     }
  288.                 }
  289.             }
  290.             return iType;
  291.         }
  292.         /// <summary>
  293.         /// get pointer tree depth
  294.         /// </summary>
  295.         /// <param name="rootNode">pointer tree root node</param>
  296.         /// <returns></returns>
  297.         public int GetDepthOfTree(AVLBinaryNode rootNode)
  298.         {
  299.             int depthCount = 0;
  300.             AVLBinaryNode nodeTemp = null;
  301.             System.Collections.Stack stack = new System.Collections.Stack();
  302.             if (rootHead != null)
  303.             {
  304.                 stack.Push(nodeTemp);
  305.                 while (stack.Count != 0)
  306.                 {
  307.                     //gain max depth count
  308.                     depthCount = depthCount < stack.Count ? stack.Count : depthCount;
  309.                     if (nodeTemp.LChild != null)
  310.                     {
  311.                         stack.Push(nodeTemp.LChild);
  312.                     }
  313.                     nodeTemp = (AVLBinaryNode)stack.Pop();
  314.                     if (nodeTemp.RChild != null)
  315.                     {
  316.                         stack.Push(nodeTemp.RChild);
  317.                     }
  318.                 }
  319.                 depthCount += 1;
  320.             }
  321.             return depthCount;
  322.         }
  323.     }
原创粉丝点击