C# 实现栈(链表与数组实现)

1.首先是数组实现方式

接口代码:

internal interface IArrayStack<T>
    {
        /// <summary>
        /// 向栈顶压入数据
        /// </summary>
        /// <param name="value">值</param>
        void Push(T value);
        /// <summary>
        /// 弹出栈顶数据
        /// </summary>
        void Pop();
        /// <summary>
        /// 查看栈顶数据,但不弹出
        /// </summary>
        /// <returns></returns>
        T Peek();
        /// <summary>
        /// 栈是否为空
        /// </summary>
        /// <returns></returns>
        bool IsEmpty();
        /// <summary>
        /// 转数组
        /// </summary>
        /// <returns></returns>
        T[] ToArray();
        /// <summary>
        /// 清除所有值
        /// </summary>
        void Clear();
        /// <summary>
        /// 是否存在元素
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        bool Contains(T item);
        /// <summary>
        /// 容量
        /// </summary>
        int Capacity { get; }
        /// <summary>
        /// 有效数量
        /// </summary>
        int Count { get; }
        /// <summary>
        /// 压缩容器(默认0.5)
        /// </summary>
        /// <param name="mul">范围[0,1]</param>
        void CompressedContainer(float mul=0.5f);
    }

接着看实现类:

/// <summary>
    /// 栈---数组实现
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal class ArrayStack<T> : IArrayStack<T>
    {
        private T[] _stack;
        public int Capacity { get; private set; }

        public int Count { get { return _top + 1; } private set { Count = value; } }

        private int _top = -1;
        private int _maxCapacity;

        public ArrayStack()
        {

        }
        public ArrayStack(int capacity)
        {
            if (capacity < 0)
                throw new ArgumentOutOfRangeException(nameof(capacity));
            _stack = new T[capacity];
            Capacity = capacity;
            _maxCapacity = capacity;
        }

        public void Clear()
        {
            Capacity = 0;
            Count = 0;
            _top = -1;
            _stack = null;
        }

        public bool Contains(T item)
        {
            foreach (T item2 in _stack)
            {
                if (item2.Equals(item))
                    return true;
            }
            return false;
        }

        public bool IsEmpty()
        {
            return _top == -1;
        }

        public T Peek()
        {
            if (IsEmpty())
                return default(T);
            return _stack[0];
        }

        public void Pop()
        {
            if (IsEmpty())
                return;
            int count = _top;
            for (int i = 0; i < count; i++)
            {
                (_stack[i], _stack[i + 1]) = (_stack[i + 1], _stack[i]);
            }
            --_top;
        }

        public void Push(T value)
        {
            int count = Count;  
            if (_maxCapacity==0)
            {
                if (count == Capacity)
                {
                    T[] tempStack = null;
                    if (Capacity == 0)
                    {
                        Capacity = 4;
                        tempStack = new T[Capacity];
                        _stack = tempStack;
                    }
                    else
                    {
                        Capacity <<= 1;
                        if (Capacity > Array.MaxLength) 
                            Capacity = Array.MaxLength;
                        tempStack = new T[Capacity];
                        Array.Copy(_stack, tempStack, count);
                        _stack = null;
                        _stack = tempStack;
                    }
                    tempStack = null;
                }
            }
            else
            {
                if(count >= _maxCapacity)
                    Pop();
            }
            _stack[++_top] = value;
        }

        public T[] ToArray()
        {
            int count = Count;
            T[] tempStack = new T[count];
            Array.Copy(_stack, tempStack, count);
            return tempStack;
        }
        public override string ToString()
        {
            return String.Join(',', ToArray());
        }

        public void CompressedContainer(float mul = 0.5f)
        {
            int count = Count;
            // 压缩
            if (Capacity-count>= count*mul)
            {
                T[] tempStack = new T[count];
                Array.Copy(_stack, tempStack, count);
                _stack = null;
                _stack = tempStack;
                tempStack = null;
            }
        }
    }

2.链表实现方式

首先看接口:

 /// <summary>
    /// 自定义栈
    /// </summary>
    internal interface ILinkedStack<T>
    {
        /// <summary>
        /// 向栈顶压入数据
        /// </summary>
        /// <param name="value">值</param>
        void Push(T value);
        /// <summary>
        /// 向栈顶压入数据
        /// </summary>
        /// <param name="value">值</param>
        void Push(SingleLinkedNode<T> value);
        /// <summary>
        /// 弹出栈顶数据
        /// </summary>
        void Pop();
        /// <summary>
        /// 查看栈顶数据,但不弹出
        /// </summary>
        /// <returns></returns>
        T Peek();
        /// <summary>
        /// 栈是否为空
        /// </summary>
        /// <returns></returns>
        bool IsEmpty();
        /// <summary>
        /// 转数组
        /// </summary>
        /// <returns></returns>
        T[] ToArray();
        /// <summary>
        /// 清除所有值
        /// </summary>
        void Clear();
        /// <summary>
        /// 是否存在元素
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        bool Contains(T item);
        /// <summary>
        /// 有效数量
        /// </summary>
        int Count { get; }
    }

接着看实现类:

/// <summary>
    /// 链表实现栈---头插入法
    /// 主要思路:
    /// 头插入法:每次插入值的Next都指向之前的头地址,例如人newNode.Next = oldNode.Next;移除时每次要移动到链表尾部前一个,使其Next=null。
    /// 尾插入法:与头插入法相反
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal class LinkedStack<T> : ILinkedStack<T>
    {
        /// <summary>
        /// 栈顶
        /// </summary>
        public SingleLinkedNode<T> Top { get; private set; }
        /// <summary>
        /// 数量
        /// </summary>
        public int Count { get; private set; }

        public LinkedStack()
        {

        }

        public LinkedStack(IEnumerable<T> values)
        {
            if (values != null)
            {
                int tempCount = values.Count();
                Count += tempCount;
                if (tempCount > 0)
                {
                    SingleLinkedNode<T> tempTop = new SingleLinkedNode<T>(values.First());
                    --tempCount;
                    for (int i = 1; i < tempCount; i++)
                    {
                        var tempValue = new SingleLinkedNode<T>(values.ElementAt(i));
                        tempValue.Next = tempTop;
                        tempTop = tempValue;
                    }
                    if (IsEmpty())
                        Top = tempTop;
                    else
                    {
                        tempTop.Next = Top;
                        Top = tempTop;
                    }
                }
            }
        }

        public void Clear()
        {
            Top = null;
            Count = 0;
        }

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

        public bool IsEmpty()
        {
            return Count == 0;
        }

        public T Peek()
        {
            if (IsEmpty())
                throw new Exception("栈空");
            return Top.Data;
        }

        public void Pop()
        {
            if (IsEmpty())
                return;
            SingleLinkedNode<T> tempNode = Top;
            int tempCount = Count - 2;
            for (int i = 0; i < tempCount; i++)
            {
                tempNode = tempNode.Next;
            }
            tempNode.Next = null;
            --Count;
        }

        public void Push(T value)
        {
            SingleLinkedNode<T> valueNode = new SingleLinkedNode<T>(value);
            if (IsEmpty())
                Top = valueNode;
            else
            {
                SingleLinkedNode<T> tempNode = Top;
                valueNode.Next = tempNode;
                Top = valueNode;
            }
            ++Count;
        }

        public void Push(SingleLinkedNode<T> value)
        {
            SingleLinkedNode<T> valueNode = value.DeepClone<T>();
            if (IsEmpty())
                Top = valueNode;
            else
            {
                SingleLinkedNode<T> tempNode = Top;
                valueNode.Next = tempNode;
                Top = valueNode;
            }
            ++Count;
        }

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

        public override string ToString()
        {
            return Top.ToString();
        }
    }

注:链表节点

 [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();
        }
    }

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值