飘遥的Blog

C/C++/.NET
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据结构(C#):单链表

Posted on 2008-12-06 15:43  Zzx飘遥  阅读(572)  评论(4编辑  收藏  举报
与顺序表相比,链表有自己的特点:插入、删除操作无需移动元素;能够高效实现动态内存分配;但不能按节点索引快速定位到节点;由于需要记录指针域,系统开销较大。

本篇介绍单链表的实现,使用上一篇定义的接口。
代码:
/*
* File     :   SingleLinkedList.cs
* Author   :   Zhenxing Zhou
* Date     :   2008-12-06
* Blog     :  
http://www.xianfen.net/
*/
using System;
using System.Collections;
using System.Collections.Generic;

namespace Xianfen.Net.DataStructure
{
    
// 定义节点
    internal class SingleLinkedListNode<T>
    {
        
private T m_Value;
        
private SingleLinkedListNode<T> m_Next;

        
public T Value
        {
            
get { return m_Value; }
            
set { m_Value = value; }
        }

        
public SingleLinkedListNode<T> Next
        {
            
get { return m_Next; }
            
set { m_Next = value; }
        }

        
public SingleLinkedListNode()
        {
            m_Next
= null;
        }

        
public SingleLinkedListNode(T t)
            :
this()
        {
            Value
= t;
        }
    }

    
// 实现单链表
    public class SingleLinkedList<T> : ILinearList<T>
    {
        
private int m_Count;
        
private SingleLinkedListNode<T> m_Head;

        
public SingleLinkedList()
        {
            m_Count
= 0;
            m_Head
= new SingleLinkedListNode<T>();
        }

        
public SingleLinkedList(T t)
            :
this()
        {
            m_Count
= 1;
            m_Head.Next
= new SingleLinkedListNode<T>(t);
        }

        
public bool IsEmpty
        {
            
get { return m_Count == 0; }
        }

        
public int Count
        {
            
get { return m_Count; }
        }

        
public void Add(T t)
        {
            InsertAt(t,
this.Count);
        }

        
public void AddHead(T t)
        {
            InsertAt(t,
0);
        }

        
public void AddTail(T t)
        {
            Add(t);
        }

        
public void InsertAt(T t, int pos)
        {
            
if (pos > this.Count || pos < 0)
            {
                
throw new IndexOutOfRangeException("pos");
            }

            
if (m_Count == int.MaxValue)
            {
                
throw new ArithmeticException();
            }

            SingleLinkedListNode
<T> currentNode = m_Head;

            
while (pos-- > 0)
            {
                currentNode
= currentNode.Next;
            }

            SingleLinkedListNode
<T> tempNode = new SingleLinkedListNode<T>(t);

            tempNode.Next
= currentNode.Next;
            currentNode.Next
= tempNode;
            m_Count
++;
        }

        
public void RemoveTail()
        {
            RemoveAt(
this.Count - 1);
        }

        
public void RemoveHead()
        {
            RemoveAt(
0);
        }

        
public void RemoveAt(int pos)
        {
            
if (pos >= Count || pos < 0)
            {
                
throw new IndexOutOfRangeException("pos");
            }

            SingleLinkedListNode
<T> currentNode = m_Head;

            
while (pos-- > 0)
            {
                currentNode
= currentNode.Next;
            }

            currentNode.Next
= currentNode.Next.Next;
            m_Count
--;
        }

        
public void RemoveAll()
        {
            m_Head.Next
= null;
            m_Count
= 0;
        }

        
public void Clear()
        {
            RemoveAll();
        }

        
public T GetHead()
        {
            
return GetAt(0);
        }

        
public T GetTail()
        {
            
return GetAt(this.Count - 1);
        }

        
public T GetAt(int pos)
        {
            
return GetNodeAt(pos).Value;
        }

        
private SingleLinkedListNode<T> GetNodeAt(int pos)
        {
            
if (pos >= Count || pos < 0)
            {
                
throw new IndexOutOfRangeException("pos");
            }

            SingleLinkedListNode
<T> currentNode = m_Head;

            
while (pos-- > 0)
            {
                currentNode
= currentNode.Next;
            }

            
return currentNode.Next;
        }

        
public void SetAt(int pos, T t)
        {
            GetNodeAt(pos).Value
= t;
        }

        
public int Find(T t)
        {
            SingleLinkedListNode
<T> node = m_Head;
            
int pos = 0;

            
while ((node = node.Next) != null)
            {
                
if (node.Value.Equals(t))
                {
                    
return pos;
                }

                pos
++;
            }

            
return -1;
        }

        
public IEnumerator<T> GetEnumerator()
        {
            SingleLinkedListNode
<T> node = m_Head;

            
while ((node = node.Next) != null)
            {
                
yield return node.Value;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            
return GetEnumerator();
        }
    }
}

如果发现BUG请留言指出,下一篇介绍双链表的实现。