二叉树 C#

来源:互联网 发布:卖宠物的软件 编辑:程序博客网 时间:2024/06/06 01:11
  1. using System;
  2. using System.Text;
  3. namespace BinarySearchTree
  4. {
  5.     class Node//二叉树结点数据类型
  6.     {
  7.         public string info;//数据
  8.         public Node lchild;//左子树
  9.         public Node rchild;//右子树
  10.         public Node(string i, Node l, Node r)
  11.         {
  12.             info = i;
  13.             lchild = l;
  14.             rchild = r;
  15.         }
  16.     }
  17.     class BinaryTree//二叉树基础操作操作类
  18.     {
  19.         public Node ROOT;//根结点
  20.         int height;//数的高度
  21.         public BinaryTree()
  22.         {
  23.             ROOT = null;
  24.         }
  25.         public void insert(string element)//插入元素
  26.         {
  27.             Node tmp, parent = null, currentNode = null;
  28.             find(element, ref parent, ref currentNode);
  29.             if (currentNode != null)//如果currentNode不为空值说明currentNode.info==element,是重复元素
  30.             {
  31.                 Console.WriteLine("Duplicates words not allowed");
  32.                 return;
  33.             }
  34.             else//如果currentNode为空值时插入新结点
  35.             {
  36.                 tmp = new Node(element, nullnull);//tmp为新节点,lchild和rchild指正均为空
  37.                 if (parent == null)//如果parent结点为空,说明树为空,则tmp作为根结点
  38.                     ROOT = tmp;
  39.                 else
  40.                     if (string.Compare(element, parent.info) < 0)//如果parent不为空,则比较parent.info和element的大小
  41.                         parent.lchild = tmp;
  42.                     else
  43.                         parent.rchild = tmp;
  44.             }
  45.         }
  46.         public void find(string element, ref Node parent, ref Node currentNode)//寻找元素
  47.         {
  48.             currentNode = ROOT;
  49.             parent = null;
  50.             while ((currentNode != null) && (currentNode.info != element))
  51.             {//当currentNode指针所指的当前结点不为空时,或者当前结点的info不为element时循环
  52.                 parent = currentNode;//将parent指针指向currentNode指向的当前结点
  53.                 if (string.Compare(element, currentNode.info) < 0)
  54.                     currentNode = currentNode.lchild;//element比current.info小时,将currentNode指向左子树
  55.                 else
  56.                     currentNode = currentNode.rchild;
  57.             }
  58.         }
  59.         public void delete(string element)//删除元素
  60.         {
  61.             Node parent = null, currentNode = null;
  62.             find(element,ref parent,ref currentNode);
  63.             if (currentNode != null)//找到目标结点
  64.             {
  65.                 if (currentNode.lchild == null && currentNode.rchild == null)//如果目标结点的左子树和右子树均为空
  66.                 {
  67.                     if (parent == null)//如果目标结点为根结点
  68.                         ROOT = null;
  69.                     //Release currentNode
  70.                     else
  71.                     {
  72.                         if (parent.lchild == currentNode)
  73.                             parent.lchild = null;
  74.                         else
  75.                             parent.rchild = null;
  76.                         //Release currentNode
  77.                     }
  78.                 }
  79.                 else if ((currentNode.lchild == null && currentNode.rchild != null)
  80.                     || (currentNode.lchild != null && currentNode.rchild == null))//如果目标结点有一棵子树
  81.                 {
  82.                     if (parent == null)
  83.                     {
  84.                         if (currentNode.lchild!=null)
  85.                             ROOT = currentNode.lchild;
  86.                         else
  87.                             ROOT = currentNode.rchild;
  88.                         //Release currentNode
  89.                     }
  90.                     else
  91.                     {
  92.                         if (parent.lchild == currentNode)
  93.                             if (currentNode.lchild != null)
  94.                                 parent.lchild = currentNode.lchild;
  95.                             else
  96.                                 parent.lchild = currentNode.rchild;
  97.                         else
  98.                             if (currentNode.lchild != null)
  99.                                 parent.rchild = currentNode.lchild;
  100.                             else
  101.                                 parent.rchild = currentNode.rchild;
  102.                         //Release currentNode
  103.                     }
  104.                 }
  105.                 else if (currentNode.lchild != null && currentNode.rchild != null)//如果目标结点有两颗子树
  106.                 {
  107.                     Node inorder_suc = currentNode.rchild;
  108.                     parent = currentNode;
  109.                     while (inorder_suc.lchild != null)//寻找currentNode右子树的最左子树
  110.                     {
  111.                         parent = inorder_suc;
  112.                         inorder_suc = inorder_suc.lchild;
  113.                     }
  114.                     currentNode.info = inorder_suc.info;
  115.                     if (inorder_suc.lchild == null && inorder_suc.rchild == null)//如果inorder_suc的左子树和右子树均为空
  116.                     {
  117.                         if (parent.lchild == inorder_suc)
  118.                             parent.lchild = null;
  119.                         else
  120.                             parent.rchild = null;
  121.                         //Release currentNode
  122.                     }
  123.                     if (inorder_suc.lchild == null || inorder_suc.rchild == null)//如果inorder_suc有一棵子树
  124.                     {
  125.                         if (parent.lchild == inorder_suc)
  126.                             if (inorder_suc.lchild != null)
  127.                                 parent.lchild = inorder_suc.lchild;
  128.                             else
  129.                                 parent.lchild = inorder_suc.rchild;
  130.                         else
  131.                             if (inorder_suc.lchild != null)
  132.                                 parent.rchild = inorder_suc.lchild;
  133.                             else
  134.                                 parent.rchild = inorder_suc.rchild;
  135.                         //Release currentNode
  136.                     }
  137.                 }
  138.             }
  139.         }
  140.         //public void inorder(Node ptr)//中序遍历二叉树
  141.         //{
  142.         //    if (ROOT == null)
  143.         //    {
  144.         //        Console.WriteLine("Tree is empty");
  145.         //        return;
  146.         //    }
  147.         //    if (ptr != null)
  148.         //    {
  149.         //        inorder(ptr.lchild);
  150.         //        Console.Write(ptr.info + "    ");
  151.         //        inorder(ptr.rchild);
  152.         //    }
  153.         //}
  154.         //public void preorder(Node ptr)//先序遍历二叉树
  155.         //{
  156.         //    if (ROOT == null)
  157.         //    {
  158.         //        Console.WriteLine("Tree is empty");
  159.         //        return;
  160.         //    }
  161.         //    if (ptr != null)
  162.         //    {
  163.         //        Console.Write(ptr.info + "    ");
  164.         //        preorder(ptr.lchild);
  165.         //        preorder(ptr.rchild);
  166.         //    }
  167.         //}
  168.         //public void postorder(Node ptr)//后序遍历二叉树
  169.         //{
  170.         //    if (ROOT == null)
  171.         //    {
  172.         //        Console.WriteLine("Tree is empty");
  173.         //        return;
  174.         //    }
  175.         //    if (ptr != null)
  176.         //    {
  177.         //        postorder(ptr.lchild);
  178.         //        postorder(ptr.rchild);
  179.         //        Console.Write(ptr.info + "    ");
  180.         //    }
  181.         //}
  182.         public int getheight(Node ptr)//求树的高度
  183.         {
  184.             int lHeight = 0, rHeight = 0;
  185.             if (ROOT == null)
  186.                 return 0;
  187.             else
  188.             {
  189.                 if (ptr != null)
  190.                 {
  191.                     lHeight = getheight(ptr.lchild);
  192.                     rHeight = getheight(ptr.rchild);
  193.                     return (lHeight > rHeight ? lHeight + 1 : rHeight + 1);
  194.                 }
  195.                 else
  196.                     return 0;
  197.             }
  198.         }
  199.         public void printtree(Node ptr,int level)//输出二叉树
  200.         {
  201.             if (ptr == null)
  202.                 return;
  203.             else
  204.             {
  205.                 if (ptr.rchild != null)
  206.                     printtree(ptr.rchild, level + 1);
  207.                 for (int i = 0; i < level; i++)
  208.                     Console.Write("   ");
  209.                 Console.WriteLine(ptr.info);
  210.                 if (ptr.lchild != null)
  211.                     printtree(ptr.lchild, level + 1);
  212.             }
  213.         }
  214.         static void Main(string[] args)
  215.         {
  216.             BinaryTree b = new BinaryTree();
  217.             while (true)
  218.             {
  219.                 Console.Clear(); 
  220.                 b.height = b.getheight(b.ROOT);
  221.                 Console.WriteLine("the height of tree:{0}", b.height);
  222.                 Console.WriteLine("Print binary tree:");
  223.                 b.printtree(b.ROOT, 1);
  224.                 Console.WriteLine("/nMenu");
  225.                 Console.WriteLine("1. Implement insert operation");
  226.                 Console.WriteLine("2. Implement delete operation");
  227.                 Console.WriteLine("3. Exit");
  228.                 Console.Write("/nEnter your Choice:");
  229.                 char ch = Convert.ToChar(Console.ReadLine());
  230.                 switch (ch)
  231.                 {
  232.                     case '1':
  233.                         {
  234.                             Console.Write("Enter a word: ");
  235.                             string word = Console.ReadLine();
  236.                             b.insert(word);
  237.                         }
  238.                         break;
  239.                     case '2':
  240.                         {
  241.                             Console.Write("Enter a word: ");
  242.                             string word = Console.ReadLine();
  243.                             b.delete(word);
  244.                         }
  245.                         break;
  246.                     case '3':
  247.                         return;
  248.                     default:
  249.                         Console.WriteLine("Invalid option");
  250.                         break;
  251.                 }
  252.             }
  253.         }
  254.     }
  255. }