14

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

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

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

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

4

5 回答 5

9

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

还有C5,我现在正在研究的一个库。

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

于 2008-09-07T11:06:32.477 回答
4

这是一个通用的二叉搜索树。我唯一没有做的是实现 IEnumerable<T> 以便您可以使用枚举器遍历树。然而,这应该是相当直截了当的。

特别感谢 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; }
        }        
    }

和实际的树类:

    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--;
        }
    }
}
于 2008-09-07T14:18:26.930 回答
2

对于您提到的数据结构,我会推荐两个资源:首先,有 .NET Framework 源代码(信息可以在 ScottGu 的博客上找到)。

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

希望这可以帮助!

于 2008-09-07T11:49:22.090 回答
2

N泛型

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

于 2009-01-19T21:00:23.943 回答
1

查看转子 2或使用反射器,看看微软是如何做到的!!!

您也可以查看Microsoft 参考源

于 2008-09-08T09:35:07.040 回答