warensoft 我是科学家

Warensoft 我是科学家

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在前面的文章中,向大家展示了C#语言链表的最简单实现.

我们知道在C#语言中有一个循环是其他C风格的语言中没有(最新的java也有了),那就是foreach循环,这种循环是从basic语言中学来的.利用这种循环(使用了iterator模式)我们可以在不知道集合长度的情况下,来对集合中的元素进行遍历,实在是很方便.

可是前面我们作的链表,大家如果使用过的话,会发现它根本就不能使用foreach进行遍历.

那么我们如何才能让这个类支持foreach呢?其实很简单,只要让我们的链表类继承自IEnumerable接口,并对该接口中的GetEnumerator()方法加以实现就可以了.

大家请看下面的代码,是前面我们实现的链表类的加强版,首选让CSArrayList 类继承自 IEnumerable接口,最下边红色的字,是对GetEnumerator()方法加以实现.

 

大家如果有什么问题,可以给我发Email: warensoft@163.com

 

代码
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

}

}

 

 

 

posted on 2010-07-29 23:01  王宇 warensoft  阅读(776)  评论(2编辑  收藏  举报