⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 orderedset.cs

📁 C#写的类似于STL的集合类,首先是C#编写,可以用于.net变程.
💻 CS
📖 第 1 页 / 共 5 页
字号:
//******************************
// Written by Peter Golde
// Copyright (c) 2004-2005, Wintellect
//
// Use and restribution of this code is subject to the license agreement 
// contained in the file "License.txt" accompanying this file.
//******************************

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

namespace Wintellect.PowerCollections
{
    /// <summary>
    /// OrderedSet&lt;T&gt; is a collection that contains items of type T. 
    /// The item are maintained in a sorted order, and duplicate items are not allowed. Each item has
    /// an index in the set: the smallest item has index 0, the next smallest item has index 1,
    /// and so forth.
    /// </summary>
    /// <remarks>
    /// <p>The items are compared in one of three ways. If T implements IComparable&lt;TKey&gt; or IComparable,
    /// then the CompareTo method of that interface will be used to compare items. Alternatively, a comparison
    /// function can be passed in either as a delegate, or as an instance of IComparer&lt;TKey&gt;.</p>
    /// <p>OrderedSet is implemented as a balanced binary tree. Inserting, deleting, and looking up an
    /// an element all are done in log(N) type, where N is the number of keys in the tree.</p>
    /// <p><see cref="Set&lt;T&gt;"/> is similar, but uses hashing instead of comparison, and does not maintain
    /// the items in sorted order.</p>
    ///</remarks>
    ///<seealso cref="Set&lt;T&gt;"/>
    [Serializable]
    public class OrderedSet<T> : CollectionBase<T>, ICollection<T>, ICloneable
    {
        // The comparer used to compare items. 
        private IComparer<T> comparer;

        // The red-black tree that actually does the work of storing the items.
        private RedBlackTree<T> tree;

        #region Constructors

        /// <summary>
        /// Creates a new OrderedSet. The T must implement IComparable&lt;T&gt;
        /// or IComparable. 
        /// The CompareTo method of this interface will be used to compare items in this set.
        /// </summary>
        ///<remarks>
        /// Items that are null are permitted, and will be sorted before all other items.
        ///</remarks>
        /// <exception cref="InvalidOperationException">T does not implement IComparable&lt;TKey&gt;.</exception>
        public OrderedSet(): 
            this(Comparers.DefaultComparer<T>())
        {
        }

        /// <summary>
        /// Creates a new OrderedSet. The passed delegate will be used to compare items in this set.
        /// </summary>
        /// <param name="comparison">A delegate to a method that will be used to compare items.</param>
        public OrderedSet(Comparison<T> comparison) :
            this(Comparers.ComparerFromComparison<T>(comparison))
        {
        }

        /// <summary>
        /// Creates a new OrderedSet. The Compare method of the passed comparison object
        /// will be used to compare items in this set.
        /// </summary>
        /// <remarks>
        /// The GetHashCode and Equals methods of the provided IComparer&lt;T&gt; will never
        /// be called, and need not be implemented.
        /// </remarks>
        /// <param name="comparer">An instance of IComparer&lt;T&gt; that will be used to compare items.</param>
        public OrderedSet(IComparer<T> comparer)
        {
            if (comparer == null)
                throw new ArgumentNullException("comparer");

            this.comparer = comparer;
            tree = new RedBlackTree<T>(comparer);
        }

        /// <summary>
        /// Creates a new OrderedSet. The T must implement IComparable&lt;T&gt;
        /// or IComparable. 
        /// The CompareTo method of this interface will be used to compare items in this set. The set is
        /// initialized with all the items in the given collection.
        /// </summary>
        ///<remarks>
        /// Items that are null are permitted, and will be sorted before all other items.
        ///</remarks>
        /// <param name="collection">A collection with items to be placed into the OrderedSet.</param>
        /// <exception cref="InvalidOperationException">T does not implement IComparable&lt;TKey&gt;.</exception>
        public OrderedSet(IEnumerable<T> collection): 
            this(collection, Comparers.DefaultComparer<T>())
        {
        }

        /// <summary>
        /// Creates a new OrderedSet. The passed delegate will be used to compare items in this set.
        /// The set is initialized with all the items in the given collection.
        /// </summary>
        /// <param name="collection">A collection with items to be placed into the OrderedSet.</param>
        /// <param name="comparison">A delegate to a method that will be used to compare items.</param>
        public OrderedSet(IEnumerable<T> collection, Comparison<T> comparison):
            this(collection, Comparers.ComparerFromComparison<T>(comparison))
        {
        }

        /// <summary>
        /// Creates a new OrderedSet. The Compare method of the passed comparison object
        /// will be used to compare items in this set. The set is
        /// initialized with all the items in the given collection.
        /// </summary>
        /// <remarks>
        /// The GetHashCode and Equals methods of the provided IComparer&lt;T&gt; will never
        /// be called, and need not be implemented.
        /// </remarks>
        /// <param name="collection">A collection with items to be placed into the OrderedSet.</param>
        /// <param name="comparer">An instance of IComparer&lt;T&gt; that will be used to compare items.</param>
        public OrderedSet(IEnumerable<T> collection, IComparer<T> comparer):
            this(comparer)
        {
            AddMany(collection);
        }

        /// <summary>
        /// Creates a new OrderedSet given a comparer and a tree that contains the data. Used
        /// internally for Clone.
        /// </summary>
        /// <param name="comparer">Comparer for the set.</param>
        /// <param name="tree">Data for the set.</param>
        private OrderedSet(IComparer<T> comparer, RedBlackTree<T> tree)
        {
            this.comparer = comparer;
            this.tree = tree;
        }

        #endregion Constructors

        #region Cloning

        /// <summary>
        /// Makes a shallow clone of this set; i.e., if items of the
        /// set are reference types, then they are not cloned. If T is a value type,
        /// then each element is copied as if by simple assignment.
        /// </summary>
        /// <remarks>Cloning the set takes time O(N), where N is the number of items in the set.</remarks>
        /// <returns>The cloned set.</returns>
        object ICloneable.Clone()
        {
            return this.Clone();     
        }

        /// <summary>
        /// Makes a shallow clone of this set; i.e., if items of the
        /// set are reference types, then they are not cloned. If T is a value type,
        /// then each element is copied as if by simple assignment.
        /// </summary>
        /// <remarks>Cloning the set takes time O(N), where N is the number of items in the set.</remarks>
        /// <returns>The cloned set.</returns>
        public OrderedSet<T> Clone()
        {
            OrderedSet<T> newSet = new OrderedSet<T>(comparer, tree.Clone());
            return newSet;
        }

        /// <summary>
        /// Makes a deep clone of this set. A new set is created with a clone of
        /// each element of this set, by calling ICloneable.Clone on each element. If T is
        /// a value type, then each element is copied as if by simple assignment.
        /// </summary>
        /// <remarks><para>If T is a reference type, it must implement
        /// ICloneable. Otherwise, an InvalidOperationException is thrown.</para>
        /// <para>Cloning the set takes time O(N log N), where N is the number of items in the set.</para></remarks>
        /// <returns>The cloned set.</returns>
        /// <exception cref="InvalidOperationException">T is a reference type that does not implement ICloneable.</exception>
        public OrderedSet<T> CloneContents()
        {
            bool itemIsValueType;
            if (!Util.IsCloneableType(typeof(T), out itemIsValueType))
                throw new InvalidOperationException(string.Format(Strings.TypeNotCloneable, typeof(T).FullName));

            OrderedSet<T> clone = new OrderedSet<T>(comparer);

            // Clone each item, and add it to the new ordered set.
            foreach (T item in this) {
                T itemClone;

                if (itemIsValueType)
                    itemClone = item;
                else {
                    if (item == null)
                        itemClone = default(T);    // Really null, because we know T is a reference type
                    else
                        itemClone = (T)(((ICloneable)item).Clone());
                }

                clone.Add(itemClone);
            }

            return clone;
        }

        #endregion Cloning

        #region Basic collection containment

        /// <summary>
        /// Returns the IComparer&lt;T&gt; used to compare items in this set. 
        /// </summary>
        /// <value>If the set was created using a comparer, that comparer is returned. If the set was
        /// created using a comparison delegate, then a comparer equivalent to that delegate
        /// is returned. Otherwise
        /// the default comparer for T (Comparer&lt;T&gt;.Default) is returned.</value>
        public IComparer<T> Comparer
        {
            get
            {
                return this.comparer;
            }
        }

        /// <summary>
        /// Returns the number of items in the set.
        /// </summary>
        /// <remarks>The size of the set is returned in constant time.</remarks>
        /// <value>The number of items in the set.</value>
        public sealed override int Count
        {
            get {
                return tree.ElementCount;
            }
        }

        /// <summary>
        /// Returns an enumerator that enumerates all the items in the set. 
        /// The items are enumerated in sorted order.
        /// </summary>
        /// <remarks>
        /// <p>Typically, this method is not called directly. Instead the "foreach" statement is used
        /// to enumerate the items, which uses this method implicitly.</p>
        /// <p>If an item is added to or deleted from the set while it is being enumerated, then 
        /// the enumeration will end with an InvalidOperationException.</p>
        /// <p>Enumeration all the items in the set takes time O(N log N), where N is the number
        /// of items in the set.</p>
        /// </remarks>
        /// <returns>An enumerator for enumerating all the items in the OrderedSet.</returns>		
        public sealed override IEnumerator<T> GetEnumerator()
        {
            return tree.GetEnumerator();
        }

        /// <summary>
        /// Determines if this set contains an item equal to <paramref name="item"/>. The set
        /// is not changed.
        /// </summary>
        /// <remarks>Searching the set for an item takes time O(log N), where N is the number of items in the set.</remarks>
        /// <param name="item">The item to search for.</param>
        /// <returns>True if the set contains <paramref name="item"/>. False if the set does not contain <paramref name="item"/>.</returns>
        public sealed override bool Contains(T item)
        {
            T dummy;
            return tree.Find(item, false, false, out dummy);
        }

        /// <summary>
        /// <para>Determines if this set contains an item equal to <paramref name="item"/>, according to the 
        /// comparison mechanism that was used when the set was created. The set
        /// is not changed.</para>
        /// <para>If the set does contain an item equal to <paramref name="item"/>, then the item from the set is returned.</para>
        /// </summary>
        /// <remarks>Searching the set for an item takes time O(log N), where N is the number of items in the set.</remarks>
        /// <example>
        /// In the following example, the set contains strings which are compared in a case-insensitive manner. 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -