当前位置:  编程技术>.net/c#/asp.net

浅谈二叉查找树的集合总结分析

    来源: 互联网  发布时间:2014-10-21

    本文导语:  我们都知道Dictionary查找元素非常快,其实现原理是:将你TKey的值散列到数组的指定位置,将TValue的值存入对应的位置,由于取和存用的是同一个算法,所以就很容易定位到TValue的位置,花费的时间基本上就是实现散列算法的...

我们都知道Dictionary查找元素非常快,其实现原理是:将你TKey的值散列到数组的指定位置,将TValue的值存入对应的位置,
由于取和存用的是同一个算法,所以就很容易定位到TValue的位置,花费的时间基本上就是实现散列算法的时间,跟其中元素的个数没有关系,故取值的时间复杂度为O(1)。
集合无非都是基于最基础语法的数组[],先欲分配,然后向其中添加元素,容量不够就创建一个2倍容量的数组,将之前的元素赋值过来,将之前的数组回收,
但基于散列算法的集合这点上有点不同,他并不是每次创建一个2倍容量的数组,为了让元素均匀的分布到数组上,数组的容量是这么增长的:3,7,11,17,23,29,37,47,59,71,89,107,131,163,197,239,293,353,431,521,631,761,919,1103...
以质数的方式增长。由于每次扩充数组的容量较小,如果要向其中添加很多元素的话,程序员又没有预先分配内存,那就会出现多次数组的创建、复制和回收。
一直想做个有用的东西出来,让想用的人用,又能让自己练练手,于是这次做了一个基于二叉查找树的集合,我们知道在二叉查找树中查询元素的最优时间复杂度是O(logN)即在满二叉树的情况下,最坏时间复杂度是O(n)即除叶子节点外每个节点只有一个子节点,
查找元素它也是很快的哦,而且查找的时候都只是做Int型的比较,而Dictionary是基于一个散列算法,当然基于二插查找树的集合也有自身的缺点:
1:元素必须实现接口IBinaryTree,其属性CompareValue主要用于比较生成二叉查找树
2:元素必须是可以new的,即不支持基础类型int,char,string等
3:每个节点都有左右两个子节点,他们只是起到指针的作用,指向该节点的子节点,只需占用额外的少量内存
4:基本上都是基于递归实现,元素过多的话,会栈溢出
优点是常用的一些功能都有,功能如下,练手吗,但会一直优化下去
代码如下:

public class BinaryTree : IDisposable, IEnumerable, IEnumerable where T :IBinaryTree, new()
    {
        public BinaryTree();
        public BinaryTree(IEnumerable list);//将一个数组构造成二插查找树
        public BinaryTree(T root); //指定跟节点
        public int Count { get; }//元素个数
        public T this[IBinaryTree iBinaryTree] { get; }//数组索引直接访问元素
        public void Add(T t);//添加元素
        public void Clear();//清除所有元素
        public bool Contains(T iBinaryTree);//是否包含自定元素
        public void Dispose();//释放资源,支持using
        public T Find(IBinaryTree iBinaryTree);//查找元素
        public T Find(IBinaryTree iBinaryTree, TreeNode node);//在指定的节点下查找元素
        public T FindMax();//最大元素
        public T FindMin();//最小元素
        public T FindMin(TreeNode node);//在指定的节点下查找最小元素
        public IEnumerator GetEnumerator();//返回所有元素,支持foreach
        public TreeNode Remove(T t);//删除元素
        public TreeNode Remove(IBinaryTree iBinaryTree, TreeNode node);//在指定的节点下删除元素
        public IEnumerable Sort();//排序(升序)
        public IEnumerable ToList();//返回所有元素
    }

代码如下:

源码
namespace Utils
{
    ///
    /// 二叉树接口
    ///
    public interface IBinaryTree
    {
        ///
        /// 用于比较的值
        ///
        int CompareValue
        {
            get;
            set;
        }
    }
    public class TreeNode where T : IBinaryTree, new()
    {
        public TreeNode Left
        {
            get;
            set;
        }
        public TreeNode Right
        {
            set;
            get;
        }
        public T Data
        {
            get;
            set;
        }
        public TreeNode(T t)
        {
            this.Data = t;
        }
        public TreeNode()
            : this(default(T))
        {
        }
    }
    ///
    /// 二插查找树
    ///
    public class BinaryTree : IDisposable,IEnumerable where T : IBinaryTree, new()
    {
        public BinaryTree()
        {

        }
        public BinaryTree(T root)
        {
            if (root == null)
            {
                throw new NullReferenceException("Parameter is null");
            }
            Add(root);
        }
        public BinaryTree(IEnumerable list)
        {
            if (list == null)
            {
                throw new NullReferenceException("Parameter is null");
            }
            foreach (var item in list)
            {
                Add(item);
            }
        }
        //根节点
        private TreeNode root;
        //添加节点(没有检查根节点是否为空,所以设为private)
        private void Add(T t, TreeNode root)
        {
            if (t == null)
            {
                return;
            }
            if (t.CompareValue < root.Data.CompareValue)
            {
                if (root.Left == null)
                {
                    root.Left = new TreeNode(t);
                    ++Count;
                }
                else
                {
                    Add(t, root.Left);
                }
            }
            else if (t.CompareValue > root.Data.CompareValue)
            {
                if (root.Right == null)
                {
                    root.Right = new TreeNode(t);
                    ++Count;
                }
                else
                {
                    Add(t, root.Right);
                }
            }
            else
            {
                root.Data = t;
            }
        }
        //添加节点
        public void Add(T t)
        {
            if (t == null)
            {
                return;
            }
            if (this.root == null)
            {
                this.root = new TreeNode(t);
                ++Count;
            }
            else
            {
                Add(t, this.root);
            }
        }
        //查找指定节点下的最小节点
        public T FindMin(TreeNode node)
        {
            if (node == null)
            {
                return default(T);
            }
            if (node.Left == null)
            {
                return node.Data;
            }
            else
            {
                return FindMin(node.Left);
            }
        }
        //查找最小节点
        public T FindMin()
        {
            return FindMin(this.root);
        }
        //查找最大节点
        private T FindMax(TreeNode node)
        {
            if (node.Right == null)
            {
                return node.Data;
            }
            else
            {
                return FindMax(node.Right);
            }
        }
        //查找最大节点
        public T FindMax()
        {
            return FindMax(this.root);
        }
        //删除指定节点下的节点
        public TreeNode Remove(IBinaryTree iBinaryTree, TreeNode node)
        {
            if (node == null)
            {
                return null;
            }
            if (iBinaryTree == null)
            {
                return node;
            }
            if (iBinaryTree.CompareValue < node.Data.CompareValue)
            {
                node.Left = Remove(iBinaryTree, node.Left);
            }
            else if (iBinaryTree.CompareValue > node.Data.CompareValue)
            {
                node.Right = Remove(iBinaryTree, node.Right);
            }
            else
            {
                if (node.Left != null && node.Right != null)
                {
                    T tmpNode = FindMin(node.Right);//查找当前节点有子树的最小节点
                    node.Data.CompareValue = tmpNode.CompareValue;//将右子树的最小节点取代当前要删除的节点
                    node.Right = Remove(tmpNode, node.Right);//这里是亮点,删除当前节点右子树的最小节点
                }
                else
                {
                    if (node.Left == null)
                    {
                        node = node.Right;
                    }
                    else if (node.Right == null)
                    {
                        node = node.Left;
                    }
                    else
                    {
                        node = null;
                    }
                    if (this.root.Data.CompareValue == iBinaryTree.CompareValue)//处理根节点
                    {
                        this.root = node;
                    }
                }
                --Count;
            }
            return node;
        }
        //删除节点
        public TreeNode Remove(T t)
        {
            if (this.root == null || t==null)
            {
                return null;
            }
            return Remove(t, this.root);
        }
        //查找节点
        public T Find(IBinaryTree iBinaryTree, TreeNode node)
        {
            if (node == null || iBinaryTree == null)
            {
                return default(T);
            }
            if (iBinaryTree.CompareValue < node.Data.CompareValue)
            {
                return Find(iBinaryTree, node.Left);
            }
            else if (iBinaryTree.CompareValue > node.Data.CompareValue)
            {
                return Find(iBinaryTree, node.Right);
            }
            return node.Data;
        }
        //查找节点
        public T Find(IBinaryTree iBinaryTree)
        {
            return Find(iBinaryTree, this.root);
        }
        //是否包含指定元素
        private bool Contains(IBinaryTree iBinaryTree, TreeNode node)
        {
            if (node == null || iBinaryTree == null)
            {
                return false; ;
            }
            if (iBinaryTree.CompareValue < node.Data.CompareValue)
            {
                return Contains(iBinaryTree, node.Left);
            }
            else if (iBinaryTree.CompareValue > node.Data.CompareValue)
            {
                return Contains(iBinaryTree, node.Right);
            }
            return iBinaryTree.Equals(node.Data);
        }
        //是否包含指定元素
        public bool Contains(T iBinaryTree)
        {
            return Contains(iBinaryTree, this.root);
        }
        //清除所有节点
        public void Clear()
        {
            while (this.Count > 0)
            {
                Remove(this.root.Data);
            }
            this.root = new TreeNode();
        }
        //释放资源
        public void Dispose()
        {
            while (this.Count > 0)
            {
                Remove(this.root.Data);
            }
            this.root = null;
        }
        //节点个数
        public int Count
        {
            private set;
            get;
        }
        //转换成集合
        public IEnumerable ToList()
        {
            IList list = new List(Count);
            LCR(this.root,list);
            return list;
        }
        //以前序遍历的方式将节点加入集合,用递归实现,如果元素很多可能会出现栈溢出
        private void LCR(TreeNode node, IList list)
        {
            if (node == null)
            {
                return;
            }
            if (node.Left != null)
            {
                LCR(node.Left, list);
            }
            list.Add(node.Data);//添加元素
            if (node.Right != null)
            {
                LCR(node.Right, list);
            }
        }
        //排序
        public IEnumerable Sort()
        {
            return ToList();
        }
        //返回一个循环访问集合的枚举数
        public IEnumerator GetEnumerator()
        {
            return this.ToList().GetEnumerator();
        }
        //返回一个循环访问集合的枚举数
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
        public T this[IBinaryTree iBinaryTree]
        {
            get {
                return this.Find(iBinaryTree);
            }
        }

    }
    public class Node : IBinaryTree
    {
        ///
        /// 用于比较的值
        ///
        public int CompareValue
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
        public override string ToString()
        {
            return string.Format("CompareValue:{0},Name:{1}", this.CompareValue, this.Name);
        }
    }
}


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • C++ Strings(字符串) 成员 rfind():查找最后一个与value相等的字符(逆向查找)
  • Linux查找包含指定文字的文件(linux查找指定文件)
  • 数据库 iis7站长之家
  • php顺序查找与二分查找实例
  • C++ MultiMaps 成员 find():查找元素
  • php顺序查找和二分查找示例
  • C++ Strings(字符串) 成员 find():在字符串中查找字符
  • 在unix查找某个目录下一小时前的生成的文件,怎么查找?find只能按天来查。
  • C++ Strings(字符串) 成员 find_first_of():查找第一个与value中的某值相等的字符
  • vim怎么查找并替换 “[bx][si]”呢。。貌似是因为两个中括号连在一起查找不到。。
  • C++ Strings(字符串) 成员 find_last_of():查找最后一个与value中的某值相等的字符
  • Linux下怎么查找指定文件大小的文件?如查找100MB以上的文件
  • C++ Strings(字符串) 成员 find_first_not_of():查找第一个与value中的所有值都不相等的字符
  • 还发一个查找文件的贴子,给一个相对目录USR0怎样用JAVA查找其下的文件
  • C++ Strings(字符串) 成员 find_last_not_of():查找最后一个与value中的所有值都不相等的字符
  • java 折半查找法(二分查找)实例
  • Linux c++库boost unordered_set数据插入及查找代码举例
  • php字符串查找 查找字符最后一次出现位置
  • HASH查找的程序实现及性能分析
  • jquery 父页面查找iframe子页面内容、子页面查找父页面内容
  • Linux c++库boost unordered_map数据插入及查找代码举例
  • 高分急求:UNIX环境下查找字符串的问题 (给出文件路径,和需要查找的字符串)工作急需,恳求各位高手帮忙!!!!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3