【问题标题】:Fundamental Data Structures in C#C# 中的基本数据结构
【发布时间】:2008-09-07 10:54:11
【问题描述】:

我想知道人们如何在不使用基类库实现的情况下在 C# 中实现以下数据结构:-

  • 链接列表
  • 哈希表
  • 二叉搜索树
  • 红黑树
  • B 树
  • 二项式堆
  • 斐波那契堆

以及人们能想到的任何其他基本数据结构!

我很好奇,因为我想加深对这些数据结构的理解,很高兴看到 C# 版本而不是互联网上的典型 C 示例!

【问题讨论】:

  • 您可以将“优先队列”添加到列表中。它不在 .Net 3.5 中。

标签: c# .net data-structures


【解决方案1】:

关于这个主题有一系列MSDN articles。但是,我自己并没有真正阅读过文本。我认为 .NET 的集合框架有一个损坏的接口,不能很好地扩展。

还有C5,我现在正在调查一个库。

由于上述原因,我有一个项目来实现我自己的 .NET 集合库,但在第一个基准测试显示即使是简单的、非线程安全的泛型 Vector 后,我已经停止了这个项目实现比原生 List<T> 慢。由于我已经注意不要产生任何低效的 IL 代码,这意味着 .NET 根本不适合(还)编写内部数据结构的标准替换,并且 .NET 框架必须使用一些幕后- 场景知识以优化内置集合类。

【讨论】:

    【解决方案2】:

    这是一个通用的二叉搜索树。我唯一没有做的是实现 IEnumerable 以便您可以使用枚举器遍历树。但是,这应该是相当简单的。

    特别感谢 Scott Mitchel 的 BSTTree 文章,我将其用作删除方法的参考。

    节点类:

        class BSTNode<T> where T : IComparable<T>
        {
            private BSTNode<T> _left = null;
            private BSTNode<T> _right = null;        
            private T _value = default(T);
    
            public T Value
            {
                get { return this._value; }
                set { this._value = value; }
            }
    
            public BSTNode<T> Left
            {
                get { return _left; }
                set { this._left = value; }
            }
    
            public BSTNode<T> Right
            {
                get { return _right; }
                set { this._right = value; }
            }        
        }
    

    还有实际的 Tree 类:

        class BinarySearchTree<T> where T : IComparable<T>
        {
            private BSTNode<T> _root = null;
            private int _count = 0;
    
            public virtual void Clear()
            {
                _root = null;
                _count = 0;
            }
    
            public virtual int Count
            {
                get { return _count; }
            }
    
            public virtual void Add(T value)
            {
                BSTNode<T> newNode = new BSTNode<T>();
                int compareResult = 0;
    
                newNode.Value = value;
    
                if (_root == null)
                {
                    this._count++;
                    _root = newNode;
                }
                else
                {
                    BSTNode<T> current = _root;
                    BSTNode<T> parent = null;
    
                    while (current != null)
                    {
                        compareResult = current.Value.CompareTo(newNode.Value);
    
                        if (compareResult > 0)
                        {
                            parent = current;
                            current = current.Left;
                        }
                        else if (compareResult < 0)
                        {
                            parent = current;
                            current = current.Right;
                        }
                        else
                        {
                            // Node already exists
                            throw new ArgumentException("Duplicate nodes are not allowed.");
                        }
                    }
    
                    this._count++;
    
                    compareResult = parent.Value.CompareTo(newNode.Value);
                    if (compareResult > 0)
                    {
                        parent.Left = newNode;
                    }
                    else
                    {
                        parent.Right = newNode;
                    }
                }
            }
    
            public virtual BSTNode<T> FindByValue(T value)
            {
                BSTNode<T> current = this._root;
    
                if (current == null)
                    return null;   // Tree is empty.
                else
                {
                    while (current != null)
                    {
                        int result = current.Value.CompareTo(value);
                        if (result == 0)
                        {
                            // Found the corrent Node.
                            return current;
                        }
                        else if (result > 0)
                        {
                            current = current.Left;
                        }
                        else
                        {
                            current = current.Right;
                        }
                    }
    
                    return null;
                }
            }
    
            public virtual void Delete(T value)
            {
    
                BSTNode<T> current = this._root;
                BSTNode<T> parent = null;
    
                int result = current.Value.CompareTo(value);
    
                while (result != 0 && current != null)
                {
                    if (result > 0)
                    {
                        parent = current;
                        current = current.Left;
                    }
                    else if (result < 0)
                    {
                        parent = current;
                        current = current.Right;
                    }
    
                    result = current.Value.CompareTo(value);
                }
    
                if (current == null)
                    throw new ArgumentException("Cannot find item to delete.");
    
    
    
                if (current.Right == null)
                {
                    if (parent == null)
                        this._root = current.Left;
                    else
                    {
                        result = parent.Value.CompareTo(current.Value);
                        if (result > 0)
                        {
                            parent.Left = current.Left;
                        }
                        else if (result < 0)
                        {
                            parent.Right = current.Left;
                        }
                    }
                }
                else if (current.Right.Left == null)
                {
                    if (parent == null)
                        this._root = current.Right;
                    else
                    {
                        result = parent.Value.CompareTo(current.Value);
                        if (result > 0)
                        {
                            parent.Left = current.Right;
                        }
                        else if (result < 0)
                        {
                            parent.Right = current.Right;
                        }
                    }
                }
                else
                {
    
                    BSTNode<T> furthestLeft = current.Right.Left;
                    BSTNode<T> furthestLeftParent = current.Right;
    
                    while (furthestLeft.Left != null)
                    {
                        furthestLeftParent = furthestLeft;
                        furthestLeft = furthestLeft.Left;
                    }
    
                    furthestLeftParent.Left = furthestLeft.Right;
    
                    furthestLeft.Left = current.Left;
                    furthestLeft.Right = current.Right;
    
                    if (parent != null)
                    {
                        result = parent.Value.CompareTo(current.Value);
                        if (result > 0)
                        {
                            parent.Left = furthestLeft;
                        }
                        else if (result < 0)
                        {
                            parent.Right = furthestLeft;
                        }
                    }
                    else
                    {
                        this._root = furthestLeft;
                    }
                }
    
                this._count--;
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我会为您提到的数据结构推荐两种资源: 首先是 .NET Framework 源代码(信息可以在 ScottGu 的博客here 找到)。

      另一个有用的资源是在 Codeplex here 上找到的 Wintellect 的 Power Collections。

      希望这会有所帮助!

      【讨论】:

        【解决方案4】:

        NGenerics

        “提供在标准 .NET 框架中未实现的通用数据结构和算法的类库。”

        【讨论】:

          【解决方案5】:

          查看Rotor 2 或使用reflector 看看微软是如何做到的!!!

          您也可以查看Microsoft reference source

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-17
            • 2020-05-17
            • 1970-01-01
            • 1970-01-01
            • 2016-08-16
            • 1970-01-01
            相关资源
            最近更新 更多