线索二叉树(threaded binary search tree) C#

来源:互联网 发布:遥知不是雪为有暗香来 编辑:程序博客网 时间:2024/05/21 18:00
  1. using System;
  2. namespace ThreadedBinaryTree
  3. {
  4.     class Node
  5.     {
  6.         public Node lchild;
  7.         public int lthread;//0 represent a thread,1 represent a link
  8.         public int data;
  9.         public Node rchild;
  10.         public int rthread;
  11.         public Node(int Data,int Lthread,int Rthread,Node Lchild,Node Rchild)
  12.         {
  13.             data = Data;
  14.             lchild = Lchild;
  15.             rchild = Rchild;
  16.             lthread = Lthread;
  17.             rthread = Rthread;
  18.         }
  19.     }
  20.     class ThreadedBST
  21.     {
  22.         private Node head;
  23.         public ThreadedBST()//Constructor
  24.         {
  25.             head = new Node(0, 0, 1, nullnull);
  26.             head.lchild = head;
  27.             head.rchild = head;
  28.         }
  29.         public void find(int element, ref Node parent, ref Node currentNode)
  30.         {
  31.             if (head.lthread != 0)//tree is not empty
  32.             {
  33.                 currentNode = head.lchild;//the top element of the tree
  34.                 parent = head;
  35.                 while (currentNode != null && currentNode.data != element)
  36.                 {
  37.                     parent = currentNode;
  38.                     if (element < currentNode.data && currentNode.lthread == 1)
  39.                         currentNode = currentNode.lchild;
  40.                     else if (element < currentNode.data && currentNode.lthread == 0)//reach the leaf node of left subtree
  41.                         currentNode = null;
  42.                     else if (element > currentNode.data && currentNode.rthread == 1)
  43.                         currentNode = currentNode.rchild;
  44.                     else if (element > currentNode.data && currentNode.rthread == 0)//reach the leaf node of right subtree
  45.                         currentNode = null;
  46.                 }
  47.             }
  48.             else//tree is empty
  49.             {
  50.                 parent = head;
  51.                 Console.WriteLine("Tree is empty");
  52.             }
  53.         }
  54.         public void insert(int element)
  55.         {
  56.             Node newNode, currentNode=null, parent=null;
  57.             find(element,ref parent,ref currentNode);
  58.             if (currentNode != null)
  59.                 return;
  60.             newNode = new Node(element, 0, 0, nullnull);
  61.             if (parent != head)//if tree is not empty
  62.             {
  63.                 if (element < parent.data)
  64.                 {
  65.                     newNode.lchild = parent.lchild;
  66.                     newNode.rchild = parent;
  67.                     parent.lthread = 1;
  68.                     parent.lchild = newNode;
  69.                 }
  70.                 else if (element > parent.data)
  71.                 {
  72.                     newNode.rchild = parent.rchild;
  73.                     newNode.lchild = parent;
  74.                     parent.rthread = 1;
  75.                     parent.rchild = newNode;
  76.                 }
  77.             }
  78.             else//if tree is empty
  79.             {
  80.                 head.lthread = 1;
  81.                 head.lchild = newNode;
  82.                 newNode.lchild = newNode.rchild = head;
  83.             }
  84.         }
  85.         //if the right child of the node is a link, then we can traverse to the leftmost node in the 
  86.         //right subtree of that node to find its inorder successor.However, if the right child of the 
  87.         //node is a thread, then the thread will point to the inorder successor of that node
  88.         public Node Inorder_successor(ref Node currentNode)//search the successor of currentNode
  89.         {
  90.             Node inorder_current=null;
  91.             if (currentNode.rthread == 0)
  92.             {//if the right child of currentNode is a thread,then the node which the thread point to is successor
  93.                 return currentNode.rchild;
  94.             }
  95.             inorder_current = currentNode.rchild;//make currentNode point to the right child of currentNode
  96.             while (inorder_current.lthread != 0)//loop until reach the leaf node of left subtree
  97.                 inorder_current  = inorder_current.lchild;
  98.             return inorder_current;
  99.         }
  100.         public Node Inorder_predecessor(ref Node currentNode)//search the predecessor of currentNode
  101.         {
  102.             Node inorder_current = null;
  103.             if (currentNode.lthread == 0)
  104.                 return currentNode.lchild;
  105.             inorder_current = currentNode.lchild;
  106.             while (inorder_current.rthread != 0)
  107.                 inorder_current = inorder_current.rchild;
  108.             return inorder_current;
  109.         }
  110.         public void Inorder_traversal()
  111.         {
  112.             Node currentNode;
  113.             if (head.lthread == 0)
  114.             {
  115.                 Console.WriteLine("Tree is empty");
  116.                 return;
  117.             }
  118.             currentNode = head.lchild;
  119.             while (currentNode.lthread != 0)//the fist-visit node is the leftmost node of the tree
  120.                 currentNode = currentNode.lchild;
  121.             Console.Write(currentNode.data + "   ");
  122.             while (currentNode.rchild != head)
  123.             {
  124.                 currentNode = Inorder_successor(ref currentNode);
  125.                 Console.Write(currentNode.data + "   ");
  126.             }
  127.         }
  128.         public void delete(int element)
  129.         {
  130.             Node parent=null, currentNode=null, child=null, successor=null, predecessor=null, inorder_parent=null;
  131.             find(element, ref parent, ref currentNode);
  132.             if (currentNode != null)
  133.             {
  134.                 successor = Inorder_successor(ref currentNode);
  135.                 predecessor = Inorder_predecessor(ref currentNode);
  136.                 if (currentNode.lthread == 0 && currentNode.rthread == 0)//node to be deleted is a leaf node
  137.                 {
  138.                     if (parent != head)
  139.                     {
  140.                         if (parent.lchild == currentNode)
  141.                         {
  142.                             parent.lthread = 0;
  143.                             parent.lchild = currentNode.lchild;
  144.                         }
  145.                         else
  146.                         {
  147.                             parent.rthread = 0;
  148.                             parent.rchild = currentNode.rchild;
  149.                         }
  150.                     }
  151.                     else
  152.                     {
  153.                         head.lthread = 0;
  154.                         head.lchild = head;
  155.                     }
  156.                 }
  157.                 else if ((currentNode.lthread == 0 && currentNode.rthread != 0)
  158.                     || (currentNode.lthread != 0 && currentNode.rthread == 0))
  159.                 //node to be deleted has one child
  160.                 {
  161.                     if (currentNode.lthread == 1)//if currentNode has a left child
  162.                     {
  163.                         child = currentNode.lchild;
  164.                         if (parent.lchild == currentNode)//if currentNode is the left child of parent
  165.                             parent.lchild = child;
  166.                         else
  167.                             parent.rchild = child;
  168.                         predecessor.rchild = successor;
  169.                         predecessor.rthread = 0;
  170.                     }
  171.                     else//current has a right child
  172.                     {
  173.                         child = currentNode.rchild;
  174.                         if (parent.lchild == currentNode)
  175.                             parent.lchild = child;
  176.                         else
  177.                             parent.rchild = child;
  178.                         successor.lchild = predecessor;
  179.                         successor.lthread = 0;
  180.                     }
  181.                 }
  182.                 else if (currentNode.lthread == 1 && currentNode.rthread == 1)
  183.                 {//node to be delete has two children
  184.                     find(successor.data, ref parent, ref successor);
  185.                     inorder_parent = parent;//the parent of successor
  186.                     currentNode.data = successor.data;
  187.                     currentNode = successor;//now delete the successor ,make currentNode point to the successor
  188.                     if (currentNode.lthread == 0 && currentNode.rthread == 0)//node to be deleted is a leaf node
  189.                     {
  190.                         if (parent != head)
  191.                         {
  192.                             if (parent.lchild == currentNode)
  193.                             {
  194.                                 parent.lthread = 0;
  195.                                 parent.lchild = currentNode.lchild;
  196.                             }
  197.                             else
  198.                             {
  199.                                 parent.rthread = 0;
  200.                                 parent.rchild = currentNode.rchild;
  201.                             }
  202.                         }
  203.                         else
  204.                         {
  205.                             head.lthread = 0;
  206.                             head.lchild = head;
  207.                         }
  208.                     }
  209.                     if ((currentNode.lthread == 0 && currentNode.rthread != 0)
  210.                         || (currentNode.lthread != 0 && currentNode.rthread == 0))
  211.                     //node to be deleted has one child
  212.                     {
  213.                         if (currentNode.lthread == 1)//if currentNode has a right child
  214.                         {
  215.                             child = currentNode.lchild;
  216.                             if (parent.lchild == currentNode)//if currentNode is the left child of parent
  217.                                 parent.lchild = child;
  218.                             else
  219.                                 parent.rchild = child;
  220.                             successor.lchild = predecessor;
  221.                             successor.lthread = 0;
  222.                         }
  223.                         else//current has a left child
  224.                         {
  225.                             child = currentNode.rchild;
  226.                             if (parent.lchild == currentNode)
  227.                                 parent.lchild = child;
  228.                             else
  229.                                 parent.rchild = child;
  230.                             successor.lchild = predecessor;
  231.                             successor.rthread = 0;
  232.                         }
  233.                     }
  234.                 }
  235.             }
  236.         }
  237.         static void Main(string[] args)
  238.         {
  239.             ThreadedBST b = new ThreadedBST();
  240.             while (true)
  241.             {
  242.                 Console.Clear();
  243.                 Console.Write("Inorder traverse:");
  244.                 b.Inorder_traversal();
  245.                 Console.WriteLine("/nMenu");
  246.                 Console.WriteLine("1. Implement insert operation");
  247.                 Console.WriteLine("2. Implement delete operation");
  248.                 Console.WriteLine("3. Exit");
  249.                 Console.Write("/nEnter your Choice:");
  250.                 char ch = Convert.ToChar(Console.ReadLine());
  251.                 switch (ch)
  252.                 {
  253.                     case '1':
  254.                         {
  255.                             Console.Write("Enter a number: ");
  256.                             int num =Convert.ToInt32( Console.ReadLine());
  257.                             b.insert(num);
  258.                         }
  259.                         break;
  260.                     case '2':
  261.                         {
  262.                             Console.Write("Enter a number: ");
  263.                             int num =Convert.ToInt32( Console.ReadLine());
  264.                             b.delete(num);
  265.                         }
  266.                         break;
  267.                     case '3':
  268.                         return;
  269.                     default:
  270.                         Console.WriteLine("Invalid option");
  271.                         break;
  272.                 }
  273.             }
  274.         }
  275.     }
  276. }

原创粉丝点击