数据结构(java)之队列

时间:2023-02-25 19:23:00

1.        队列的逻辑结构

a)       定义:只允许在表的一端进行插入,另一端进行删除的线性表,进行插入的一端叫队尾,进行删除的一端叫队头,没有数据元素时称为空队列。

b)       特征:先进先出

c)        抽象数据类型

                     i.            数据元素:同属一类的任意类型对象

                    ii.            数据结构:线性结构,队头无前驱,队尾无后继

                  iii.            数据操作:定义在IQueue

publicinterface IQueue<E> {

  boolean enqueue(E e); //入栈

  E dequeue();   //出栈

  E peek();  //去对头元素

  int size();    //返回队长

  boolean isEmpty(); //判断是否空队

  boolean ifFull(); //判断是否满队

}

2.        队列实现之顺序队列

a)       存储结构:顺序队列采用一个连续的一维数组来保存数据,队头设置在最近一个元素离开的位置front,队尾设置在最近一个元素插入的位置rear,但是如果队列设置成一个直线型的由于队尾入队和队头出对会造成“假溢出”,因此将队列设置成一个环状的。当队空时,front=rear,当队满时(rear+1)%maxsize=front,入队时,rear=(rear+1)%maxsize,出队时,front=(front+1)%maxsize,队中元素个数为(rear-front+maxsize),且数组中的下标为front的元素不存储数据

b)       基本操作

                     i.            初始化顺序队列:给定顺序队列最大存储空间大小,frontrear都设为0size设为0

                    ii.            入队:将下标为rear设为(rear+1)%maxsize且对应的位置值设为指定入队元素

                  iii.            出队:将front设为(front+1)%maxsize

                  iv.            求队长:返回(rear-front+maxsize)%maxsize

                    v.            判断是否满队:判断(rear+1)%maxsize==front

                  vi.            判断是否空队:判断rear==front

c)        代码实现

publicclass MySequenceQueue<E> implements IQueue<E> {

  privateintsize; //队列长度

  privateintmaxsize//队列最大长度

  privateintfront; //队头,指向的是将要离开的元素的前一个位置

  privateintrear; //队尾

  private E[] data;

  //初始化顺序队列

  public MySequenceQueue(intmaxsize) {

     super();

     this.size = 0;

     this.maxsize = maxsize;

     data=(E[])new Object[this.maxsize];

     this.front = 0;

     this.rear = 0;

  }

  //入队

  @Override

  publicboolean enqueue(E e) {

     if(!this.isFull()) {

         this.rear=(this.rear+1)%this.maxsize;

         this.data[this.rear]=e;

         returntrue;

     }

     returnfalse;

  }

  //出队

  @Override

  public E dequeue() {

     if(!this.isEmpty()) {

         this.front=(this.front+1)%this.maxsize;

         returnthis.data[this.front];

     }

     returnnull;

  }

  //取队头元素

  @Override

  public E peek() {

     if(!this.isEmpty())

         returnthis.data[(this.front+1)%maxsize];

     returnnull;

  }

  //求队长

  @Override

  publicint size() {

     this.size=(this.rear-this.front+maxsize)%maxsize;

     returnthis.size;

  }

 

  @Override

  publicboolean isEmpty() {

     if(this.front==this.rear)

         returntrue;

     returnfalse;

  }

 

  @Override

  publicboolean isFull() {

     if((this.rear+1+this.maxsize)%maxsize==this.front)

         returntrue;

     returnfalse;

  }

}

3.        队列实现之链队列

a)       存储结构:队头节点用front,队尾节点用rear,每个节点包含数据域和指向下一个节点的next,队尾节点的nextnull,队头队尾节点不用来存储数据

b)       基本操作

                     i.            初始化链队列:设置队列长度size0,队头节点和队尾节点都为null,然后将队头节点的next设置为rear

                    ii.            入队:首先找到队列的除队尾的最后一个节点(队尾的上一个节点),然后新建节点,将新建节点的next设为rear,将入队前的最后一个节点的next设为新建节点,并使size自增

                  iii.            出队:找到队头节点的下一个节点,将其数据区域的值取出并保存在临时变量中,将队头节点的next设为出队前的第一个节点的下一个节点,使size自减,并返回临时变量

                  iv.            判断是否空队:如果frontnext指向rear返回true,否则返回false

c)        代码实现

//建立队列节点,包括数据和指向下一个节点的next

class QueueNode<E>{

  private E e;

  private QueueNode<E> next;

  public QueueNode(E e, QueueNode<E> next) {

     super();

     this.e = e;

     this.next = next;

  }

  public E getE() {

     returne;

  }

  publicvoid setE(E e) {

     this.e = e;

  }

  public QueueNode<E> getNext() {

     returnnext;

  }

  publicvoid setNext(QueueNode<E> next) {

     this.next = next;

  }

}

publicclass MylinkQueue<E> implements IQueue<E> {

  privateintsize;

  private QueueNode<E> front;

  private QueueNode<E> rear;

  //初始化链队列,将size设为0frontrear都设为null

  public MylinkQueue() {

     super();

     this.size = 0;

     this.front = new QueueNode(null,null)//初始化队列,让队头的next指向队尾

     this.rear = new QueueNode(null,null);

     this.front.setNext(this.rear);

  }

  //入队

  @Override

  publicboolean enqueue(E e) {

     QueueNode temp=this.front;

     if(!this.isFull()) {

         while(temp.getNext()!=this.rear)

            temp=temp.getNext();  //找到队尾的上一个元素

         QueueNode<E> node=new QueueNode(e,this.rear)//新建立一个节点,并将该节点的next指向队尾

         temp.setNext(node);   //将入队前队列的最后一个元素的next指向新节点

         this.size++;

         returntrue;

     }

     returnfalse;

  }

  //出队

  @Override

  public E dequeue() {

     QueueNode<E> temp=this.front.getNext();

     this.front.setNext(temp.getNext());

     this.size--;

     returntemp.getE();

  }

  //返回队列的第一个元素

  @Override

  public E peek() {

     returnthis.front.getNext().getE();

  }

 

  @Override

  publicint size() {

     returnthis.size;

  }

 

  @Override

  publicboolean isEmpty() {

     if(this.front.getNext()==this.rear)

         returntrue;

     returnfalse;

  }

 

  @Override

  publicboolean isFull() {

     returnfalse;

  }

 

1.        队列的逻辑结构

a)       定义:只允许在表的一端进行插入,另一端进行删除的线性表,进行插入的一端叫队尾,进行删除的一端叫队头,没有数据元素时称为空队列。

b)       特征:先进先出

c)        抽象数据类型

                     i.            数据元素:同属一类的任意类型对象

                    ii.            数据结构:线性结构,队头无前驱,队尾无后继

                  iii.            数据操作:定义在IQueue

publicinterface IQueue<E> {

  boolean enqueue(E e);//入栈

  E dequeue();   //出栈

  E peek();  //去对头元素

  int size();    //返回队长

  boolean isEmpty();//判断是否空队

  boolean ifFull();//判断是否满队

}

2.        队列实现之顺序队列

a)       存储结构:顺序队列采用一个连续的一维数组来保存数据,队头设置在最近一个元素离开的位置front,队尾设置在最近一个元素插入的位置rear,但是如果队列设置成一个直线型的由于队尾入队和队头出对会造成“假溢出”,因此将队列设置成一个环状的。当队空时,front=rear,当队满时(rear+1)%maxsize=front,入队时,rear=(rear+1)%maxsize,出队时,front=(front+1)%maxsize,队中元素个数为(rear-front+maxsize),且数组中的下标为front的元素不存储数据

b)       基本操作

                     i.            初始化顺序队列:给定顺序队列最大存储空间大小,frontrear都设为0size设为0

                    ii.            入队:将下标为rear设为(rear+1)%maxsize且对应的位置值设为指定入队元素

                  iii.            出队:将front设为(front+1)%maxsize

                  iv.            求队长:返回(rear-front+maxsize)%maxsize

                    v.            判断是否满队:判断(rear+1)%maxsize==front

                  vi.            判断是否空队:判断rear==front

c)        代码实现

publicclass MySequenceQueue<E> implements IQueue<E> {

  privateintsize;//队列长度

  privateintmaxsize;  //队列最大长度

  privateintfront;//队头,指向的是将要离开的元素的前一个位置

  privateintrear;//队尾

  private E[] data;

  //初始化顺序队列

  public MySequenceQueue(intmaxsize) {

     super();

     this.size = 0;

     this.maxsize = maxsize;

     data=(E[])new Object[this.maxsize];

     this.front = 0;

     this.rear = 0;

  }

  //入队

  @Override

  publicboolean enqueue(E e) {

     if(!this.isFull()) {

         this.rear=(this.rear+1)%this.maxsize;

         this.data[this.rear]=e;

         returntrue;

     }

     returnfalse;

  }

  //出队

  @Override

  public E dequeue() {

     if(!this.isEmpty()) {

         this.front=(this.front+1)%this.maxsize;

         returnthis.data[this.front];

     }

     returnnull;

  }

  //取队头元素

  @Override

  public E peek() {

     if(!this.isEmpty())

         returnthis.data[(this.front+1)%maxsize];

     returnnull;

  }

  //求队长

  @Override

  publicint size() {

     this.size=(this.rear-this.front+maxsize)%maxsize;

     returnthis.size;

  }

 

  @Override

  publicboolean isEmpty() {

     if(this.front==this.rear)

         returntrue;

     returnfalse;

  }

 

  @Override

  publicboolean isFull() {

     if((this.rear+1+this.maxsize)%maxsize==this.front)

         returntrue;

     returnfalse;

  }

}

3.        队列实现之链队列

a)       存储结构:队头节点用front,队尾节点用rear,每个节点包含数据域和指向下一个节点的next,队尾节点的nextnull,队头队尾节点不用来存储数据

b)       基本操作

                     i.            初始化链队列:设置队列长度size0,队头节点和队尾节点都为null,然后将队头节点的next设置为rear

                    ii.            入队:首先找到队列的除队尾的最后一个节点(队尾的上一个节点),然后新建节点,将新建节点的next设为rear,将入队前的最后一个节点的next设为新建节点,并使size自增

                  iii.            出队:找到队头节点的下一个节点,将其数据区域的值取出并保存在临时变量中,将队头节点的next设为出队前的第一个节点的下一个节点,使size自减,并返回临时变量

                  iv.            判断是否空队:如果frontnext指向rear返回true,否则返回false

c)        代码实现

//建立队列节点,包括数据和指向下一个节点的next

class QueueNode<E>{

  private E e;

  private QueueNode<E> next;

  public QueueNode(E e, QueueNode<E> next) {

     super();

     this.e = e;

     this.next = next;

  }

  public E getE() {

     returne;

  }

  publicvoid setE(E e) {

     this.e = e;

  }

  public QueueNode<E> getNext() {

     returnnext;

  }

  publicvoid setNext(QueueNode<E> next) {

     this.next = next;

  }

}

publicclass MylinkQueue<E> implements IQueue<E> {

  privateintsize;

  private QueueNode<E> front;

  private QueueNode<E> rear;

  //初始化链队列,将size设为0frontrear都设为null

  public MylinkQueue() {

     super();

     this.size = 0;

     this.front = new QueueNode(null,null);  //初始化队列,让队头的next指向队尾

     this.rear = new QueueNode(null,null);

     this.front.setNext(this.rear);

  }

  //入队

  @Override

  publicboolean enqueue(E e) {

     QueueNode temp=this.front;

     if(!this.isFull()) {

         while(temp.getNext()!=this.rear)

            temp=temp.getNext();  //找到队尾的上一个元素

         QueueNode<E> node=new QueueNode(e,this.rear);  //新建立一个节点,并将该节点的next指向队尾

         temp.setNext(node);   //将入队前队列的最后一个元素的next指向新节点

         this.size++;

         returntrue;

     }

     returnfalse;

  }

  //出队

  @Override

  public E dequeue() {

     QueueNode<E> temp=this.front.getNext();

     this.front.setNext(temp.getNext());

     this.size--;

     returntemp.getE();

  }

  //返回队列的第一个元素

  @Override

  public E peek() {

     returnthis.front.getNext().getE();

  }

 

  @Override

  publicint size() {

     returnthis.size;

  }

 

  @Override

  publicboolean isEmpty() {

     if(this.front.getNext()==this.rear)

         returntrue;

     returnfalse;

  }

 

  @Override

  publicboolean isFull() {

     returnfalse;

  }

}