• c#环形队列


    上一章说到的数组模拟队列存在的问题,问题分析并优化

    • 目前数组使用一次就不能用,没有达到复用的效果
    • 将这个数组使用算法,改进成一个环形的队列

    1.数组模拟环形队列

    对前面的数组模拟队列的优化,充分利用数组。因此将数组看做是一个环形的。(通过去模的方式来实现即可)

    分析说明:

    • 尾索引的下一个为头索引时,表示队列满。即将队列容量空出一个作为约定,这个在做判断队列满的时候需要注意(rear+1)%maxsize==front 满
    • rear==front 空

     

     

    实现思路如下:

    • front指针含义调整,front指向队列第一个元素。也就是array[front]就是队列的第一个元素。front初始值=0。
    • rear变量的含义调整,rear指向队列的最后一个元素的后一个位置。因为希望空出一个空间作为约定。rear初始值=0。
    • 当队列满时,条件是(rear + 1)% maxsize = front , 位满。(PS:rear +1是预留一个位置,不牺牲这个空间会导致无法判断队列空或者满,rear一直自增,也就是说rear是很有可能大于maxsieze的,比如maxsize=5,rear=10,因为rear被加到10,此时rear的实际位置是0。取模式保证党front为0时,rear+1取模为0与front相等)
    • 当队列空是,条件是rear==front 。
    • 有效的数据个数,(raer + maxsize - front)%maxsize。(为什么要取模,因为是环形同时有rear可能是最大的然后跑到最前面来;假如:rear=1,front=0,maxsize=10 再套入公式中 (1+10-0)%10=1 有效数据为1)

    2.代码实现

    public class CircleArrayQueue
    {
        //队列最大值
        private int _maxSize;
        //队列头部
        private int _front;
        //队列尾部
        private int _rear;
        //存储值的数组
        private int[] _tempArray;
        
        public CircleArrayQueue(int maxSize)
        {
            Console.WriteLine($"MaxSize : { maxSize }");
            _maxSize = maxSize;
            _tempArray = new int[_maxSize];
            //front指向队列第一个元素
            _front = 0;
            //rear指向队列的最后一个元素的后一个位置
            _rear = 0;
        }
    
        public bool IsFull()
        {
            return (_rear + 1) % _maxSize == _front;
        }
    
        public bool IsEmpty()
        {
            return _rear == _front;
        }
    
        /// <summary>
        /// 有效数据个数
        /// </summary>
        /// <returns></returns>
        public int Num() 
        {
            return (_rear + _maxSize - _front) % _maxSize;
        }
    
        public void EnQueue(int val)
        {
            if (IsFull())
            {
                Console.WriteLine("队列已满,无法加入数据!");
                return;
            }
            //直接插入数据
            _tempArray[_rear] = val;
            //_rear后移一位,这里必须考虑取模
            _rear = (_rear + 1) % _maxSize;
        }
    
        public int DeQueue()
        {
            if (IsEmpty())
            {
                throw new Exception("队列是空的,无法取出数据!");
            }
            //这里需要分析出front是指向队列的第一个元素
            //1.先把front对应的值保留到一个临时变量
            //2.将front后移
            //3.将临时保存的变量返回
    
            var tempVal = _tempArray[_front];
            _front = (_front + 1) % _maxSize;
            return tempVal;
        }
    
        public void ShowAll()
        {
            if (IsEmpty())
            {
                Console.WriteLine("队列是空的!");
                return;
            }
            Console.WriteLine("显示队列所有内容:");
            for (int i = _front; i < _front + Num(); i++)
            {
                Console.Write($"{ _tempArray[i % _maxSize] }\t");
            }
            Console.WriteLine();
        }
    
        public void PeekFirst()
        {
            if (IsEmpty())
            {
                Console.WriteLine("队列是空的,无法取出数据!");
                return;
            }
    
            Console.WriteLine($"查看第一个值:{ _tempArray[_front] }");
        }
    }
    

    代码调用

    class Program
    {
            static void Main(string[] args)
            {
                //MySparseArray sparseArray = new MySparseArray();
                //sparseArray.Print();    
            try
            {
                CircleArrayQueue queue = new CircleArrayQueue(4);
                queue.EnQueue(97);
                queue.EnQueue(98);
                queue.EnQueue(200);
                queue.EnQueue(1000);
                //查看第一个值
                queue.PeekFirst();
                //显示队列里所有的内容
                queue.ShowAll();
                //取出一个值
                Console.WriteLine($"取出一个值:{ queue.DeQueue() }");
                Console.WriteLine($"取出一个值:{ queue.DeQueue() }");
                Console.WriteLine($"取出一个值:{ queue.DeQueue() }");
                queue.PeekFirst();
                queue.EnQueue(200);
                queue.ShowAll();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
    
            Console.Read();
        }
    }
    

    运行效果

     

  • 相关阅读:
    设置eclipse编码
    前端基础知识
    微信小程序
    jQuery下拉框
    Vue-cli的安装
    vue的数据交互形式
    node安装和小测试
    shui
    JQ-滚动条下拉无限的加载数据
    HTML-video全屏
  • 原文地址:https://www.cnblogs.com/justzhuzhu/p/15866448.html
Copyright © 2020-2023  润新知