平衡二叉树(B-Tree) C#

  1. using System;
  2. namespace BTree
  3. {
  4.     class Node//二叉树结点数据类型
  5.     {
  6.         public int data;//数据
  7.         public Node lchild;//左子树
  8.         public Node rchild;//右子树
  9.         public Node(int i, Node l, Node r)
  10.         {
  11.             data = i;
  12.             lchild = l;
  13.             rchild = r;
  14.         }
  15.     }
  16.     class BTree
  17.     {
  18.         public Node ROOT;
  19.         public BTree()
  20.         {
  21.             ROOT = null;
  22.         }
  23.         public void insert(int element)
  24.         {
  25.             Node tmp, parent = null, currentNode = null;
  26.             find(element, ref parent, ref currentNode);
  27.             if (currentNode != null)//如果currentNode不为空值说明currentNode.info==element,是重复元素
  28.             {
  29.                 Console.WriteLine(“Duplicates words not allowed”);
  30.                 return;
  31.             }
  32.             else//如果currentNode为空值时插入新结点
  33.             {
  34.                 tmp = new Node(element, nullnull);//tmp为新节点,lchild和rchild指正均为空
  35.                 if (parent == null)//如果parent结点为空,说明树为空,则tmp作为根结点
  36.                     ROOT = tmp;
  37.                 else
  38.                     if (element < parent.data)//如果parent不为空,则比较parent.data和element的大小
  39.                         parent.lchild = tmp;
  40.                     else
  41.                         parent.rchild = tmp;
  42.             }
  43.         }
  44.         public void find(int element, ref Node parent, ref Node currentNode)//寻找元素
  45.         {
  46.             currentNode = ROOT;
  47.             parent = null;
  48.             while ((currentNode != null) && (currentNode.data != element))
  49.             {//当currentNode指针所指的当前结点不为空时,或者当前结点的info不为element时循环
  50.                 parent = currentNode;//将parent指针指向currentNode指向的当前结点
  51.                 if (element < currentNode.data)
  52.                     currentNode = currentNode.lchild;//element比current.data小时,将currentNode指向左子树
  53.                 else
  54.                     currentNode = currentNode.rchild;
  55.             }
  56.         }
  57.         public void delete(int element)
  58.         {
  59.             Node parent = null, currentNode = null;
  60.             find(element, ref parent, ref currentNode);
  61.             if (currentNode != null)//找到目标结点
  62.             {
  63.                 if (currentNode.lchild == null && currentNode.rchild == null)//如果目标结点的左子树和右子树均为空
  64.                 {
  65.                     if (parent == null)//如果目标结点为根结点
  66.                         ROOT = null;
  67.                     //Release currentNode
  68.                     else
  69.                     {
  70.                         if (parent.lchild == currentNode)
  71.                             parent.lchild = null;
  72.                         else
  73.                             parent.rchild = null;
  74.                         //Release currentNode
  75.                     }
  76.                 }
  77.                 else if ((currentNode.lchild == null && currentNode.rchild != null)
  78.                     || (currentNode.lchild != null && currentNode.rchild == null))//如果目标结点有一棵子树
  79.                 {
  80.                     if (parent == null)
  81.                     {
  82.                         if (currentNode.lchild != null)
  83.                             ROOT = currentNode.lchild;
  84.                         else
  85.                             ROOT = currentNode.rchild;
  86.                         //Release currentNode
  87.                     }
  88.                     else
  89.                     {
  90.                         if (parent.lchild == currentNode)
  91.                             if (currentNode.lchild != null)
  92.                                 parent.lchild = currentNode.lchild;
  93.                             else
  94.                                 parent.lchild = currentNode.rchild;
  95.                         else
  96.                             if (currentNode.lchild != null)
  97.                                 parent.rchild = currentNode.lchild;
  98.                             else
  99.                                 parent.rchild = currentNode.rchild;
  100.                         //Release currentNode
  101.                     }
  102.                 }
  103.                 else if (currentNode.lchild != null && currentNode.rchild != null)//如果目标结点有两颗子树
  104.                 {
  105.                     Node inorder_suc = currentNode.rchild;
  106.                     parent = currentNode;
  107.                     while (inorder_suc.lchild != null)//寻找currentNode右子树的最左子树
  108.                     {
  109.                         parent = inorder_suc;
  110.                         inorder_suc = inorder_suc.lchild;
  111.                     }
  112.                     currentNode.data = inorder_suc.data;
  113.                     if (inorder_suc.lchild == null && inorder_suc.rchild == null)//如果inorder_suc的左子树和右子树均为空
  114.                     {
  115.                         if (parent.lchild == inorder_suc)
  116.                             parent.lchild = null;
  117.                         else
  118.                             parent.rchild = null;
  119.                         //Release currentNode
  120.                     }
  121.                     if (inorder_suc.lchild == null || inorder_suc.rchild == null)//如果inorder_suc有一棵子树
  122.                     {
  123.                         if (parent.lchild == inorder_suc)
  124.                             if (inorder_suc.lchild != null)
  125.                                 parent.lchild = inorder_suc.lchild;
  126.                             else
  127.                                 parent.lchild = inorder_suc.rchild;
  128.                         else
  129.                             if (inorder_suc.lchild != null)
  130.                                 parent.rchild = inorder_suc.lchild;
  131.                             else
  132.                                 parent.rchild = inorder_suc.rchild;
  133.                         //Release currentNode
  134.                     }
  135.                 }
  136.             }
  137.         }
  138.         public void balanceTree(ref Node pivot, ref int BF)
  139.         {
  140.             Node X, Y, parent = null, currentNode = null;
  141.             if (BF < 0)//if tree is initially right heavy
  142.             {
  143.                 X = pivot.rchild;
  144.                 if (getHeight(X.lchild, ref pivot, ref BF) < getHeight(X.rchild, ref pivot, ref BF))
  145.                 {//the new node is inserted in the right subtree of X
  146.                     find(pivot.data, ref parent, ref currentNode);
  147.                     if (pivot != ROOT)
  148.                     {
  149.                         if (parent.lchild == pivot)
  150.                             parent.lchild = X;
  151.                         else
  152.                             parent.rchild = X;
  153.                     }
  154.                     else
  155.                         ROOT = X;
  156.                     pivot.rchild = X.lchild;
  157.                     X.lchild = pivot;
  158.                 }
  159.                 else//the new node is inserted in the left subtree of x
  160.                 {
  161.                     Y = X.lchild;
  162.                     X.lchild = Y.rchild;
  163.                     Y.rchild = X;
  164.                     pivot.rchild = Y;
  165.                     //repeat once the code above when getHeight(X.lchild) < getHeight(X.rchild) 
  166.                     X = pivot.rchild;
  167.                     find(pivot.data, ref parent, ref currentNode);
  168.                     if (pivot != ROOT)
  169.                     {
  170.                         if (parent.lchild == pivot)
  171.                             parent.lchild = X;
  172.                         else
  173.                             parent.rchild = X;
  174.                     }
  175.                     else
  176.                         ROOT = X;
  177.                     pivot.rchild = X.lchild;
  178.                     X.lchild = pivot;
  179.                 }
  180.             }
  181.             else//if the tree is initially left heavy
  182.             {
  183.                  X = pivot.lchild;
  184.                  if (getHeight(X.lchild, ref pivot, ref BF) > getHeight(X.rchild, ref pivot, ref BF))
  185.                  {//the new node is inserted in the left subtree of X
  186.                      find(pivot.data, ref parent, ref currentNode);
  187.                      if (pivot != ROOT)
  188.                      {
  189.                          if (parent.lchild == pivot)
  190.                              parent.lchild = X;
  191.                          else
  192.                              parent.rchild = X;
  193.                      }
  194.                      else
  195.                          ROOT = X;
  196.                      pivot.lchild = X.rchild;
  197.                      X.rchild = pivot;
  198.                  }
  199.                  else//the new node is inserted in the right subtree of x
  200.                  {
  201.                      Y = X.rchild;
  202.                      X.rchild = Y.lchild;
  203.                      Y.lchild = X;
  204.                      pivot.lchild = Y;
  205.                      //repeat once the code above when getHeight(X.lchild) > getHeight(X.rchild) 
  206.                      X = pivot.lchild;
  207.                      find(pivot.data, ref parent, ref currentNode);
  208.                      if (pivot != ROOT)
  209.                      {
  210.                          if (parent.lchild == pivot)
  211.                              parent.lchild = X;
  212.                          else
  213.                              parent.rchild = X;
  214.                      }
  215.                      else
  216.                          ROOT = X;
  217.                      pivot.lchild = X.rchild;
  218.                      X.rchild = pivot;
  219.                  }
  220.             }
  221.         }
  222.         public int getHeight(Node ptr, ref Node pivot, ref int BF)
  223.         {
  224.             int lHeight = 0, rHeight = 0;
  225.             if (ROOT == null && pivot != null)
  226.                 return 0;
  227.             else
  228.             {
  229.                 if (ptr!= null)
  230.                 {
  231.                     lHeight = getHeight(ptr.lchild, ref pivot, ref BF);
  232.                     rHeight = getHeight(ptr.rchild, ref pivot, ref BF);
  233.                     if (Math.Abs(lHeight – rHeight) > 1 && pivot == null)//notice here!! “pivot==null”,otherwise make a mistake
  234.                     {//here get pivot and balance factor
  235.                         pivot = ptr;
  236.                         BF = lHeight – rHeight;
  237.                     }
  238.                     return (lHeight > rHeight ? lHeight + 1 : rHeight + 1);
  239.                 }
  240.                 else
  241.                     return 0;
  242.             }
  243.         }
  244.         public void printTree(Node ptr, int level)//输出二叉树
  245.         {
  246.             if (ptr == null)
  247.                 return;
  248.             else
  249.             {
  250.                 if (ptr.rchild != null)
  251.                     printTree(ptr.rchild, level + 1);
  252.                 for (int i = 0; i < level; i++)
  253.                     Console.Write(”   “);
  254.                 Console.WriteLine(ptr.data);
  255.                 if (ptr.lchild != null)
  256.                     printTree(ptr.lchild, level + 1);
  257.             }
  258.         }
  259.     }
  260.     class Program
  261.     {
  262.         static void Main(string[] args)
  263.         {
  264.             char ch;
  265.             int data, BF;
  266.             Node pivot;
  267.             BTree b = new BTree();
  268.             while (true)
  269.             {
  270.                 Console.Clear();
  271.                 BF = 0;
  272.                 pivot = null;
  273.                 b.getHeight(b.ROOT, ref pivot, ref BF);
  274.                 if (pivot != null)
  275.                     b.balanceTree(ref pivot, ref BF);
  276.                 Console.WriteLine(“print B-Tree:”);
  277.                 b.printTree(b.ROOT, 1);
  278.                 Console.WriteLine(“——MENU——“);
  279.                 Console.WriteLine(“1. inseret data”);
  280.                 Console.WriteLine(“2. delete data”);
  281.                 Console.WriteLine(“3. Exit”);
  282.                 ch = char.Parse(Console.ReadLine());
  283.                 switch (ch)
  284.                 {
  285.                     case ‘1’:
  286.                         {
  287.                             Console.Write(“enter a data:”);
  288.                             data = int.Parse(Console.ReadLine());
  289.                             b.insert(data);
  290.                             break;
  291.                         }
  292.                     case ‘2’:
  293.                         {
  294.                             Console.WriteLine(“enter a data:”);
  295.                             data = int.Parse(Console.ReadLine());
  296.                             b.delete(data);
  297.                             break;
  298.                         }
  299.                     case ‘3’:
  300.                         return;
  301.                     default:
  302.                         {
  303.                             Console.WriteLine(“Invalid option”);
  304.                             break;
  305.                         }
  306.                 }
  307.             }
  308.         }
  309.     }
  310. }
    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/zen_chou/article/details/3016471
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞