博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java数据结构与算法解析(三)——队列与背包
阅读量:5130 次
发布时间:2019-06-13

本文共 4621 字,大约阅读时间需要 15 分钟。

队列基本概念

像栈一样,队列也是表。然而,使用队列时插入在一端进行,而删除则在另一端进行。插入的一端称为队尾,删除的一端称为队头 。其插入和删除的操作分别在表的两端进行,队列的特点就是先进先出(First In First Out)。

队列的数组实现

 

队列的顺序储存

缺点:出队复杂度高0(n),容易假溢出

Front为队头指针,rear为队尾指针,但是这种存储方式的缺点就是出队复杂度高0(n),容易假溢出,例如让a1,a2出队,则a1,a2存储的位置会被设置为null,然后将front进行移动,指向a3,容易假溢出是指,上图右边的情况,rear已经角标越界,说明要扩容,但是其实队列里有两个地方是空的,就是角标0和1的位置,这种就是假溢出现象

 

循环队列

把队列的头尾相接的循环存储结构叫做循环队列。

循环队列就可以很好的解决假溢出的现象

实现循环队列

声明队列的公用接口

public interface  Queue<T> {

 

    int size();

    boolean isEmpty();

    void enqueue(T t);

    T dequeue();

 

}

 

 

public class ArrayQueue<T> implements Queue<T> {

    private T[] mArray;

    private int mQueueSize;

    private int mFront;

    private int mLast;

 

    private static final int DEFAULT_CAPACITY = 10;

 

    public ArrayQueue(int capacity) {

        if (capacity < DEFAULT_CAPACITY) {

            ensureCapacity(DEFAULT_CAPACITY);

        } else {

            ensureCapacity(capacity);

        }

    }

 

    @Override

    public int size() {

        return mQueueSize;

    }

 

    @Override

    public boolean isEmpty() {

        return mFront == mLast;

    }

 

    @Override

    public boolean enqueue(T t) {

        //判断是否满队

        if (mFront == (this.mLast + 1) % mArray.length) {

            ensureCapacity(mArray.length * 2 + 1);

        }

 

        mArray[mLast] = t;

        mLast = (mLast + 1) % mArray.length;

        mQueueSize++;

        return true;

 

 

 

    }

 

    private int findFirstEmptyIndex() {

        for (int i = 0; i < mArray.length; i++) {

            if (mArray[i] == null) {

                return i;

            }

        }

    }

 

    @Override

    public T dequeue() {

        if (mLast == mFront) {

            return null;

 

        } else {

            T t = mArray[mFront];

            mFront = (mFront + 1) % mArray.length;

            return t;

        }

 

 

    }

 

    private void ensureCapacity(int newCapacity) {

        T[] newArray = (T[]) new Object[newCapacity];

        for (int i = 0; i < mArray.length; i++) {

            newArray[i] = mArray[i];

        }

        mArray = newArray;

    }

}

 

队列的链式存储模式

 

实现队列的最好的方式就是使用单链表来实现,队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已。

这种实现出队和入队就十分方便,出队只需要将头结点指向的位置进行改变,入队只需要将rear的指向进行改变

 

空队列的图如下:

队列的链式实现

public class LinkedQueue<T> implements Queue<T> {

    //队列头指针

    private Node<T> mFront;

    //队列尾指针

    private Node<T> mRear;

    //队列长度

    private int mSize = 0;

 

    public LinkedQueue() {

        Node n = new Node(null, null);

        mFront = mRear = n;

    }

 

    @Override

    public int size() {

        return mSize;

    }

 

    @Override

    public boolean isEmpty() {

        return mFront == mRear;

    }

 

    @Override

    public boolean enqueue(T t) {

        Node n = new Node(t, null);

        //将队尾指针指向新加入的节点,将s节点插入队尾

        mFront.mNext = n;

        mRear = n;

        mSize++;

        return true;

    }

 

    @Override

    public T dequeue() {

        if (mRear == mFront) {

            throw new NoSuchElementException("The LinkedQueue is empty");

        }

        Node<T> deleNote = mFront.mNext;

        T t = deleNote.mData;

        mFront.mNext = deleNote.mNext;

        //判断出队列长度是否为1

        if (mFront.mNext == null) {

            mFront = mRear;

        }

        mSize--;

        return t;

    }

 

    private static class Node<T> {

 

        private Node<T> mNext;

        private T mData;

 

 

        public Node(T data, Node<T> next) {

            mData = data;

            mNext = next;

        }

    }

}

背包的概念

 

背包是一种不支持从中删除元素的集合数据类型,它的目的就是帮助用例收集元素并迭代遍历所有收集到的元素,使用背包就说明元素的处理顺序不重要,可以想象一个背包,往里面放了N个小球,在取球的时候手伸进背包是随机取出来的,通常这样的数据结构用来进行计算平均值等对元素顺序没有要求的算法;

图1

 

背包的数组实现

 

public class ArrayBag<T> implements Iterable {

    private T[] mArray;

    private int mBagSize;

    private static final int DEFAULT_CAPACITY = 10;

 

    public ArrayBag() {

        ensureCapacity(DEFAULT_CAPACITY);

    }

 

    public ArrayBag(int bagSize) {

        if (bagSize > DEFAULT_CAPACITY) {

            ensureCapacity(bagSize);

        } else {

            ensureCapacity(DEFAULT_CAPACITY);

        }

    }

 

    public void add(T t) {

        if (mArray.length == mBagSize) {

            ensureCapacity(mArray.length);

        }

        mArray[mBagSize] = t;

        mBagSize++;

    }

 

    private void ensureCapacity(int newCapacity) {

        T[] newArray = (T[]) new Object[newCapacity];

        for (int i = 0; i < mArray.length; i++) {

            newArray[i] = mArray[i];

        }

        mArray = newArray;

    }

 

    @Override

    public Iterator iterator() {

        return new ArrayIterator();

    }

 

    private class ArrayIterator implements Iterator<T> {

        private int currentPositon;

 

        @Override

        public boolean hasNext() {

 

            return currentPositon < mBagSize;

        }

 

        @Override

        public T next() {

            if (!hasNext()) {

                throw new NoSuchElementException();

            }

 

            return mArray[currentPositon++];

        }

 

    }

}

 

背包的链表实现

 

public class LinkedBag<T> implements Iterable {

 

    private int mBagSize;

    private Node<T> headNote;

 

    public LinkedBag() {

        headNote = new Node<T>(null, null);

    }

 

    public void add(T t) {

        Node<T> node = new Node<T>(t, null);

        headNote.mNext = node;

    }

 

    @Override

    public Iterator iterator() {

        return new ArrayIterator();

    }

 

    private class ArrayIterator implements Iterator<T> {

        private Node<T> currentNode = headNote.mNext;

 

        @Override

        public boolean hasNext() {

 

            return currentNode != null;

        }

 

        @Override

        public T next() {

            if (!hasNext()) {

                throw new NoSuchElementException();

            }

 

            T t = currentNode.mData;

            currentNode = currentNode.mNext;

 

            return t;

        }

 

    }

 

    private static class Node<T> {

 

        private Node<T> mNext;

        private T mData;

 

 

        public Node(T data, Node<T> next) {

            mData = data;

            mNext = next;

        }

    }

}

 

 

                                   来源:CSDN

转载于:https://www.cnblogs.com/taiyuanzhongruan/p/7511185.html

你可能感兴趣的文章
小程序踩坑(三)-上拉加载和下拉刷新篇
查看>>
mysql backup
查看>>
【BZOJ 2791】 2791: [Poi2012]Rendezvous (环套树、树链剖分LCA)
查看>>
[书籍分享]0-008.商业模式新生代[Business Model Generation]
查看>>
css好看的银行卡号样式
查看>>
使用 fiex 布局
查看>>
腾讯企业邮箱POP,SMTP分别是什么
查看>>
基于NHibernate的三层结构应用程序开发初步
查看>>
《图解HTTP》读书笔记
查看>>
Winxp环境下vs2010配置COCOS2D-X2.20开发环境
查看>>
c语言学习笔记十五
查看>>
成绩排序
查看>>
MySQL存储引擎
查看>>
简单几何(推公式) UVA 11646 Athletics Track
查看>>
wildfly部署solr.war
查看>>
CentOS 命令随笔
查看>>
python周报第十二周
查看>>
Spring in Action(一) Core Spring:Spring into Action(2)
查看>>
ElasticSearch
查看>>
HDU 2066 一个人的旅行 最短路问题
查看>>