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#中参数的ref与val的关系
{
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的学习之路 阅读(532) 评论(0) 编辑 收藏 举报