`
flyingdutchman
  • 浏览: 358061 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

索引优先队列:最小索引优先队列

阅读更多
         在很多应用中,会允许引用优先队列中的数据,我们可以把这种数据结构看作是能够快速访问其最小元素的数组。
package org.test;

/*************************************************************************
 *  Compilation:  javac IndexMinPQ.java
 *  Execution:    java IndexMinPQ
 *
 *  Minimum-oriented indexed PQ implementation using a binary heap.
 *
 *********************************************************************/

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 *  The <tt>IndexMinPQ</tt> class represents an indexed priority queue of generic keys.
 *  It supports the usual <em>insert</em> and <em>delete-the-minimum</em>
 *  operations, along with <em>delete</em> and <em>change-the-key</em> 
 *  methods. In order to let the client refer to items on the priority queue,
 *  an integer between 0 and NMAX-1 is associated with each key&mdash;the client
 *  uses this integer to specify which key to delete or change.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  <p>
 *  The <em>insert</em>, <em>delete-the-minimum</em>, <em>delete</em>,
 *  <em>change-key</em>, <em>decrease-key</em>, and <em>increase-key</em>
 *  operations take logarithmic time.
 *  The <em>is-empty</em>, <em>size</em>, <em>min-index</em>, <em>min-key</em>, and <em>key-of</em>
 *  operations take constant time.
 *  Construction takes time proportional to the specified capacity.
 *  <p>
 *  This implementation uses a binary heap along with an array to associate
 *  keys with integers in the given range.
 *  <p>
 *  For additional documentation, see <a href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public class IndexMinPQ<Key extends Comparable<Key>> implements Iterable<Integer> {
    private int NMAX;        // maximum number of elements on PQ
    private int N;           // number of elements on PQ
    private int[] pq;        // binary heap using 1-based indexing
    private int[] qp;        // inverse of pq - qp[pq[i]] = pq[qp[i]] = i
    private Key[] keys;      // keys[i] = priority of i

   /**
     * Create an empty indexed priority queue with indices between 0 and NMAX-1.
     * @throws java.lang.IllegalArgumentException if NMAX < 0
     */
    public IndexMinPQ(int NMAX) {
        if (NMAX < 0) throw new IllegalArgumentException();
        this.NMAX = NMAX;
        keys = (Key[]) new Comparable[NMAX + 1];    // make this of length NMAX??
        pq   = new int[NMAX + 1];
        qp   = new int[NMAX + 1];                   // make this of length NMAX??
        for (int i = 0; i <= NMAX; i++) qp[i] = -1;
    }

   /**
     * Is the priority queue empty?
     */
    public boolean isEmpty() { return N == 0; }

   /**
     * Is i an index on the priority queue?
     * @throws java.lang.IndexOutOfBoundsException unless (0 &le; i < NMAX)
     */
    public boolean contains(int i) {
        if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
        return qp[i] != -1;
    }

   /**
     * Return the number of keys on the priority queue.
     */
    public int size() {
        return N;
    }

   /**
     * Associate key with index i.
     * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
     * @throws java.util.IllegalArgumentException if there already is an item associated with index i.
     */
    public void insert(int i, Key key) {
        if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
        if (contains(i)) throw new IllegalArgumentException("index is already in the priority queue");
        N++;
        qp[i] = N;
        pq[N] = i;
        keys[i] = key;
        swim(N);
    }

   /**
     * Return the index associated with a minimal key.
     * @throws java.util.NoSuchElementException if priority queue is empty.
     */
    public int minIndex() { 
        if (N == 0) throw new NoSuchElementException("Priority queue underflow");
        return pq[1];        
    }

   /**
     * Return a minimal key.
     * @throws java.util.NoSuchElementException if priority queue is empty.
     */
    public Key minKey() { 
        if (N == 0) throw new NoSuchElementException("Priority queue underflow");
        return keys[pq[1]];        
    }

   /**
     * Delete a minimal key and return its associated index.
     * @throws java.util.NoSuchElementException if priority queue is empty.
     */
    public int delMin() { 
        if (N == 0) throw new NoSuchElementException("Priority queue underflow");
        int min = pq[1];        
        exch(1, N--); 
        sink(1);
        qp[min] = -1;            // delete
        keys[pq[N+1]] = null;    // to help with garbage collection
        pq[N+1] = -1;            // not needed
        return min; 
    }

   /**
     * Return the key associated with index i.
     * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
     * @throws java.util.NoSuchElementException no key is associated with index i
     */
    public Key keyOf(int i) {
        if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
        else return keys[i];
    }

   /**
     * Change the key associated with index i to the specified value.
     * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
     * @deprecated Replaced by changeKey()
     */
    @Deprecated public void change(int i, Key key) {
        changeKey(i, key);
    }

   /**
     * Change the key associated with index i to the specified value.
     * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
     * @throws java.util.NoSuchElementException no key is associated with index i
     */
    public void changeKey(int i, Key key) {
        if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
        keys[i] = key;
        swim(qp[i]);
        sink(qp[i]);
    }

   /**
     * Decrease the key associated with index i to the specified value.
     * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
     * @throws java.lang.IllegalArgumentException if key &ge; key associated with index i
     * @throws java.util.NoSuchElementException no key is associated with index i
     */
    public void decreaseKey(int i, Key key) {
        if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
        if (keys[i].compareTo(key) <= 0) throw new IllegalArgumentException("Calling decreaseKey() with given argument would not strictly decrease the key");
        keys[i] = key;
        swim(qp[i]);
    }

   /**
     * Increase the key associated with index i to the specified value.
     * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
     * @throws java.lang.IllegalArgumentException if key &le; key associated with index i
     * @throws java.util.NoSuchElementException no key is associated with index i
     */
    public void increaseKey(int i, Key key) {
        if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
        if (keys[i].compareTo(key) >= 0) throw new IllegalArgumentException("Calling increaseKey() with given argument would not strictly increase the key");
        keys[i] = key;
        sink(qp[i]);
    }

   /**
     * Delete the key associated with index i.
     * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
     * @throws java.util.NoSuchElementException no key is associated with index i
     */
    public void delete(int i) {
        if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
        int index = qp[i];
        exch(index, N--);
        swim(index);
        sink(index);
        keys[i] = null;
        qp[i] = -1;
    }


   /**************************************************************
    * General helper functions
    **************************************************************/
    private boolean greater(int i, int j) {
        return keys[pq[i]].compareTo(keys[pq[j]]) > 0;
    }

    private void exch(int i, int j) {
        int swap = pq[i]; pq[i] = pq[j]; pq[j] = swap;
        qp[pq[i]] = i; qp[pq[j]] = j;
    }


   /**************************************************************
    * Heap helper functions
    **************************************************************/
    private void swim(int k)  {
        while (k > 1 && greater(k/2, k)) {
            exch(k, k/2);
            k = k/2;
        }
    }

    private void sink(int k) {
        while (2*k <= N) {
            int j = 2*k;
            if (j < N && greater(j, j+1)) j++;
            if (!greater(k, j)) break;
            exch(k, j);
            k = j;
        }
    }


   /***********************************************************************
    * Iterators
    **********************************************************************/

   /**
     * Return an iterator that iterates over all of the elements on the
     * priority queue in ascending order.
     * <p>
     * The iterator doesn't implement <tt>remove()</tt> since it's optional.
     */
    public Iterator<Integer> iterator() { return new HeapIterator(); }

    private class HeapIterator implements Iterator<Integer> {
        // create a new pq
        private IndexMinPQ<Key> copy;

        // add all elements to copy of heap
        // takes linear time since already in heap order so no keys move
        public HeapIterator() {
            copy = new IndexMinPQ<Key>(pq.length - 1);
            for (int i = 1; i <= N; i++)
                copy.insert(pq[i], keys[pq[i]]);
        }

        public boolean hasNext()  { return !copy.isEmpty();                     }
        public void remove()      { throw new UnsupportedOperationException();  }

        public Integer next() {
            if (!hasNext()) throw new NoSuchElementException();
            return copy.delMin();
        }
    }
 }
         
分享到:
评论

相关推荐

    C语言数据结构优先队列实现

    1. 初始化优先队列: 使用`malloc`动态分配内存,创建一个大小为`LIST_INIT_SIZE`的数组,用于存储优先队列中的元素。初始长度设为0,列表容量设为`LIST_INIT_SIZE`。 2. 插入操作: 当向优先队列插入新元素时,...

    利用堆实现的优先队列

    ### 利用堆实现的优先队列 #### 引言 在计算机科学领域,优先队列是一种非常重要的数据结构,它被广泛应用于多种算法中,如任务调度、事件驱动模拟等场景。相比于传统队列,优先队列允许插入元素时指定一个优先级...

    数据结构课程设计优先队列数据(priority_queue)类型

    优先队列通常通过堆数据结构来实现,堆可以是最大堆或最小堆。最大堆中,父节点的值总是大于或等于其子节点的值;相反,最小堆中,父节点的值小于或等于子节点的值。这种特性使得堆的根节点总是具有最高(或最低)的...

    优先队列课程设计代码

    - **索引优先队列**:每个元素都有一个索引,可以快速定位元素位置。 通过以上分析可以看出,优先队列作为一种高效的数据结构,在多种计算机科学领域都有着广泛的应用。正确理解和实现优先队列能够极大地提高程序...

    优先队列代码堆实现

    在实际应用中,堆实现的优先队列常用于各种算法,如Dijkstra最短路径算法(每次处理最小距离的节点)、Prim最小生成树算法(每次添加最小权值的边)等。由于堆的高效特性,它们在处理大量数据时尤其有用。 总的来说...

    用堆实现简单的优先队列(JAVA)

    在计算机科学中,优先队列是一种特殊的数据结构,它允许我们插入元素并总是能优先处理具有最高优先级的元素。这种数据结构常用于调度任务、事件驱动系统和各种算法中。在Java中,我们可以利用堆(Heap)来实现一个...

    c#优先队列

    优先队列是一种特殊的数据结构,它允许用户插入元素并总是能快速访问到具有最高优先级的元素。在C#中,实现优先队列的方式多种多样,包括使用有序数组、无序数组、集合以及二叉堆。下面将详细介绍这四种方法。 1. *...

    优先队列(1).zip

    二叉堆是一种常见的优先队列实现方式,分为最大堆和最小堆。在最大堆中,父节点的值总是大于或等于其子节点的值,因此根节点总是具有最高优先级;相反,最小堆中父节点的值总是小于或等于子节点的值,根节点是最小的...

    优先队列

    以下是一个简单的基于最小堆实现的优先队列的伪代码示例: ```cpp class PriorityQueue { private: std::vector&lt;int&gt; heap; void heapify(int index); int leftChild(int index); int rightChild(int index); ...

    字典,图,优先队列

    优先队列常用于事件驱动的模拟、任务调度、最小生成树算法(Prim或Kruskal)等。其核心操作包括插入元素、删除最高优先级元素以及检查队首元素。 压缩包内的"第13章 图"可能涵盖图的表示方法(邻接矩阵和邻接表)、...

    flatqueue一个非常快速和简单的JavaScript优先队列

    3. 搜索算法:优先队列在Dijkstra算法、A*搜索等路径寻找算法中扮演重要角色。 4. 事件处理:可以用于优先处理高优先级的事件。 六、源码学习 对于开发者来说,深入研究flatqueue的源码,理解其内部机制,不仅能...

    张宴作品--队列

    《队列:张宴技术解析》 队列是一种基础且重要的数据结构,它遵循“先进先出”(First In First Out, FIFO)的原则。在计算机科学中,队列被广泛应用于各种场景,如任务调度、缓冲区管理、多线程通信等。本文将围绕...

    堆排序及优先队列源代码_上机c++ 添加元素 删除最大节点

    ### 堆排序及优先队列的实现与应用 #### 一、堆排序的基本概念 堆排序是一种基于比较的排序算法,它利用堆这种数据结构的特性进行排序。堆可以分为大顶堆(Max Heap)和小顶堆(Min Heap)。在大顶堆中,任意节点...

    二叉树-基于Objective-C的完全二叉树实现的优先队列.zip

    优先队列是一种特殊的队列,它的特点是队列中的元素具有优先级,出队顺序由优先级决定,优先级高的元素先出队。常见的优先队列实现有堆(堆排序中的二叉堆)和 Fibonacci heap 等。在本案例中,使用完全二叉树实现...

    java队列实现(顺序队列、链式队列、循环队列)

    循环队列在出队后可能需要更新队头索引以避免数组下标越界。 - **查看队头元素(peek)**:查看但不移除队头元素。所有类型的队列都可以实现这个操作。 - **检查队列是否为空(isEmpty)**:检查队列中是否有元素。 ...

    优先队列及堆实验报告附C++源码.doc

    在本实验中,优先队列是通过最小堆实现的,这是一个完全二叉树,其中每个父节点的值都小于或等于其子节点的值。这种结构确保了根节点总是具有最小的优先级,即是最优先的元素。 首先,我们定义了一个名为`Node`的...

    算法与数据结构:队列

    - 初始化队列:分配内存(对于链队列),设定队头和队尾指针。 - 入队:在队尾添加元素,更新队尾。 - 出队:移除队头元素,更新队头。 - 判断队列是否为空:检查队头是否等于队尾。 - 判断队列是否已满:对于循环...

    栈和队列.zip

    4. 双端队列:允许在两端进行入队和出队操作,适用于需要快速插入和删除的情况。 5. 堆栈和队列的应用示例:例如,递归函数的模拟、括号匹配、深度优先搜索(DFS)和广度优先搜索(BFS)等。 学习这些代码,不仅...

    基于最大堆的最大优先队列的C++类模板实现

    在计算机科学中,优先队列是一种特殊的数据结构,它允许我们根据优先级处理元素,其中最高优先级的元素最先被处理。在这个场景中,我们关注的是一个基于最大堆实现的最大优先队列。最大堆是一种完全二叉树,其中每个...

Global site tag (gtag.js) - Google Analytics