了解集合本质必须要知晓的概念04-二叉查找树

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

与链表、堆栈和队列不一样,二叉查找树不是线性数据结构,是二维数据结构。每个节点都包含一个LeftNode和RightNode,二叉查找树把比节点数据项小的数据放在LeftNode,把比节点数据项大的数据放在RightNode。

关于节点的类。

publicclassTreeNode<T>

{

publicT Element {get;set; }

publicTreeNode<T> LeftNode {get;set; }

publicTreeNode<T> RightNode {get;set; }

publicTreeNode(T element)

{

this.Element = element;

LeftNode = RightNode =null;

}

publicoverridestringToString()

{

stringnodeString = "[" +this.Element + "";

if(this.LeftNode ==null&&this.RightNode ==null)

{

nodeString += "(叶节点)";

}

if(this.LeftNode !=null)

{

nodeString += "左节点:" +this.LeftNode.ToString();

}

if(this.RightNode !=null)

{

nodeString += "右节点:" +this.RightNode.ToString();

}

nodeString += "]";

returnnodeString;

}

}

以上,把比节点数据项Element小的数据所在节点赋值给LeftNode,把比节点数据项Element大的数据所在节点赋值给RightNode。

创建一个泛型二叉树查找类,维护着一个根节点,并提供各种对节点的操作方法。

publicclassBinarySearchTree<T>

{

publicTreeNode<T> Root {get;set; }

publicBinarySearchTree()

{

this.Root =null;

}

//把某个数据项插入到二叉树

publicvoidInsert(T x)

{

this.Root = Insert(x,this.Root);

}

//把某个数据项从二叉树中删除

publicvoidRemove(T x)

{

this.Root = Remove(x,this.Root);

}

//删除二叉树中的最小数据项

publicvoidRemoveMin()

{

this.Root = RemoveMin(this.Root);

}

//获取二叉树中的最小数据项

publicT FindMin()

{

returnElemntAt(FindMin(this.Root));

}

//获取二叉树中的最大数据项

publicT FindMax()

{

returnElemntAt(FindMax(this.Root));

}

//获取二叉树中的某个数据项

publicT Find(T x)

{

returnElemntAt(Find(x,this.Root));

}

//清空

publicvoidMakeEmpty()

{

this.Root =null;

}

//判断二叉树是否为空,是否存在

publicboolIsEmpty()

{

returnthis.Root ==null;

}

//获取某个节点的数据项

PRivateT ElemntAt(TreeNode<T> t)

{

returnt ==null?default(T) : t.Element;

}

/// <summary>

/// 查找节点

/// </summary>

/// <param name="x">要查找数据项</param>

/// <param name="t">已存在的节点</param>

/// <returns>返回节点</returns>

privateTreeNode<T> Find(T x, TreeNode<T> t)

{

while(t !=null)//当没有找到匹配数据项,不断调整查找范围,即t的值

{

if((xasIComparable).CompareTo(t.Element) < 0)

{

t = t.LeftNode;

}

elseif((xasIComparable).CompareTo(t.Element) > 0)

{

t = t.RightNode;

}

else//如果找到数据项,就返回当前t的值

{

returnt;

}

}

returnnull;

}

//获取最小的节点,

privateTreeNode<T> FindMin(TreeNode<T> t)

{

if(t !=null)

{

while(t.LeftNode !=null)//不断循环二叉树的左半边树

{

t = t.LeftNode;//不断设置t的值

}

}

returnt;

}

//获取最大的节点

privateTreeNode<T> FindMax(TreeNode<T> t)

{

if(t !=null)

{

while(t.RightNode !=null)

{

t = t.RightNode;

}

}

returnt;

}

/// <summary>

/// 插入节点

/// </summary>

/// <param name="x">要插入的数据项</param>

/// <param name="t">已经存在的节点</param>

/// <returns>返回已存在的节点</returns>

protectedTreeNode<T> Insert(T x, TreeNode<T> t)

{

if(t ==null)

{

t =newTreeNode<T>(x);

}

elseif((xasIComparable).CompareTo(t.Element) < 0)

{

//等号右边的t.LeftNode是null,因此会创建一个TreeNode实例给t.LeftNode

t.LeftNode = Insert(x, t.LeftNode);

}

elseif((xasIComparable).CompareTo(t.Element) > 0)

{

t.RightNode = Insert(x, t.RightNode);

}

else

{

thrownewException("插入了相同元素~~");

}

returnt;

}

//删除最小的节点

//返回当前根节点

protectedTreeNode<T> RemoveMin(TreeNode<T> t)

{

if(t ==null)

{

thrownewException("节点不存在~~");

}

elseif(t.LeftNode !=null)

{

//通过递归不断设置t.LeftNode,直到t.LeftNode=null

t.LeftNode = RemoveMin(t.LeftNode);

returnt;

}

else//当t.LeftNode=null的时候,就把t.RightNode当作最小节点返回

{

returnt.RightNode;

}

}

//删除某数据项,返回当前根节点

protectedTreeNode<T> Remove(T x, TreeNode<T> t)

{

if(t ==null)

{

thrownewException("节点不存在~~");

}

elseif((xasIComparable).CompareTo(t.Element) < 0)

{

t.LeftNode = Remove(x, t.LeftNode);

}

elseif((xasIComparable).CompareTo(t.Element) > 0)

{

t.RightNode = Remove(x, t.RightNode);

}

elseif(t.LeftNode !=null&& t.RightNode !=null)

{

t.Element = FindMin(t.RightNode).Element;

t.RightNode = RemoveMin(t.RightNode);

}

else

{

t = (t.LeftNode !=null) ? t.LeftNode : t.RightNode;

}

returnt;

}

publicoverridestringToString()

{

returnthis.Root.ToString();

}

}

客户端创建二叉查找树的实例,并调用实例方法插入随机数据。BinarySearchTree<int> intTree =newBinarySearchTree<int>();

Random r =newRandom(DateTime.Now.Millisecond);

stringtrace = "";

//插入5个随机数

for(inti = 0; i < 5; i++)

{

intrandomInt = r.Next(1, 500);

intTree.Insert(randomInt);

trace += randomInt + "";

}

Console.WriteLine("最大的节点:" + intTree.FindMax());

Console.WriteLine("最小的节点:" + intTree.FindMin());

Console.WriteLine("根节点:" + intTree.Root.Element);

Console.WriteLine("插入节点的依次顺序是:" + trace);

Console.WriteLine("打印树为:" + intTree);

Console.ReadKey();

参考资料:

Binary Search Trees (BSTs) in C#

“了解集合本质必须要知晓的概念”系列包括:

了解集合本质必须要知晓的概念01-链表了解集合本质必须要知晓的概念02-堆栈了解集合本质必须要知晓的概念03-队列了解集合本质必须要知晓的概念04-二叉查找树

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航