C#链表栈的底层实现

和之前文章数组栈类似。
1.定义栈接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 数组栈
{
   public interface IStack<E>
    {
        //栈中元素数量
         int Count { get;  }

        //是否为空
        bool IsEmpty { get; }

        //添加
        void Push(E e);

        //删除
        E Pop();

        //查找
        E Peek();
    }
}

2.实现接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 数组栈;
using 链表;

namespace 链表栈
{
    class LinkedList1Stack<E> : IStack<E>
    {

        private LinkedList1<E> list;
        public LinkedList1Stack()
        {
            list = new LinkedList1<E>();
        }
        public int Count { get { return list.Count; } }
        

        public bool IsEmpty { get { return list.IsEmpty; } }

        public E Peek()
        {
            return list.GetFirst();
        }

        public E Pop()
        {
            return list.RemoveFirst();
        }

        public void Push(E e)
        {
            list.AddFirst(e);
        }

        public override string ToString()
        {
            return "Stack:top"+list.ToString();
        }
    }
}

这里给出链表底层实现的代码,之前文章有提到,我直接用呢

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 链表
{
   public class LinkedList1<E>
    {

        //如果嵌套类  最好设为私有  (内部类)节点类
        private class Node
        {
            public E e;   //节点存储的元素
            public Node next;  //下一个节点的引用(指针)

            public Node(E e, Node next)
            {
                this.e = e;
                this.next = next;
            }

            public Node(E e)
            {
                this.e = e;
                this.next = null; 
            }

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

        }

        private Node head;  //节点头部

        private int N; //链表中有多少元素

        public LinkedList1()
        {
            head = null;
            N = 0;
        }

        //链表中有多少元素
        public int Count
        { get { return N; } }


        //链表是否为空
        public bool IsEmpty
        { get { return N==0; } }

        //为链表添加元素
        public void Add(int index, E e)
        {
            if (index < 0 || index > N)
                throw new ArgumentNullException("非法索引");
            //如果给链表头部添加元素
            if (index == 0)
            {
                //Node node = new Node(e);
                //node.next = head;
                //head = node;   

                //上面三段和下面这个同等

                head = new Node(e, head);
            }
            else
            {
                Node pre = head;
                for (int i = 0; i < index-1; i++)
                {
                    pre = pre.next;
                }
                //Node node = new Node(e);
                //node.next = pre.next;
                //pre.next = node;

                pre.next = new Node(e, pre.next);
            }
            N++;
        }


        public void AddFirst(E e)
        {
            Add(0, e);
        }

        public void AddLast(E e)
        {
            Add(N, e);
        }

        /// <summary>
        /// 查找指定下标的元素
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public E Get(int index)
        {
            if (index < 0 || index > N)
                throw new ArgumentNullException("非法索引");

            Node cur = head;
            for (int i = 0; i < index; i++)
            {
                cur = cur.next;

            }

            return cur.e;

        }

        public E GetFirst()
        {
            return Get(0);
        }

        /// <summary>
        /// 返回最后一个元素
        /// </summary>
        /// <returns></returns>
        public E GetLast()
        {
            return Get(N - 1);
        }

        //指定位置元素修改新的元素
        public void Set(int index ,E newE)
        {
            if (index < 0 || index > N)
                throw new ArgumentNullException("非法索引");

            Node cur = head;
            for (int i = 0; i < index; i++)
            {
                cur = cur.next;

            }
            cur.e = newE;

        }


        //查找链表中是否有该元素
        public bool Contains(E e)
        {
            Node cur = head;
            //链表末端为null
            while (cur != null)
            {
                //如果存在 就返回
                if (cur.e.Equals(e))
                {
                    return true;
                }
                //不存在就遍历下一个
               cur= cur.next;
            }


            //如果遍历完还没有 就返回假
            return false;
        }


        /// <summary>
        /// 删除指定位置的链表元素
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public E RemobeAt(int index)
        {
            if (index < 0 || index >= N)
            {
                throw new ArgumentException("非法索引");
            }
            if (index == 0)
            {
                Node delNode = head;
                head = head.next;
                N--;
                return delNode.e;
            }
            else
            {
                Node pre = head;
                for (int i = 0; i < index-1; i++)
                {
                    pre = pre.next;
                }
                Node delNode = pre.next;
                pre.next = delNode.next;
                N--;
                return delNode.e;
            }
        }

        public E RemoveFirst()
        {
            return RemobeAt(0);
        }

        public E RemoveLast()
        {
            return RemobeAt(N-1);
        }

        //通过指定元素删除节点
        public void Remove(E e)
        {
            //判断节点是否为空
            if (head == null)
                return;
            //如果存在头元素里
            if (head.e.Equals(e))
            {
                //进行删除 让头元素指向下一个位置。  系统会自动回收未被用到的节点
                head = head.next;
                N--;
            }
            else
            {
                Node cur = head;
                Node pre = null;
                while (cur != null)
                {
                    if (cur.e.Equals(e))
                    {
                        break;
                    }
                    pre = cur; //存储上个节点的位置
                    cur = cur.next;

                }

                if (cur != null)
                {
                    //pre下一个节点指向下一个下一个节点  跨过找到的元素节点
                    pre.next = pre.next.next;
                    N--;
                }
            }


        }




        //打印链表
        public override string ToString()
        {
            StringBuilder res = new StringBuilder();
            Node cur = head;
            while (cur != null)
            {
                res.Append(cur+"->");
                cur = cur.next;
            }
            res.Append("Null");
            return res.ToString();
        }




    }
}

一切准备就绪,Main方法调用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;

namespace 链表栈
{
    class Program
    {
        static void Main(string[] args)
        {
            LinkedList1Stack<int> stack = new LinkedList1Stack<int>();
            //进栈
            for (int i = 0; i < 5; i++)
            {
                stack.Push(i);
                WriteLine(stack);
            }
            //出栈
            for (int i = 0; i < 5; i++)
            {
                stack.Pop();
                WriteLine(stack);
            }



            Read();
        }
    }
}

这里添加删除和数组栈恰恰相反,数组栈是对尾部操作,链表栈是对头部操作,这样二者时间复杂度都是最小为O(1)

结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值