您的位置:首页 > 理论基础 > 数据结构算法

重温数据结构:队列的链式实现、顺序实现及循环队列

2014-03-12 16:33 966 查看
1.队列的链式存储实现

队列接口:

package edu.njupt.zhb;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2014-3-12 Nanjing,njupt,China
*/
public interface MyQueue {
public void add(Object object);//从队列尾部加入一个元素
public Object remove();//出列,返回队列头部的值,并将其删除
public int getSize();//获取队列的大小
public Object peek();//偷看队列的前端元素,但是不出列
public boolean isEmpty();
}

链式存储的实现
/*
* $filename: MyLinkedQueue.java,v $
* $Date: 2014-3-12 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;

import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2014-3-12 Nanjing,njupt,China
*/
/**
* 队列的链式实现
*/
public class MyLinkedQueue implements MyQueue{
public class Node{
Node next;
Object data;
}
private Node front;//前面的指针
private Node rear;//后面的指针
private int size;
public MyLinkedQueue(){
front=new Node();
front.next=null;
rear=new Node();
rear.next=null;
size=0;
}
/**
* 入列,从尾部添加元素
*/
@Override
public void add(Object object) {
// TODO Auto-generated method stub
Node node = new Node();
node.data=object;
if(size==0){//如果是空的
front.next=node;
rear.next=node;
size++;
return;
}
rear.next.next=node;//将尾节点指向新增节点
rear.next=node;//将rear指针指向新增节点
size++;
}
/**
* 出列,从头部取出元素,并删除
*/
@Override
public Object remove() {
// TODO Auto-generated method stub
if(front.next!=null){
Object object=front.next.data;//取出当前队列的头元素
front.next=front.next.next;//删除第一个元素
size--;
return object;
}
return null;
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return size;
}

@Override
public Object peek() {
// TODO Auto-generated method stub
return front.next.data;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return size==0;
}
public static void main(String[] args) {
MyQueue queue = new MyLinkedQueue();
for(int i=0;i<20;i++){
queue.add("str"+i);
}
while(!queue.isEmpty()){
Object object=queue.remove();
System.out.println((String)object);
}
}
}

队列的顺序存储:
/*
* $filename: MyArrayQueue.java,v $
* $Date: 2014-3-12 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2014-3-12 Nanjing,njupt,China
*/
public class MyArrayQueue implements MyQueue {

private int size;
private int front;
private int rear;
final int INIT_LEN=10;//初始化长度
final int INCREAMENT_LEN=10;//长度增量大小
Object []objects;//用数组保存队列中的元素
public MyArrayQueue(){
size=0;
front=0;
rear=-1;
objects = new Object[INIT_LEN];
}
@Override
public void add(Object object) {
// TODO Auto-generated method stub
if(size+1==objects.length){//扩充数组
Object []temp = new Object[objects.length+INCREAMENT_LEN];
for(int i=0;i<objects.length;i++){
temp[i]=objects[i];
}
objects=temp;
}
objects[++rear]=object;//将元素添加在队列的尾部
size++;
}

@Override
public Object remove() {
// TODO Auto-generated method stub
if(size==0){
return null;
}
Object object = objects[front];//取出队列的头元素
for(int i=0;i<objects.length-1;i++){//通过平移,删除已取出的元素
objects[i]=objects[i+1];
}
size--;
return object;
}

@Override
public int getSize() {
// TODO Auto-generated method stub
return size;
}

@Override
public Object peek() {
// TODO Auto-generated method stub
if(size==0){
return null;
}
Object object = objects[front];//取出队列的头元素
return object;
}

@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return size==0;
}
public static void main(String[] args) {
MyQueue queue = new MyArrayQueue();
for(int i=0;i<20;i++){
queue.add("str"+i);
}
while(!queue.isEmpty()){
Object object=queue.remove();
System.out.println((String)object);
}
}
}

循环队列:
原因:主要是解决队列的“假溢出”问题。其实上面的顺序实现方式已经有效避免了假溢出(通过平移的方式)。下面来看一下循环队列吧。

/*
* $filename: MyArrayCircularQueue.java,v $
* $Date: 2014-3-12 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2014-3-12 Nanjing,njupt,China
*/
/**
*实现循环队列操作:
(1)为使入队和出队实现循环,可以利用取余运算符%
(2)队头指针进一:front=(front+1) % maxSize
(3)队尾指针进一:rear=(rear+1) % maxSize
(4)空队列:当front==rear 时为空队列
(5)满队列:当(rear+1) % maxSize ==front时为满队列。满队列时实际仍有一个元素的空间未使用。
*/
public class MyArrayCircularQueue implements MyQueue {

private int front;
private int rear;
private final int maxSize = 10;
private Object []objects;
private int size;
public MyArrayCircularQueue(){
front=rear=0;
size=0;
objects=new Object[maxSize];
}
@Override
public void add(Object object) {
// TODO Auto-generated method stub
if((rear+1)%maxSize==front){
System.out.println("队列已满...");
return;
}
rear=(rear+1)%maxSize;
objects[rear]=object;
size++;
}

@Override
public Object remove() {
// TODO Auto-generated method stub
if(front==rear){
System.out.println("队列已经空了...");
return null;
}
front=(front+1)%maxSize;
Object object = objects[front];
size--;
return object;
}

@Override
public int getSize() {
// TODO Auto-generated method stub
return size;
}

@Override
public Object peek() {
// TODO Auto-generated method stub
return objects[front+1];
}

@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return front==rear;
}

public static void main(String[] args) {
MyQueue queue = new MyArrayCircularQueue();
for(int i=0;i<50;i++){
queue.add("str"+i);
}
while(!queue.isEmpty()){
Object object=queue.remove();
System.out.println((String)object);
}
}
}


附录:



循环队列的示意图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: