Binary Search Tree的C#实现

//////////////////////

// BST.cs

//////////////////////

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace BST

{

    class node

    {

        public node left;

        public node right;

        public node parent;

        public object key;

        public node()

        {

            left = null;

            right = null;

            parent = null;

            key = null;

        }

        public node(int key)

        {

            this.key=key;

            left=null;

            right=null;

            parent=null;

        }

        public void display()

        {

            Console.WriteLine("Node: {0},  Parent {1},  Left {2},  Right {3}",this,this.parent,this.left,this.right);

        }

        public override string ToString()

        {

            try

            {

            return this.key.ToString();

            }

            catch (System.NullReferenceException ex)

            {

                return "null";

            }

        }

    }

 

    class BST

    {

        public node root;

 

        public BST()

        {

            root = new node();

        }

 

        public BST(int rootkey)

        {

            root = new node(rootkey);

        }

 

        public node TreeMinimum(node x)//注意C#中参数的refval的关系

        {

            while (x.left!=null)

            {

                x = x.left;

            }

            return x;

        }

 

        public node TreeMaximum(node x)

        {

            while (x.right!=null)

            {

                x = x.right;

            }

            return x;

        }

 

        public node insert(node NewNode)

        {

            node y = new node();

            node x = this.root;

            while (x!=null)

            {

                y = x;

                if ((int)NewNode.key<(int)x.key)

                {

                    x = x.left;

                }

                else

                {

                    x = x.right;

                }

            }//finds the place to insert

            NewNode.parent = y;

            if (y==null)

            {

                this.root = NewNode;

            }

            else if ((int)NewNode.key<(int)y.key)

            {

                y.left = NewNode;

            }

            else

            {

                y.right = NewNode;

            }

            return NewNode;

        }

        public node search(node x,int key)

        {

            node current = x;

            while (current!=null && (int)current.key!=key)

            {

                if (key<(int)current.key)

                {

                    current = current.left;

                }

                else

                {

                    current = current.right;

                }

            }

            return current;

        }

        public void inorder_transvers(node x)

        {

            if (x!=null)

            {

               inorder_transvers(x.left);

                //do some extra work here

                ExtraTransverseWork(this, new ArgNode(x));

               inorder_transvers(x.right);

            }

        }

 

        public void preorder_transvers(node x)

        {

            if (x != null)

            {

                //do some extra work here

                ExtraTransverseWork(this, new ArgNode(x));

                preorder_transvers(x.left);

                preorder_transvers(x.right);

            }

        }

 

        public void postorder_transvers(node x)

        {

            if (x != null)

            {

                postorder_transvers(x.left);

                postorder_transvers(x.right);

                //do some extra work here

                ExtraTransverseWork(this, new ArgNode(x));

            }

        }

 

        public node GetSuccessor(node x)

        {

            //CASE 1: successor is in the right subtree

            if (x.right!=null)

            {

                return TreeMinimum(x.right);;

            }

            //CASE2: successor is in the parent path(the CASE when x=root is included here!)

            else

            {

                node y = x.parent;

                while (y!=null && x==y.right)//successor.right=x indicates successor<x

                {

                    x = y;

                    y = y.parent;

                }

                return y;

            }

        }

 

        public node Delete(node DeleteNode)

        {

            //STEP1:choose the node y to be spliced out

            node y=new node();

            if (DeleteNode.left==null || DeleteNode.right==null)

            {

                y = DeleteNode;

            }

            else

            {

                y = GetSuccessor(DeleteNode);

            }

            //STEP2:set x to non-NIL child of y, or NIL if y has no child

            node x=new node();

            if (y.left!=null)

            {

                x = y.left;

            }

            else

            {

                x = y.right;

            }

            //STEP3:y is spliced out

            if (x!=null)

            {

                x.parent = y.parent;

            }

            if (y.parent==null)

            {

                this.root = x;

            }

            else if(y==y.parent.left)

            {

                y.parent.left = x;

            }

            else

            {

                y.parent.right = x;

            }

            //STEP4:

            if (y!=DeleteNode)

            {

                //copy satellite data of y into z

                DeleteNode.key = y.key;

            }

            return y;

        }

 

        //class event variable for Transverse Job Routine

        public event EventHandler<ArgNode> ExtraTransverseWork;    

    }

 

    class ArgNode : EventArgs

    {

        public node m_ArgNode;

        public ArgNode(node x)

        {

            m_ArgNode = x;

        }

    }

 

}

 

 

 

//////////////////////

// Program.cs

//////////////////////

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace BST

{

    class Program

    {

        static void Main(string[] args)

        {

            //node node12 = new node(12);

            //node1.display();

            BST mybst = new BST(10);

            mybst.insert(new node(12));

            mybst.insert(new node(19));

            mybst.insert(new node(15));

            mybst.insert(new node(17));

            mybst.insert(new node(11));

            mybst.insert(new node(8));

            mybst.insert(new node(9));

            mybst.ExtraTransverseWork += new EventHandler<ArgNode>(ShowNode);

            mybst.ExtraTransverseWork += new EventHandler<ArgNode>(VerifyNode);

            //mybst.ExtraTransverseWork += new EventHandler<ArgNode>(ShowSuccessor);

            //mybst.ExtraTransverseWork += new EventHandler<ArgNode>(ShowTreeMinimum);

            //mybst.ExtraTransverseWork += new EventHandler<ArgNode>(ShowTreeMaximum);

 

            Console.WriteLine("*** Displaying BST ***\n**********************");

            mybst.preorder_transvers(mybst.root);

            Console.WriteLine("**********************");

            mybst.Delete(mybst.search(mybst.root, 12));

            mybst.preorder_transvers(mybst.root);

            Console.WriteLine("**********************");

            Console.WriteLine("*** Press Any Key to Continue...");

            Console.ReadKey();

        }

 

        static void ShowNode(object sender, ArgNode e)

        {

            e.m_ArgNode.display();

        }

 

 

        static void ShowTreeMaximum(object sender, ArgNode e)

        {

            BST bst = (BST)sender;

            Console.WriteLine("\tTreeMaximum of node {0} is node {1}", e.m_ArgNode, bst.TreeMaximum(e.m_ArgNode));

        }

 

        static void ShowTreeMinimum(object sender, ArgNode e)

        {

            BST bst = (BST)sender;

            Console.WriteLine("\tTreeMinimum of node {0} is node {1}", e.m_ArgNode, bst.TreeMinimum(e.m_ArgNode));

        }

 

        static void ShowSuccessor(object sender, ArgNode e)

        {

            BST bst = (BST)sender;

            Console.WriteLine("\tSuccessor of node {0} is node {1}", e.m_ArgNode, bst.GetSuccessor(e.m_ArgNode));

        }

 

        static void VerifyNode(object sender, ArgNode e)

        {

            if (e.m_ArgNode.left!=null &&

                (int)e.m_ArgNode.key<(int)e.m_ArgNode.left.key)

            {

                Console.WriteLine("ERROR: left child of node{0} is corrupted!", e.m_ArgNode);

            }

            if (e.m_ArgNode.right!=null &&

                (int)e.m_ArgNode.key>(int)e.m_ArgNode.right.key)

            {

                Console.WriteLine("ERROR: right child of node{0} is corrupted!", e.m_ArgNode);

            }

        }

 

    }

}

 

posted on 2009-08-06 20:55  TobyLin的学习之路  阅读(529)  评论(0编辑  收藏  举报

导航