English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french
查看: 1|回复: 0

重生之数据结构与算法----队列&栈

[复制链接]
查看: 1|回复: 0

重生之数据结构与算法----队列&栈

[复制链接]
查看: 1|回复: 0

232

主题

0

回帖

706

积分

高级会员

积分
706
1A9wq7NjN

232

主题

0

回帖

706

积分

高级会员

积分
706
7 天前 | 显示全部楼层 |阅读模式
简介

上文说到,数据结构只有两种。其它的数据结构都是它的整花活。


  • 栈只能在表的一端(称为栈顶)进行插入和删除操作,遵循 “后进先出”(Last In First Out,LIFO)的原则。就像生活中的一摞盘子,最后放上去的盘子会最先被拿走
  • 队列
    它只允许在表的一端进行插入操作(队尾),在另一端进行删除操作(队头),遵循 “先进先出”(First In First Out,FIFO)的原则。类似于生活中排队买票,先排队的人先买到票离开队列。

用链表实现stack

    public class MyLinkedStack<T>()    {        public static void Run()        {            var stack = new MyLinkedStack<string>();            stack.Push("aaaa");            stack.Push("bbbb");            stack.Push("cccc");            stack.Push("dddd");            while (stack.Count > 0)            {                Console.WriteLine(stack.Pop());            }                    }        private LinkedList<T> _linked = new LinkedList<T>();        /// <summary>        /// 入栈        /// O(1)        /// </summary>        /// <param name="item"></param>        public void Push(T item)        {            _linked.AddFirst(item);        }        /// <summary>        /// 出栈        /// O(1)        /// </summary>        /// <returns></returns>        public T Pop()        {            var first = _linked.First;            _linked.RemoveFirst();            return first.Value;        }        /// <summary>        /// 查看栈顶        /// </summary>        /// O(1)        /// <returns></returns>        public T Peek()        {            return _linked.First.Value;        }        public int Count { get { return _linked.Count; } }    }用链表实现queue

public class MyLinkedQueue<T>{    public static void Run()    {        var queue = new MyLinkedQueue<string>();        queue.Enqueue("aaa");        queue.Enqueue("bbb");        queue.Enqueue("ccc");        queue.Enqueue("ddd");        while (queue.Count > 0)        {            Console.WriteLine(queue.Dequeue());        }    }    private LinkedList<T> _linked = new LinkedList<T>();    /// <summary>    /// 入列    /// </summary>    /// <param name="item"></param>    public void Enqueue(T item)    {        _linked.AddFirst(item);    }    /// <summary>    /// 出列    /// </summary>    /// <returns></returns>    public T Dequeue()    {        var last= _linked.Last;        _linked.RemoveLast();        return last.Value;    }    /// <summary>    /// 查看队列顶    /// </summary>    /// <returns></returns>    public T Peek()    {        return _linked.First.Value;    }    public int Count { get { return _linked.Count; } }}用数组实现stack

    public class MyArrayStack<T>()    {        public static void Run()        {            var stack = new MyLinkedStack<string>();            stack.Push("aaaa");            stack.Push("bbbb");            stack.Push("cccc");            stack.Push("dddd");            while (stack.Count > 0)            {                Console.WriteLine(stack.Pop());            }        }        private List<T> _list=new List<T>();        /// <summary>        /// 入栈        /// O(1)        /// </summary>        /// <param name="item"></param>        public void Push(T item)        {            _list.Add(item);        }        /// <summary>        /// 出栈        /// O(1)        /// </summary>        /// <returns></returns>        public T Pop()        {            var v = _list[_list.Count - 1];            _list.RemoveAt(_list.Count - 1);            return v;        }        /// <summary>        /// 查看栈顶        /// </summary>        /// O(1)        /// <returns></returns>        public T Peek()        {            return _list[_list.Count - 1];        }        public int Count { get { return _list.Count; } }    }用数组实现queue

由于queue先进先出的特性,list头部增删元素的复杂度是O(N),不符合性能要求,我们可以使用前文介绍的环形数组,来实现list头部增删的O(1)
public class MyArrayQueue<T>{    public static void Run()    {        var queue = new MyArrayQueue<string>();        queue.Push("aaaa");        queue.Push("bbbb");        queue.Push("cccc");        queue.Push("dddd");        while (queue.Count > 0)        {            Console.WriteLine(queue.Pop());        }    }    private CircularArray<T> _list = new CircularArray<T>();    /// <summary>    /// 入栈    /// O(1)    /// </summary>    /// <param name="item"></param>    public void Push(T item)    {        _list.AddFirst(item);    }    /// <summary>    /// 出栈    /// O(1)    /// </summary>    /// <returns></returns>    public T Pop()    {        var v = _list.GetLast();        _list.RemoveLast();        return v;    }    /// <summary>    /// 查看栈顶    /// </summary>    /// O(1)    /// <returns></returns>    public T Peek()    {        return _list.GetFirst();    }    public int Count { get { return _list.Count; } }}队列的变种:双端队列

所谓双端队列,主要是比普通队列,多一个出入口,可以从队列的两头进行插入,删除。但也破坏了先进先出的原则。
日常场景使用不多。只有 Python用得多一些,因为Python标准库没有提供内置的栈和队列,一般会用双端队列来模拟标准队列。
    public interface IMyQueue<T>    {        /// <summary>        /// 从头入列        /// </summary>        /// <param name="item"></param>        void EnqueueFirst(T item);        /// <summary>        /// 从头出列        /// </summary>        /// <param name="item"></param>        /// <returns></returns>        T DequeueFirst(T item);        /// <summary>        /// 从尾入列        /// </summary>        void EnqueueLast();        /// <summary>        /// 从头出列        /// </summary>        /// <returns></returns>        T DequeueLast();    }
实现比较简单,不再重复,参考普通队列思路即可。链表/环形数组均可实现。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

232

主题

0

回帖

706

积分

高级会员

积分
706

QQ|智能设备 | 粤ICP备2024353841号-1

GMT+8, 2025-3-11 03:31 , Processed in 4.619280 second(s), 29 queries .

Powered by 智能设备

©2025

|网站地图