- using System;
- namespace ThreadedBinaryTree
- {
- class Node
- {
- public Node lchild;
- public int lthread;//0 represent a thread,1 represent a link
- public int data;
- public Node rchild;
- public int rthread;
- public Node(int Data,int Lthread,int Rthread,Node Lchild,Node Rchild)
- {
- data = Data;
- lchild = Lchild;
- rchild = Rchild;
- lthread = Lthread;
- rthread = Rthread;
- }
- }
- class ThreadedBST
- {
- private Node head;
- public ThreadedBST()//Constructor
- {
- head = new Node(0, 0, 1, null, null);
- head.lchild = head;
- head.rchild = head;
- }
- public void find(int element, ref Node parent, ref Node currentNode)
- {
- if (head.lthread != 0)//tree is not empty
- {
- currentNode = head.lchild;//the top element of the tree
- parent = head;
- while (currentNode != null && currentNode.data != element)
- {
- parent = currentNode;
- if (element < currentNode.data && currentNode.lthread == 1)
- currentNode = currentNode.lchild;
- else if (element < currentNode.data && currentNode.lthread == 0)//reach the leaf node of left subtree
- currentNode = null;
- else if (element > currentNode.data && currentNode.rthread == 1)
- currentNode = currentNode.rchild;
- else if (element > currentNode.data && currentNode.rthread == 0)//reach the leaf node of right subtree
- currentNode = null;
- }
- }
- else//tree is empty
- {
- parent = head;
- Console.WriteLine("Tree is empty");
- }
- }
- public void insert(int element)
- {
- Node newNode, currentNode=null, parent=null;
- find(element,ref parent,ref currentNode);
- if (currentNode != null)
- return;
- newNode = new Node(element, 0, 0, null, null);
- if (parent != head)//if tree is not empty
- {
- if (element < parent.data)
- {
- newNode.lchild = parent.lchild;
- newNode.rchild = parent;
- parent.lthread = 1;
- parent.lchild = newNode;
- }
- else if (element > parent.data)
- {
- newNode.rchild = parent.rchild;
- newNode.lchild = parent;
- parent.rthread = 1;
- parent.rchild = newNode;
- }
- }
- else//if tree is empty
- {
- head.lthread = 1;
- head.lchild = newNode;
- newNode.lchild = newNode.rchild = head;
- }
- }
- //if the right child of the node is a link, then we can traverse to the leftmost node in the
- //right subtree of that node to find its inorder successor.However, if the right child of the
- //node is a thread, then the thread will point to the inorder successor of that node
- public Node Inorder_successor(ref Node currentNode)//search the successor of currentNode
- {
- Node inorder_current=null;
- if (currentNode.rthread == 0)
- {//if the right child of currentNode is a thread,then the node which the thread point to is successor
- return currentNode.rchild;
- }
- inorder_current = currentNode.rchild;//make currentNode point to the right child of currentNode
- while (inorder_current.lthread != 0)//loop until reach the leaf node of left subtree
- inorder_current = inorder_current.lchild;
- return inorder_current;
- }
- public Node Inorder_predecessor(ref Node currentNode)//search the predecessor of currentNode
- {
- Node inorder_current = null;
- if (currentNode.lthread == 0)
- return currentNode.lchild;
- inorder_current = currentNode.lchild;
- while (inorder_current.rthread != 0)
- inorder_current = inorder_current.rchild;
- return inorder_current;
- }
- public void Inorder_traversal()
- {
- Node currentNode;
- if (head.lthread == 0)
- {
- Console.WriteLine("Tree is empty");
- return;
- }
- currentNode = head.lchild;
- while (currentNode.lthread != 0)//the fist-visit node is the leftmost node of the tree
- currentNode = currentNode.lchild;
- Console.Write(currentNode.data + " ");
- while (currentNode.rchild != head)
- {
- currentNode = Inorder_successor(ref currentNode);
- Console.Write(currentNode.data + " ");
- }
- }
- public void delete(int element)
- {
- Node parent=null, currentNode=null, child=null, successor=null, predecessor=null, inorder_parent=null;
- find(element, ref parent, ref currentNode);
- if (currentNode != null)
- {
- successor = Inorder_successor(ref currentNode);
- predecessor = Inorder_predecessor(ref currentNode);
- if (currentNode.lthread == 0 && currentNode.rthread == 0)//node to be deleted is a leaf node
- {
- if (parent != head)
- {
- if (parent.lchild == currentNode)
- {
- parent.lthread = 0;
- parent.lchild = currentNode.lchild;
- }
- else
- {
- parent.rthread = 0;
- parent.rchild = currentNode.rchild;
- }
- }
- else
- {
- head.lthread = 0;
- head.lchild = head;
- }
- }
- else if ((currentNode.lthread == 0 && currentNode.rthread != 0)
- || (currentNode.lthread != 0 && currentNode.rthread == 0))
- //node to be deleted has one child
- {
- if (currentNode.lthread == 1)//if currentNode has a left child
- {
- child = currentNode.lchild;
- if (parent.lchild == currentNode)//if currentNode is the left child of parent
- parent.lchild = child;
- else
- parent.rchild = child;
- predecessor.rchild = successor;
- predecessor.rthread = 0;
- }
- else//current has a right child
- {
- child = currentNode.rchild;
- if (parent.lchild == currentNode)
- parent.lchild = child;
- else
- parent.rchild = child;
- successor.lchild = predecessor;
- successor.lthread = 0;
- }
- }
- else if (currentNode.lthread == 1 && currentNode.rthread == 1)
- {//node to be delete has two children
- find(successor.data, ref parent, ref successor);
- inorder_parent = parent;//the parent of successor
- currentNode.data = successor.data;
- currentNode = successor;//now delete the successor ,make currentNode point to the successor
- if (currentNode.lthread == 0 && currentNode.rthread == 0)//node to be deleted is a leaf node
- {
- if (parent != head)
- {
- if (parent.lchild == currentNode)
- {
- parent.lthread = 0;
- parent.lchild = currentNode.lchild;
- }
- else
- {
- parent.rthread = 0;
- parent.rchild = currentNode.rchild;
- }
- }
- else
- {
- head.lthread = 0;
- head.lchild = head;
- }
- }
- if ((currentNode.lthread == 0 && currentNode.rthread != 0)
- || (currentNode.lthread != 0 && currentNode.rthread == 0))
- //node to be deleted has one child
- {
- if (currentNode.lthread == 1)//if currentNode has a right child
- {
- child = currentNode.lchild;
- if (parent.lchild == currentNode)//if currentNode is the left child of parent
- parent.lchild = child;
- else
- parent.rchild = child;
- successor.lchild = predecessor;
- successor.lthread = 0;
- }
- else//current has a left child
- {
- child = currentNode.rchild;
- if (parent.lchild == currentNode)
- parent.lchild = child;
- else
- parent.rchild = child;
- successor.lchild = predecessor;
- successor.rthread = 0;
- }
- }
- }
- }
- }
- static void Main(string[] args)
- {
- ThreadedBST b = new ThreadedBST();
- while (true)
- {
- Console.Clear();
- Console.Write("Inorder traverse:");
- b.Inorder_traversal();
- Console.WriteLine("/nMenu");
- Console.WriteLine("1. Implement insert operation");
- Console.WriteLine("2. Implement delete operation");
- Console.WriteLine("3. Exit");
- Console.Write("/nEnter your Choice:");
- char ch = Convert.ToChar(Console.ReadLine());
- switch (ch)
- {
- case '1':
- {
- Console.Write("Enter a number: ");
- int num =Convert.ToInt32( Console.ReadLine());
- b.insert(num);
- }
- break;
- case '2':
- {
- Console.Write("Enter a number: ");
- int num =Convert.ToInt32( Console.ReadLine());
- b.delete(num);
- }
- break;
- case '3':
- return;
- default:
- Console.WriteLine("Invalid option");
- break;
- }
- }
- }
- }
- }
线索二叉树(threaded binary search tree) C#
最新推荐文章于 2024-09-02 16:43:09 发布