关于C#的优先队列

最近在实习期间学习《C#高级编程》看到了书上讲到多优先级队列,产生了兴趣,然后在网上百度了许多C#的多优先级队列,基本都是用数组什么的,而书上使用的是双向链表。但是书上的优先队列没有写全,我通过自己的琢磨理解之后写了一个优先队列类。希望各位大佬帮忙看看,多谢。同时,希望能够对一些需要的人产生一丢丢作用。

话不多说,上代码。

这是优先队列的类

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

namespace PriorityQueueWinform
{
    class PriorityQueue<T> : IEnumerable<PriorityItem<T>> where T : IComparable<T>, IEquatable<T>
    {
        //创建链表和节点集合
        private LinkedList<PriorityItem<T>> _linkedList;
        private List<LinkedListNode<PriorityItem<T>>> _firstNodeList;
        private List<LinkedListNode<PriorityItem<T>>> _lastNodeList;

        //返回多优先级队列的长度
        public int Count { get { return _linkedList.Count; } }
        //返回最大优先级
        public int MaxPriority { get; private set; }
        //返回优先级是否从大到小
        public bool IsDesc { get; private set; }

        //重载构造函数
        public PriorityQueue() : this(10, true)
        { }
        public PriorityQueue(int priority) : this(priority, true)
        { }
        public PriorityQueue(bool isDesc) : this(10, isDesc)
        { }
        public PriorityQueue(int priority, bool isDesc)
        {
            MaxPriority = priority;
            IsDesc = isDesc;
            _linkedList = new LinkedList<PriorityItem<T>>();
            _firstNodeList = new List<LinkedListNode<PriorityItem<T>>>(priority);
            _lastNodeList = new List<LinkedListNode<PriorityItem<T>>>(priority);
            for (int i = 0; i < priority; i++)
            {
                _firstNodeList.Add(new LinkedListNode<PriorityItem<T>>(new PriorityItem<T>(default(T), -1)));
                _lastNodeList.Add(new LinkedListNode<PriorityItem<T>>(new PriorityItem<T>(default(T), -1)));
            }
        }

        /// <summary>
        /// 添加值为value,优先级为priority的元素
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="priority">优先级</param>
        public void Enqueue(T value, int priority)
        {
            if (value == null) throw new ArgumentNullException($"{nameof(value)}为空!");
            if (priority < 0 || priority > MaxPriority) throw new ArgumentOutOfRangeException($"{nameof(priority)} 超出范围!");
            PriorityItem<T> item = new PriorityItem<T>(value, priority);
            LinkedListNode<PriorityItem<T>> node = _lastNodeList[priority];
            if (_linkedList.Find(item) != null) throw new ArgumentException("此节点已存在");
            //如果当前节点中有元素
            if (node.Value.Priority >= 0)
            {
                _linkedList.AddAfter(node, item);
                _lastNodeList[priority] = node.Next;
            }
            else
            {
                //如果优先级从大到小则找比将添加节点的优先级大的第一个节点
                if (IsDesc)
                    node = _lastNodeList.Find(n => n.Value.Priority > priority);
                else//否则找比将添加节点的优先级小的最后一个节点
                    node = _lastNodeList.FindLast(n => n.Value.Priority < priority & n.Value.Priority >= 0);
                //即寻找离将添加节点前面最近的节点
                //如果找不到节点
                if (node != default(LinkedListNode<PriorityItem<T>>) && node != null)
                {
                    _linkedList.AddAfter(node, item);
                    _firstNodeList[priority] = node.Next;
                    _lastNodeList[priority] = node.Next;
                }
                //如果找到
                else
                {
                    _linkedList.AddFirst(item);
                    _firstNodeList[priority] = _linkedList.First;
                    _lastNodeList[priority] = _linkedList.First;
                }
            }
        }

        /// <summary>
        /// 输出队列第一个元素并删除之
        /// </summary>
        /// <returns>第一个元素</returns>
        public T Dequeue()
        {
            if (_linkedList.Count == 0)
                return default(T);
            LinkedListNode<PriorityItem<T>> first = _linkedList.First;
            int priority = first.Value.Priority;
            //如果这是该优先级的最后一个元素
            if (_firstNodeList[priority] == _lastNodeList[priority])
            {
                _firstNodeList[priority] = new LinkedListNode<PriorityItem<T>>(new PriorityItem<T>(default(T), -1));
                _lastNodeList[priority] = new LinkedListNode<PriorityItem<T>>(new PriorityItem<T>(default(T), -1));
            }
            else
            {
                _firstNodeList[priority] = _firstNodeList[priority].Next;
            }
            _linkedList.RemoveFirst();
            return first.Value.Value;
        }

        /// <summary>
        /// 删除指定元素
        /// </summary>
        /// <param name="item"></param>
        public void Delete(PriorityItem<T> item)
        {
            LinkedListNode<PriorityItem<T>> node = _linkedList.Find(item);
            int priority = node.Value.Priority;
            if (_lastNodeList[priority] == _firstNodeList[priority])
            {
                _firstNodeList[priority] = new LinkedListNode<PriorityItem<T>>(new PriorityItem<T>(default(T), -1));
                _lastNodeList[priority] = new LinkedListNode<PriorityItem<T>>(new PriorityItem<T>(default(T), -1));
            }
            else if (node == _firstNodeList[priority])
                _firstNodeList[priority] = _firstNodeList[priority].Next;
            else if (node == _lastNodeList[priority])
                _lastNodeList[priority] = _lastNodeList[priority].Previous;
            _linkedList.Remove(node);
        }

        /// <summary>
        /// 搜索优先级为priority的节点
        /// </summary>
        /// <param name="priority">优先级</param>
        /// <returns>该优先级的所有节点</returns>
        public IEnumerable<PriorityItem<T>> SelectByPriority(int priority)
        {
            LinkedListNode<PriorityItem<T>> node = _firstNodeList[priority];
            while (node.Value.Priority != -1 && node.Previous != _lastNodeList[priority] && node.Next != null)
            {
                yield return node.Value;
                node = node.Next;
            }
        }
        IEnumerator<PriorityItem<T>> IEnumerable<PriorityItem<T>>.GetEnumerator()
        {
            foreach (var i in _linkedList)
                yield return i;
        }

        public IEnumerator GetEnumerator()
        {
            foreach (var i in _linkedList)
                yield return i;
        }
    }
}

这是优先队列中节点value的类

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

namespace PriorityQueueWinform
{
    class PriorityItem<T> : IEquatable<PriorityItem<T>> where T : IComparable<T>, IEquatable<T>
    {
        private T _value;
        private int _priority;

        public T Value
        {
            get
            {
                return _value;
            }
        }

        public int Priority
        {
            get
            {
                return _priority;
            }
        }

        public PriorityItem(T value, int priority)
        {
            _value = value;
            _priority = priority;
        }

        public override string ToString()
        {
            return $"Priority:{_priority} Value:{_value}";
        }

        public bool Equals(PriorityItem<T> other)
        {
            return _priority == other.Priority && Value.Equals(other.Value);
        }
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值