上了三年半的大学,学的计算机,我却一直不知道二叉树是干什么使的。最近在看《Visual C# 2005 从入门到精通》,书中说.NET类库里缺少二叉树这个类,于是就想自己写一个,没想到一边写着一边思考,竟也把二叉树的用处以及其优势劣势搞明白了。

二叉树有什么用?
二叉树本身没有什么用,其主要作用在于有序二叉树(下文简称“有序二叉树”为“二叉树”)。二叉树在插入和查找的时候具有高效率。为什么会具有高效率?因为二叉树保持总保持一个有序状态:即左子树小于根节点,根节点小于右子树。这样的结构使得二叉树在查找上具有与二分搜索同样的效率。当然,排好序的的一维数组也可以进行二分搜索。那二叉树的优势在哪呢?就在于其插入的效率比数组高,二叉树不用为了给新添加的元素腾出地方而移动大量元素。二叉树插入的效率与搜索的效率是相等的。

对比如下:(lgN是以2为底N的对数)
二叉树:搜索效率=插入效率=lgN
有序数组:搜索效率=lgN,插入效率=lgN + N/2

由此不难得到二叉树的适用场合:需要经常插入和删除元素且对速度要求较高的场合。
比如要举办一个大型网络会议,有成千上万的人参加,并且随着时间的推移会不断有新的人加入进来或离开。这种场合就很适合用二叉树。

有序性是二叉树最重要特点,编程的时候决不应该破坏有序性。为了保持有序性,在删除节点的时候就会遇到一些麻烦。以前在《数据结构》课本上见过删除节点的算法,很复杂而且很难读懂。于是我就干脆自己写一个删除节点的算法,费了好一番周折。开始我打算从物理上删除,即把要删除的节点真的从树中拿掉。这种做法带来的问题就是,被删节点的左右两棵子树不知该如何安放。为了解决这个问题,我在类中添加了SearchParent方法,甚至还想添加一个parent字段以提高效率,后来越做越觉得麻烦。最后我想出一个好的解决办法,给每个节点添加一个removed字段,用来标识节点是否已被删除。这样之前为了删除节点而写的那一堆辅助方法就都用不着了!可见优秀的设计比优秀的算法更有效!有了removed字段,删除节点的效率就与插入和搜索的效率一样,都是lgN。

对二叉树来说,有序性第一重要,位列第二的就是平衡性了。一个极不平衡的二叉树的效率是很低的。为了保持高效率,我添加了Optimize方法来使二叉树变得平衡。只有在平衡结构下,效率才能达到上面所说的lgN。《数据结构》课本上也介绍过平衡二叉树的算法,但相当繁琐。我自己写了一个,可能效率不是最高,但算法简单易理解。

我写的这个二叉树类有很多方法用到了递归。虽然递归在速度上不是很快,但能大大简化算法,避免了很多因算法设计不当而引入的bug。我信奉的编程思想是:首先保证简单,然后才追求速度。

我目前还是学生,编程肯定不够专业,在此将源代码奉上,望您提出宝贵意见!新年到了,愿2007是您丰收的一年!


 

using System;
using System.Collections.Generic;
using System.Text;


namespace OrderedBinaryTree
{
    
/// <summary>
    
/// 有序二叉树
    
/// 作者: dc10101
    
/// 完成日期:2007/1/1
    
/// </summary>
    
/// <typeparam name="T"></typeparam>

    public class Tree<T> where T:IComparable<T>
    
{
        
fields

        
properties

        
methods

    }
// Tree<T>
}
// namespace


posted on 2007-01-01 18:29  MainTao  阅读(2749)  评论(1编辑  收藏  举报