数据结构 C#版 链表 加强版 支持 foreach语句

 
在前面的文章中,向大家展示了C#语言链表的最简单实现.
我们知道在C#语言中有一个循环是其他C风格的语言中没有(最新的java也有了),那就是foreach循环,这种循环是从basic语言中学来的.利用这种循环(使用了iterator模式)我们可以在不知道集合长度的情况下,来对集合中的元素进行遍历,实在是很方便.
可是前面我们作的链表,大家如果使用过的话,会发现它根本就不能使用foreach进行遍历.
那么我们如何才能让这个类支持foreach呢?其实很简单,只要让我们的链表类继承自IEnumerable接口,并对该接口中的GetEnumerator()方法加以实现就可以了.
大家请看下面的代码,是前面我们实现的链表类的加强版,首选让CSArrayList 类继承自 IEnumerable接口,最下边红色的字,是对GetEnumerator()方法加以实现.
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
 
namespace 链表加强版_可以使用foreach语句进遍历_
{
    ///<summary>
    /// 用于表示链表的一个结点
    ///</summary>
    public class CSArrayListNode
    {
        private object element;
        ///<summary>
        /// 当前结点中的元素值
        ///</summary>
        public object Element
        {
            get { return element; }
            set { element = value; }
        }
 
        private CSArrayListNode nextNode;
        ///<summary>
        /// 该结结点的下一个结点的引用
        ///</summary>
        public CSArrayListNode NextNode
        {
            get { return nextNode; }
            set { nextNode = value; }
        }
 
    }
    ///<summary>
    /// 用于表示链表
    ///</summary>
    public class CSArrayList:IEnumerable
    {
        CSArrayListNode firstNode;
        int count; bool isReadOnly = false;
       
        ///<summary>
        /// 获取 CSArrayList 中实际包含的元素数。
        ///</summary>
        public int Count
        {
            get
            {
                return this.count;
            }
        }
 
 
 
        ///<summary>
        /// 将对象添加到 CSArrayList 的结尾处。
        ///</summary>
        ///<param name="Item"> 要添加到 CSArrayList 的末尾处的 Object。该值可以为 空引用. </param>
        public void Add(object Item)
        {
            // 第一次加入元素
            if (this.firstNode == null)
            {
                this.firstNode = new CSArrayListNode();
                this.firstNode.Element = Item;
            }
            // 非第一次加入元素
            else
            {
                CSArrayListNode tmpnode = this.firstNode;
                // 通过循环找到最后一个结点
                while (true)
                {
 
                    // 如果该结点为空,则将新值插入该链表
                    if (tmpnode.NextNode == null)
                    {
                        tmpnode.NextNode = new CSArrayListNode();
                        tmpnode.NextNode.Element = Item;
                        break;
                    }
                    tmpnode = tmpnode.NextNode;
                }
            }
            // 链表长度增加1
            this.count++;
        }
 
        ///<summary>
        /// 从 CSArrayList 中移除所有元素。
        ///</summary>
        public void Clear()
        {
            // 最好将所有结点清空
            this.firstNode = null;
        }
 
        ///<summary>
        /// 确定某元素是否在 CSArrayList 中。
        ///</summary>
        ///<param name="item"> 要在 ArrayList 中查找的 Object。该值可以为 空引用 </param>
        ///<returns> 如果在 CSArrayList 中找到 item,则为 true;否则为 false。 </returns>
        public bool Contains(object item)
        {
            CSArrayListNode tmpnode = this.firstNode;
            while (true)
            {
                if (tmpnode == null)
                {
                    return false;
                }
                if (tmpnode.Element.Equals(item))
                {
                    return true;
                }
                tmpnode = tmpnode.NextNode;
            }
        }
 
        ///<summary>
        /// 搜索指定的 Object,并返回整个 ArrayList 中第一个匹配项的从零开始的索引。
        ///</summary>
        ///<param name="value"> 要在 ArrayList 中查找的 Object。 </param>
        ///<returns> 如果在整个 ArrayList 中找到 value 的第一个匹配项,则为该项的从零开始的索引;否则为 -1。 </returns>
        public int IndexOf(object value)
        {
            CSArrayListNode tmpnode = this.firstNode;
            int index = 0;
            while (true)
            {
                // 如果找到最后一个还找不到,则返回-1
                if (tmpnode == null)
                {
                    return -1;
                }
                // 否则返回索引号
                if (tmpnode.Element.Equals(value))
                {
                    return index;
                }
                tmpnode = tmpnode.NextNode;
                index++;
            }
        }
 
        ///<summary>
        /// 将元素插入 ArrayList 的指定索引处。
        ///</summary>
        ///<param name="index"> 从零开始的索引,应在该位置插入 value。 </param>
        ///<param name="value"> 要插入的 Object。 </param>
        public void Insert(int index, object value)
        {
            // 如果索引号大于该链表的长度,则不作为
            if (index > this.count)
            {
                return;
            }
            // 如果索引号是0,则直接将该值插入第一个结点
            if (index == 0)
            {
                CSArrayListNode node = new CSArrayListNode();
                node.Element = value;
                node.NextNode = this.firstNode;
                this.firstNode = node;
                this.count++;
                return;
 
            }
            CSArrayListNode tmpnode = this.firstNode;
            int index1 = 0;
            while (true)
            {
                if (tmpnode == null)
                {
                    return;
                }
                // 插入新值,这里要注意结点是如何交换的
                //C# 的类名就是引用,这一点类似于C++中的指针
                if (index == (index1 + 1))
                {
                    CSArrayListNode node = new CSArrayListNode();
                    node.Element = value;
                    node.NextNode = tmpnode.NextNode;
                    tmpnode.NextNode = node;
                    this.count++;
                    return;
 
                }
                tmpnode = tmpnode.NextNode;
                index1++;
            }
        }
 
        ///<summary>
        /// 从 ArrayList 中移除特定对象的第一个匹配项。
        ///</summary>
        ///<param name="value"> 要从 ArrayList 移除的 Object。 </param>
        public void Remove(object value)
        {
 
            if (this.firstNode.Element.Equals(value))
            {
                this.firstNode = this.firstNode.NextNode;
                this.count--;
                return;
            }
            int index = 0;
            CSArrayListNode tmpnode = this.firstNode;
            while (true)
            {
                if (tmpnode.NextNode == null)
                {
                    return;
                }
                if (tmpnode.NextNode.Element.Equals(value))
                {
                    tmpnode.NextNode = tmpnode.NextNode.NextNode;
                    this.count--;
                    return;
                }
                tmpnode = tmpnode.NextNode;
                index++;
            }
        }
 
        ///<summary>
        /// 移除 ArrayList 的指定索引处的元素。
        ///</summary>
        ///<param name="index"> 要移除的元素的从零开始的索引。 </param>
        public void RemoveAt(int index)
        {
            if (index > this.count)
            {
                return;
            }
            if (index == 0)
            {
                this.firstNode = this.firstNode.NextNode;
                this.count--;
                return;
            }
            int index1 = 0;
            CSArrayListNode tmpnode = this.firstNode;
            while (true)
            {
                if (index1 == (this.count - 1))
                {
                    return;
                }
                if (index == (index1 + 1))
                {
                    tmpnode.NextNode = tmpnode.NextNode.NextNode;
                    this.count--;
                    return;
                }
                tmpnode = tmpnode.NextNode;
                index1++;
            }
        }
 
        public object this[int index]
        {
            get
            {
                if (index > this.count - 1)
                {
                    return null;
                }
                CSArrayListNode tmpnode = this.firstNode;
                for (int i = 0; i < index; i++)
                {
                    tmpnode = tmpnode.NextNode;
                }
                return tmpnode.Element;
            }
            set
            {
                if (index > this.count - 1)
                {
                    return;
                }
                CSArrayListNode tmpnode = this.firstNode;
                for (int i = 0; i < index; i++)
                {
                    tmpnode.NextNode = tmpnode.NextNode;
                }
                tmpnode.Element = value;
            }
        }
 
        #region IEnumerable 成员
         // 大家这里要注意yield return语句后的this[i]实际上 CSArrayList 类的索引器
        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < this.count ; i++)
            {
                yield return this[i];
            }
        }
 
        #endregion
    }
}
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值