C# 单向链表简单业务实现

首先看链表节点SingleLinkedNode<T>


    [Serializable]
    public class SingleLinkedNode<T> : ICloneable
    {
        public T Data { get; set; }
        public SingleLinkedNode<T> Next { get; set; }
        public SingleLinkedNode()
        {
            Data = default(T);
            Next = null;
        }
        public SingleLinkedNode(T data)
        {
            Data = data;
            Next = null;
        }
        public SingleLinkedNode(T data, SingleLinkedNode<T> node)
        {
            Data = data;
            Next = node;
        }
        /// <summary>
        /// 浅克隆
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        /// <summary>
        /// 深克隆
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public SingleLinkedNode<T> DeepClone<T>()
        {
            object obj = null;
            // 将对象序列化成内存中的二进制流
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            using MemoryStream memoryStream = new MemoryStream();
            binaryFormatter.Serialize(memoryStream, this);
            // 将二进制流反序列成对象
            using MemoryStream memoryStream2 = new MemoryStream(memoryStream.ToArray());
            BinaryFormatter binaryFormatter2 = new BinaryFormatter();
            obj = binaryFormatter2.Deserialize(memoryStream2);
            
            return (SingleLinkedNode<T>)obj;
        }
        public override bool Equals(object? obj)
        {
            // 判断是否为引用相等
            if (ReferenceEquals(this, obj))
                return true;
            if (obj == null || this == null)
                return false;
            SingleLinkedNode<T> tempNode = obj as SingleLinkedNode<T>;
            if (tempNode == null)
                return false;
            return this.GetHashCode() == tempNode.GetHashCode();
        }
        public override int GetHashCode()
        {
            return (this.Data, this.Next).GetHashCode();
        }
        public static bool operator == (SingleLinkedNode<T> first, SingleLinkedNode<T> second)
        {
            // 判断是否为引用相等
            if (ReferenceEquals(first, second))
                return true;
            return first.Equals(second);
        }
        public static bool operator !=(SingleLinkedNode<T> first, SingleLinkedNode<T> second)
        {
            // 判断是否为引用相等
            if (ReferenceEquals(first, second))
                return false;
            return !first.Equals(second);
        }
        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendLine(this.Data?.ToString());
            SingleLinkedNode<T> tempNode = this.Next;
            while (tempNode != null)
            {
                stringBuilder.AppendLine(tempNode.Data.ToString());
                tempNode = tempNode.Next;
            }
            string ads=stringBuilder.ToString();
            return stringBuilder.ToString();
        }
    }

类上面加上 [Serializable]的目的是为了后面的深克隆 。

接着看单链表接口方法:

 /// <summary>
    /// 单向链表
    /// </summary>
    public interface ISingleLinked<T>
    {
        /// <summary>
        /// 第一个节点
        /// </summary>
        SingleLinkedNode<T> First { get; }

        /// <summary>
        /// 最后一个节点
        /// </summary>
        SingleLinkedNode<T> Last { get; }

        /// <summary>
        /// 链表数量
        /// </summary>
        int Count { get; }

        /// <summary>
        /// 链表是否为空
        /// </summary>
        bool IsEmpty { get; }

        /// <summary>
        /// 清空链表
        /// </summary>
        void Clear();

        /// <summary>
        /// 链表中是否包含该数据(对象比较必须重写Equals)
        /// </summary>
        /// <param name="value">验证数据项</param>
        /// <returns></returns>
        bool Contains(T value);

        /// <summary>
        /// 添加一个节点到节点起点
        /// </summary>
        /// <param name="value">节点数据</param>
        /// <returns>返回Node节点</returns>
        SingleLinkedNode<T> AddFirst(T value);

        /// <summary>
        /// 添加一个节点到节点起点
        /// </summary>
        /// <param name="node">需要添加的节点</param>
        /// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
        SingleLinkedNode<T> AddFirst(SingleLinkedNode<T> node);

        /// <summary>
        /// 添加一个节点到链表最后
        /// </summary>
        /// <param name="value">节点数据</param>
        /// <returns>节点</returns>
        SingleLinkedNode<T> AddLast(T value);

        ///<summary>
        /// 添加一个节点到链表最后
        /// </summary>
        /// <param name="node">需要添加的节点</param>
        /// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
        SingleLinkedNode<T> AddLast(SingleLinkedNode<T> node);

        /// <summary>
        /// 插入一个节点到指定的下标出
        /// </summary>
        /// <param name="value">节点数据</param>
        /// <param name="index">插入下标</param>
        /// <returns>新增节点</returns>
        SingleLinkedNode<T> Insert(T value, int index);

        /// <summary>
        /// 插入一个节点到指定的下标出
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="index">插入下标</param>
        /// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
        SingleLinkedNode<T> Insert(SingleLinkedNode<T> node, int index);

        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="value">数据</param>
        /// <returns>是否删除成功</returns>
        bool Delete(T value);

        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="index">删除的节点下标</param>
        /// <returns>是否删除成功</returns>
        bool DeleteAt(int index);

        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="index">删除的节点</param>
        /// <returns>是否删除成功</returns>
        bool Delete(SingleLinkedNode<T> node);

        /// <summary>
        /// 删除第一个节点
        /// </summary>
        /// <returns>是否删除成功</returns>
        bool DeleteFirst();

        /// <summary>
        /// 删除最后一个节点
        /// </summary>
        /// <returns>是否删除成功</returns>
        bool DeleteLast();

        /// <summary>
        /// 根据数据查找节点
        /// </summary>
        /// <param name="value">数据</param>
        /// <returns>节点</returns>
        SingleLinkedNode<T> Find(T value);

        /// <summary>
        /// 根据数据查找节点
        /// </summary>
        /// <param name="value">数据</param>
        /// <returns>节点</returns>
        SingleLinkedNode<T> Find(Func<SingleLinkedNode<T>, bool> func);

        /// <summary>
        /// 根据数据查找上一个节点
        /// </summary>
        /// <param name="value">数据</param>
        /// <returns>节点</returns>
        SingleLinkedNode<T> FindPrevious(T value);

        /// <summary>
        /// 索引器取数据
        /// </summary>
        /// <param name="index">下标</param>
        /// <returns></returns>
        T this[int index] { get; }

        /// <summary>
        /// 根据下标取数据
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        T GetElement(int index);

        /// <summary>
        /// 根据数据获取下标
        /// </summary>
        /// <param name="value">数据</param>
        /// <returns>数据节点下标</returns>
        int IndexOf(T value);
        /// <summary>
        /// 转数组
        /// </summary>
        /// <returns></returns>
        T[] ToArray();
    }

最后看具体实现:

/// <summary>
    /// 单向链表
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SingleLinked<T> : ISingleLinked<T>
    {
        /// <summary>
        /// 头节点
        /// </summary>
        private SingleLinkedNode<T> _first = null;
        /// <summary>
        /// 尾节点
        /// </summary>
        private SingleLinkedNode<T> _last = null;

        public T this[int index]
        {
            get
            {
                if (index >= Count || index < 0)
                    return default(T);

                var tempNode = _first;
                for (int i = 0; i < index; i++)
                {
                    tempNode = tempNode.Next;
                }
                return tempNode.Data;
            }
        }

        public SingleLinkedNode<T> First => _first;

        public SingleLinkedNode<T> Last => _last;

        public int Count
        {
            get
            {
                int tempCount = 0;
                SingleLinkedNode<T> tempNode = _first;
                while (tempNode != null)
                {
                    tempCount++;
                    tempNode = tempNode.Next;
                }
                return tempCount;
            }
        }

        public bool IsEmpty => _first == null;

        public SingleLinkedNode<T> AddFirst(T value)
        {
            var tempNode = new SingleLinkedNode<T>(value);
            if (_first == null)
                (_first, _last) = (tempNode, tempNode);
            else
            {
                tempNode.Next = _first;
                _first = tempNode;
            }
            return tempNode;
        }

        public SingleLinkedNode<T> AddFirst(SingleLinkedNode<T> node)
        {
            SingleLinkedNode<T> tempNode = node.DeepClone<T>();
            tempNode.Next = null;
            if (_first == null)
                (_first, _last) = (node, node);
            else
            {
                node.Next = _first;
                _first = node;
            }
            return tempNode;
        }

        public SingleLinkedNode<T> AddLast(T value)
        {
            var tempNode = new SingleLinkedNode<T>(value);
            if(_first==null)
                (_first, _last) = (tempNode, tempNode);
            else
                (_last.Next, _last) = (tempNode, tempNode);

            return tempNode;
        }

        public SingleLinkedNode<T> AddLast(SingleLinkedNode<T> node)
        {
            SingleLinkedNode<T> tempNode = node.DeepClone<T>();
            tempNode.Next = null;
            if (_first == null)
                (_first, _last) = (tempNode, tempNode);
            else
                (_last.Next, _last) = (tempNode, tempNode);

            return tempNode;
        }

        public void Clear()
        {
            (_first, _last) = (null, null);
        }

        public bool Contains(T value)
        {
            SingleLinkedNode<T> tempNode = _first;
            while (tempNode != null)
            {
                if (tempNode.Data.Equals(value))
                    return true;
                tempNode = tempNode.Next;
            }
            return false;
        }

        public bool Delete(T value)
        {
            if (_first == null)
                return false;
            SingleLinkedNode<T> tempNode = _first;
            if (tempNode.Data.Equals(value))
            {
                _first = _first.Next;
                return true;
            }
            SingleLinkedNode<T> tempPrevious = null;
            while (tempNode.Next != null)
            {
                tempPrevious = tempNode;
                tempNode = tempNode.Next;
                if (tempNode.Data.Equals(value))
                {
                    tempPrevious.Next = tempNode.Next;
                    return true;
                }
            }
            return false;
        }

        public bool Delete(SingleLinkedNode<T> node)
        {
            if (_first == null)
                return false;
            SingleLinkedNode<T> tempNode = _first;
            if (tempNode.Equals(node))
            {
                _first = _first.Next;
                return true;
            }
            SingleLinkedNode<T> tempPrevious = null;
            while (tempNode.Next != null)
            {
                tempPrevious = tempNode;
                tempNode = tempNode.Next;
                if (tempNode.Equals(node))
                {
                    tempPrevious.Next = tempNode.Next;
                    return true;
                }
            }
            return false;
        }

        public bool DeleteAt(int index)
        {
            if (index < 0 || index >= Count)
                return false;
            if (index == 0)
            {
                _first = _first.Next;
                return true;
            }
            SingleLinkedNode<T> tempNode = _first;
            for (int i = 0; i < index - 1; i++)
            {
                tempNode = tempNode.Next;
            }
            tempNode.Next = tempNode.Next.Next;
            return true;
        }

        public bool DeleteFirst()
        {
            if (_first == null)
                return false;
            _first = _first.Next;
            return true;
        }

        public bool DeleteLast()
        {
            if (_first == null)
                return false;
            if(_first.Equals(_last))
                (_first, _last) = (null, null);
            SingleLinkedNode<T> tempNode = _first;
            SingleLinkedNode<T> tempPrevious = null;
            while (tempNode.Next != null)
            {
                tempPrevious = tempNode;
                tempNode = tempNode.Next;
            }
            tempPrevious.Next = null;
            _last = tempPrevious;
            return true;
        }

        public SingleLinkedNode<T> Find(T value)
        {
            if (_first == null)
                return _first;

            SingleLinkedNode<T> tempNode = _first;
            if (tempNode.Data.Equals(value))
                return tempNode;
            while (tempNode != null)
            {
                if (tempNode.Data.Equals(value))
                    return tempNode;
                tempNode = tempNode.Next;
            }
            return null;
        }

        public SingleLinkedNode<T> Find(Func<SingleLinkedNode<T>, bool> func)
        {
            if (_first == null)
                return _first;
            SingleLinkedNode<T> tempNode = _first;
            if (func(tempNode))
                return tempNode;
            while (tempNode != null)
            {
                if (func(tempNode))
                    return tempNode;
                tempNode = tempNode.Next;
            }
            return null;
        }

        public SingleLinkedNode<T> FindPrevious(T value)
        {
            if (this._first == null)
                return null ;
            SingleLinkedNode<T> tempNode = _first;
            if (tempNode.Data.Equals(value))
                return null;
            SingleLinkedNode<T> tempPrevious = null;
            while (tempNode.Next!=null)
            {
                tempPrevious = tempNode;
                tempNode = tempNode.Next;
                if (tempNode.Data.Equals(value))
                    return tempPrevious;
            }
            return null;
        }

        public T GetElement(int index)
        {
            if (index < 0 || index >= Count)
                return default(T);
            if (index == 0)
                return _first.Data;
            SingleLinkedNode<T> tempNode = _first;
            for (int i = 0; i < index; i++)
            {
                tempNode = tempNode.Next;
            }
            return tempNode.Data;
        }

        public int IndexOf(T value)
        {
            int tempIndex = 0;
            SingleLinkedNode<T> tempNode = _first;
            while (tempNode != null)
            {
                if (tempNode.Data.Equals(value))
                {
                    return tempIndex;
                }
                tempNode = tempNode.Next;
                tempIndex++;
            }
            return -1;
        }

        public SingleLinkedNode<T> Insert(T value, int index)
        {
            if (index < 0 || index > Count)
                return null;
            if(index==0)
                return AddFirst(value);
            else if(index==Count)
                return AddLast(value);
            else
            {
                if (_first == null)
                    return null;
                SingleLinkedNode<T> tempNode = _first;
                for (int i = 0; i < index - 1; i++)
                {
                    tempNode = tempNode.Next;
                }
                SingleLinkedNode<T> newNode = new SingleLinkedNode<T>(value,tempNode.Next);
                tempNode.Next = newNode;
                return newNode;
            }
        }

        public SingleLinkedNode<T> Insert(SingleLinkedNode<T> node, int index)
        {
            if (index < 0 || index > Count)
                return null;
            if (index == 0)
                return AddFirst(node);
            else if (index == Count)
                return AddLast(node);
            else
            {
                if (_first == null)
                    return null;
                SingleLinkedNode<T> tempNode = _first;
                for (int i = 0; i < index - 1; i++)
                {
                    tempNode = tempNode.Next;
                }
                SingleLinkedNode<T> newNode = node.DeepClone<T>();
                newNode.Next = tempNode.Next;
                tempNode.Next = newNode;
                return newNode;
            }
        }

        public T[] ToArray()
        {
            T[] array = new T[this.Count];
            SingleLinkedNode<T> tempNode = _first;
            int index = 0;
            while(tempNode!=null)
            {
                array[index++] = tempNode.Data;
                tempNode = tempNode.Next;
            }
            return array;
        }

        public override string ToString()
        {
            return this._first.ToString();
        }
    }

 若有错误欢迎指正,需要实现其它功能欢迎留言.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值