代码改变世界

C# 实现一个单向链表

2011-06-26 15:10  音乐让我说  阅读(462)  评论(0编辑  收藏  举报

链表就是通过地址来将某个数据的下一个数据关联起来的一种数据结构。
在每个数据后面附带一个指针,这个指针里面存放的是下一个数据的地址,依次类推形成了单链表结构。
同样一个数据后跟两个指针,一个存放他前面一个数据的地址,一个存放后面数据的地址。这样就形成了双向链表。
什么时候用到呢?
假如说你要将(34,56,3,54,2,6,12......)这样的一组数据存储到计算机里面,而且还要求把他们之间的关系,也就是34,56。。。。这样的顺序关系存储到计算机中的话就要用到链表。当然他的作用并不止如此。

下面是代码实现:

节点类:

public class Node<T>
   {
       /// <summary>
       /// 数据
       /// </summary>
       public T NodeData
       {
           get;
           set;
       }

       /// <summary>
       /// 指向下一个节点
       /// </summary>
       public Node<T> Next
       {
           get;
           set;
       }
   }

链表类:

public class SingleList<T>
  {
     private Node<T> _first;//头节点
      private Node<T> _last;//尾节点
      private int _length;//链表长度

      /// <summary>
      /// 头节点
      /// </summary>
      public T First 
      {
          get { return _first.NodeData; }
      }

      /// <summary>
      /// 尾节点
      /// </summary>
      public T Last 
      { 
          get{ return _last.NodeData; }
      }

      /// <summary>
      /// 链表长度
      /// </summary>
      public int Length 
      {
          get { return _length; }
      }

      /// <summary>
      /// 链表是否为空
      /// </summary>
      public bool IsEmpty
      {
          get { return _first == null; }
      }

      /// <summary>
      /// 清空链表
      /// </summary>
      public void Clear()
      {
          _first = null;
      }

      /// <summary>
      /// 追加一个节点
      /// </summary>
      /// <param name="item"></param>
      public void Append(T item)
      {
          Node<T> newNode = new Node<T>();
          newNode.NodeData = item;

          if (_first == null)
          {
              _first = _last = newNode;
          }
          else
          {
              _last.Next = newNode;
              _last = newNode;
          }
          _length++;
      }

      /// <summary>
      /// 在指定位置插入节点
      /// </summary>
      /// <param name="item"></param>
      /// <param name="location"></param>
      public void Insert(T item, int location)
      {
          Node<T> tempNodePre;//前一个节点
          Node<T> tempNodeNex;//后一个节点
          Node<T> newNode = new Node<T>();//待插入新节点

          newNode.NodeData = item;

          if (this.IsEmpty)//链表为空:不能进行插入操作
          {
              throw new Exception("链表为空");
          }

          if (location == 0)//在链表头插入
          {
              tempNodeNex = _first;
              _first = newNode;
              newNode.Next = tempNodeNex;
              _length++;
              return;
          }

          if (location == _length - 1)//在链表尾插入
          {
              _last.Next = newNode;
              _last = newNode;
              _length++;
              return;
          }

          //*********其它位置***********************//
          tempNodePre = this.FindNode(location - 1);
          if (tempNodePre == null)
          {
              throw new Exception("位置无效");
          }
          tempNodeNex = tempNodePre.Next;
          tempNodePre.Next = newNode;
          newNode.Next = tempNodeNex;
          _length++;
      }

      /// <summary>
      /// 删除指定位置的节点
      /// </summary>
      /// <param name="location"></param>
      /// <returns>删除的数据</returns>
      public T Delete(int location)
      {
          T deleteData;
          Node<T> tempNodeDel;//待删除节点
          Node<T> tempNodePre;//前一个节点
          Node<T> tempNodeNex;//后一个节点

          if (this.IsEmpty)
          {
              throw new Exception("链表为空,不能删除节点");
          }
          if (location == 0)//删除头节点
          {
              deleteData = _first.NodeData;
              _first = _first.Next;
              _length--;
              return deleteData;
          }
          if (location == _length - 1)//删除尾节点
          {
              tempNodeDel = _last;
              _last = this.FindNode(location - 1);
              _last.Next = null;
              _length--;
              return tempNodeDel.NodeData;
          }
          //*********其它位置***********************//
          tempNodePre = this.FindNode(location - 1);
          if (tempNodePre == null)
          {
              throw new Exception("无效位置");
          }
          tempNodeDel = tempNodePre.Next;
          tempNodeNex = tempNodeDel.Next;
          tempNodePre.Next = tempNodeNex;
          _length--;
          return tempNodeDel.NodeData;
      }

      /// <summary>
      /// 根据索引查找值
      /// </summary>
      /// <param name="index"></param>
      /// <returns></returns>
      public T Find(int index)
      {
          if (this.IsEmpty)
          {
              throw new Exception("链表为空");
          }
          Node<T> find = this.FindNode(index);
          if (find == null)
          {
              return default(T);
          }
          return this.FindNode(index).NodeData;
      }

      /// <summary>
      /// 根据索引查找值
      /// </summary>
      /// <param name="item"></param>
      /// <returns>没有找到时返回-1</returns>
      public int Find(T item)
      {
          if (this.IsEmpty)
          {
              throw new Exception("链表为空");
          }
          int index = 0;
          int result=-1;
          Node<T> temp = _first;
          while (index < _length)
          {
              if (temp.NodeData.Equals(item))
              {
                  result = index;
                  break;
              }
              temp = temp.Next;
              index++;
          }
          return result;
      }

      /// <summary>
      /// 翻转链表
      /// </summary>
      public void Reverses()
      {
          if (this.IsEmpty)
          {
              return;
          }
          Node<T> temp = _first.Next;
          Node<T> nextNode;
          Node<T> currentNode = _first;
          while (temp != null)
          {
              nextNode = temp.Next;
              temp.Next = currentNode;
              currentNode = temp;
              temp = nextNode;
          }
          Node<T> tempFirst = _first;
          _first = _last;
          _last = tempFirst;
      }

      /// <summary>
      /// 根据索引找到节点
      /// </summary>
      /// <param name="index"></param>
      /// <returns></returns>
      private Node<T> FindNode(int index)
      {
          if (index < 0 || index >= _length)
          {
              return null;
          }
          int i = 0;
          Node<T> tempNode = _first; 
          while (i < index)
          {
              tempNode = tempNode.Next;
              i++;
          }
          return tempNode;
      }
  }

谢谢浏览!