队列

1、顺序结构描述的队列

在这一章中,我们选择用Rear队尾的指针来指示最后一个入队的元素在队列中的位置。我们选择队列内存储的数组的Data[0]作为队头,每次取数据的时候,队头弹出(out)。具体的代码如下所示:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace DataStructure.Queue

{

    class SeqQueue<T>: IQueue<T>

    {

 

        int Rear =-1;//队尾

        constint MaxSize=100;//队列的最大容量

        T[] Data =new T[MaxSize];//一个数组

        public SeqQueue()

        {

 

        }

        public SeqQueue(T[] data)

        {

            Array.Copy(data,this.Data,data.Length);

            Rear = data.Length -1;

        }

 

 

        publicint GetLength(out States states)

        {

            if(Rear==-1)

            {

                states = States.Fail;

                return0;

            }

            else

            {

                states = States.Success;

                return Rear +1;

            }

        }

        publicbool IsEmpty()

        {

            return Rear ==-1?true:false;

         }

 

        publicvoid Clear()

        {

            Rear =-1;

        }

        privatebool isFull(){

            return Rear +1== MaxSize ?true:false;

        }

        publicvoid In(T item,out States states)

        {

            if(isFull())

            {

                states = States.Fail;

                return;

            }

            this.Data[++Rear]= item;

            states = States.Success;

 

        }

 

        public T Out(out States states)

        {

            //判断队列是否为空

            if(IsEmpty())

            {

                states = States.Fail;

                returndefault(T);

            }

           

            States mStates;

            //当队列中只有一个元素的时候

            if(this.GetLength(out mStates)==1)

            {

                Rear--;

                states = States.Success;

                returnthis.Data[0];

            }

            //普通的情况

        

            //(1)将所有元素往前移动一位

            T DataToOut=this.Data[0];

            for(int i =1; i <this.GetLength(out mStates); i++)

            {

                this.Data[-1]=this.Data[i];

            }

            --Rear;

            states = States.Success;

            //(2)返回要弹出的值

            return DataToOut;

        }

 

        public T GetFront(out States states)

        {

            if(this.IsEmpty()==true)

            {

                states = States.Fail;

                returndefault(T);

            }

            else

            {

                states= States.Success;

                return Data[0];//返回队头的元素

            }   

        }

    }

}

 

从代码的实现上看,这种实现的方式有一种明显缺点:那就是每次当我们出队一个元素的时候,我们都需要将除队头外的元素全部往前移动一个,这样子的时间复杂度为O(n)。我们将在循环队列中讨论相应的解决方案。

2、循环队列

在循环队列中,比较困难的地方就是在队列长度和是否为满的判断。由于这方面的教程很多,大家可自行百度。另外,队头(Front)和队尾(Rear)的初始化位置(比如以下代码中是Front=0,Rear=0,如果改为Front=0,Rear=-1呢?)将会极大地影响代码的书写。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace DataStructure.Queue

{

    /// <summary>

    /// 循环队列

    /// </summary>

    class CSeqQueue<T>: IQueue<T>

    {

        int Front =0;//队头

        int Rear =0;//队尾

        constint MaxSize =4;//队列的最大容量

        T[] Data =new T[MaxSize];//一个数组

        public CSeqQueue()

        {

 

        }

        public CSeqQueue(int[] data)

        {

            Array.Copy(data,this.Data, data.Length);

            Rear = data.Length -1;

        }

 

 

        publicint GetLength()

        {

            return(Rear - Front + MaxSize)% MaxSize;

        }

 

        publicbool IsEmpty()

        {

            returnthis.GetLength()==0?true:false;

        }

 

        publicvoid Clear()

        {

            Front =0;//队头

            Rear =0;//队尾

        }

        publicbool isFull()

        {

            return(Rear +1)% MaxSize == Front ?true:false;

 

        }

        publicvoid In(T item,out States states)

        {

            if(isFull())

            {

                states = States.Fail;

                return;

            }

 

            this.Data[Rear]= item;

            Rear =(Rear +1)% MaxSize;

            states = States.Success;

        }

 

        public T Out(out States states)

        {

            if(IsEmpty())

            {

                states = States.Fail;

                returndefault(T);

            }

            T dataToOut =this.Data[Front];

            Front =(Front +1)% MaxSize;

            states = States.Success;

            return dataToOut;

        }

 

        public T GetFront(out States states)

        {

            thrownew NotImplementedException();

        }

    }

}

 

2、链队

由单链表的实现,我们可知单链表有一个Head字段,通过Head字段我们可以遍历单链表。在链队中,我们打算直接利用Head字段,只不过我们将其命名Front。通常当我们需要遍历一个单链表时,我们得从链表头遍历都最后,才能找到链表尾。这样操作的话,时间复杂度为O(n),我们打算引用Rear字段,用来指示每次新入队的元素。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace DataStructure.Queue

{

    class LinkQueue<T>:IQueue<T>

    {

 

        class Node<T>

        {

 

            private T data;

            /// <summary>

            /// 数据域

            /// </summary>

            public T Data

            {

                get {return data;}

                set { data = value;}

            }

 

 

            private Node<T> next;

            /// <summary>

            /// 引用域

            /// </summary>

            public Node<T> Next

            {

                get {return next;}

                set { next = value;}

            }

 

            //头结点构造函数

            public Node(Node<T> node)

                :this(default(T), node)

            {

            }

            //普通结点构造函数

            public Node(T data, Node<T> node)

            {

                this.Data = data;

                this.Next = node;

            }

            /// <summary>

            /// 空构造函数

            /// </summary>

            public Node()

                :this(default(T),null)

            {

            }

            //尾结点构造函数

            public Node(T data)

                :this(data,null)

            {

 

            }

        }

        private Node<T> Front;//队头

        private Node<T> Rear;//队尾

 

        publicbool IsEmpty()

        {

            return Front ==null?true:false;

       

        }

 

        publicvoid Clear()

        {

            Front =null;

        }

 

        publicvoid In(T item,out States states)

        {

            if(IsEmpty())

            {

                Front =new Node<T>(item);

                states = States.Success;

                Rear = Front;

            }

            else

            {

                Node<T> newNode=new Node<T>(item);

                Rear.Next = newNode;

                Rear = newNode;

                states = States.Success;

            }

       

        }

 

        public T Out(out States states)

        {

            if(this.IsEmpty())

            {

                states = States.Fail;

                returndefault(T);

            }

            else

            {

                states = States.Success;

                T DataToOut =this.Front.Data;

                Front = Front.Next;

                return DataToOut;

            }

        }

 

        public T GetFront(out States states)

        {

            if(this.IsEmpty())

            {

                states = States.Fail;

                returndefault(T);

            }

            else

            {

                states = States.Success;

                returnthis.Front.Data;

            }

        }

 

        publicint GetLength()

        {

            if(IsEmpty())

            {

                return0;

            }

            int Lenth=0;//长度

            for(Node<T> last = Front; last.Next !=null; last=last.Next)

            {

                Lenth++;

            }

            return Lenth;

 

        }

    }

}

 

作者:kissazi2 
出处:http://www.cnblogs.com/kissazi2/ 
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/kissazi2/p/3203428.html

时间: 2024-11-08 17:13:45

队列的相关文章

[数据结构] 队列

队列 队列是一种操作受限制的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.  队列中没有元素时,称为空队列.在队列这种数据结构中,最先插入的元素将是最先被删除的元素:反之最后插入的元素将是最后被删除的元素,因此队列又称为"先进先出"(FIFO-first in first out)的线性表. 队列空的条件:front=rear 队列满的条件: rear = MAXSIZE 顺序队列 建立顺

缓冲区-关于操作系统中缓冲池里面队列的分类问题。。

问题描述 关于操作系统中缓冲池里面队列的分类问题.. 缓冲池(Buffer Pool)中的缓冲区可供多个进程共享,缓冲池中的缓冲区根据类型划分,相同类型的缓冲区链成一个队列,于是形成了三个队列: 空缓冲队列 输入队列(装满输入数据的缓冲区链成的队列) 输出队列(装满输出数据的缓冲区链成的队列) 然而,在UNIX的缓冲区管理中,设置了三种队列,分别为: 自由buf队列 设备buf队列 NODEV设备队列 那么缓冲区到底是怎么划分的..?UNIX中的三种队列和缓冲池中划分的三种队列有什么关系? 解决

数据结构——队列

1 队列是一种只允许在表的一端插入元素,在另一端删除元素的特殊的线性表.允许插入的一端成为队尾(rear),允许删除的一端成为队头(front).当队列中没有任何元素时成为空队列.队列是一种先进先出的线性表,简称FIFO表. 2 与栈类似,队列也是一种操作受限的特殊的线性表,同样可以采用顺序存储结构和链式存储结构来表示队列. 3 队列的顺序存储表示--循环队列 队列的顺序存储表示同样是利用一维数组来实现.为了解决"假溢出"问题,可以将队列的数组看成是头尾相接的环状空间,当队尾元素放到数

消息队列入门(四)ActiveMQ的应用实例

部署和启动ActiveMQ 去官网下载:http://activemq.apache.org/ 我下载的是apache-activemq-5.12.0-bin.tar.gz, 解压到本地目录,进入到bin路径下, 运行activemq启动ActiveMQ. 运行方式:启动 ./activemq start ActiveMQ默认使用的TCP连接端口是61616, 5.0以上版本默认启动时,开启了内置的Jetty服务器,可以进入控制台查看管理. 启动ActiveMQ以后,登陆:http://loca

wcf-使用MSMQ消息队列的WCF的效率的问题。

问题描述 使用MSMQ消息队列的WCF的效率的问题. 请教个问题,WCF在使用MSMQ的时候,每次WCF程序处理MSMQ中的数据量,每秒只有几百条. 以下是测试数据 处理消息数: 180000 开始时间: [2013-11-01 15:35:27] Start To Save Log To DB. 结束时间: [2013-11-01 15:51:12] Finish To Save Log To DB. 耗时: 00:15:45 基本上算下来也就每秒190多条,以前好的时候可以达到200多条,其

java concurrent包自带线程池和队列详细讲解

Java线程池使用说明一简介线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的问题提供了非常大的帮助.二:线程池线程池的作用:线程池作用就是限制系统中执行线程的数量.     根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪费了系统资

STL--双端队列(deque)和链表(list)

双端队列(deque容器类): #include<deque>与vector 类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间. 与vector不同的是:deque 还支持从开始端插入数据:push_front() . 此外deque 不支持与vector 的capacity() .reserve() 类似的操作. deque,是"double-ended queue"的缩写.可以随机存取元素(用索引直接存取). 数组头部和尾部添加或移除元素都

java如何队列同步redis?

问题描述 java如何队列同步redis? 就是数据批量插入redis,然后再同步插入到数据库里面,怎么搞 解决方案 java redis使用之利用jedis实现redis消息队列0135 java redis使用之利用jedis实现redis消息队列java redis使用之利用jedis实现redis消息队列 解决方案二: 一般是数据先插入数据库,然后再利用触发器等把数据插入redis.或者用过期方式来从数据库同步数据到redis

Linux TCP队列相关参数的总结

文/锋寒 在Linux上做网络应用的性能优化时,一般都会对TCP相关的内核参数进行调节,特别是和缓冲.队列有关的参数.网上搜到的文章会告诉你需要修改哪些参数,但我们经常是知其然而不知其所以然,每次照抄过来后,可能很快就忘记或混淆了它们的含义.本文尝试总结TCP队列缓冲相关的内核参数,从协议栈的角度梳理它们,希望可以更容易的理解和记忆.注意,本文内容均来源于参考文档,没有去读相关的内核源码做验证,不能保证内容严谨正确.作为Java程序员没读过内核源码是硬伤. 下面我以server端为视角,从 连接

消息队列入门(二)消息队列的规范和开源实现

1.AMQP规范 AMQP 是 Advanced Message Queuing Protocol,即高级消息队列协议.AMQP不是一个具体的消息队列实现,而 是一个标准化的消息中间件协议.目标是让不同语言,不同系统的应用互相通信,并提供一个简单统一的模型和编程接口. 目前主流的ActiveMQ和RabbitMQ都支持AMQP协议. AMQP相关的角色和职责 Producer 消息生产者 一个给exchange发送消息的程序,发送方式大致是:它首先创建一个空消息,然后填上内容.路由KEY,最后发