`
冰糖葫芦
  • 浏览: 297815 次
社区版块
存档分类
最新评论

java使用小根堆实现优先级队列的几种方式

阅读更多

写在之前

1.自定义实现采用数组作为内部数据结构

2.内部数组通过grow方法进行扩容,每次只是简单的扩展为原来的2倍

3.集中实现方式的主要区别在于siftDown方法

4.以下给出关键代码,更多详细信息请看附件源码

 

实现方式一(递归实现)

关键代码:

   @Override
    protected void siftDown(int index)
    {
        int len = totalCount - 1;
        int left = left(index);
        int right = right(index);
        if(left > len)
        {
            return;
        }
        int currentMin = left;
        if(right <= len && arr[currentMin] > arr[right])
        {
            currentMin = right;
        }
        if(arr[currentMin] < arr[index])
        {
            swap(arr, currentMin, index);
            siftDown(currentMin);
        }
    }

  

实现方式二(循环实现)

关键代码:

   @Override
    protected void siftDown(int index)
    {
        int len = totalCount - 1;
        while(left(index) <= len)
        {
            int left = left(index);
            int right = right(index);
            if(left > len)
            {
                break;
            }
            int currentMin = left;
            if(right <= len && arr[currentMin] > arr[right])
            {
                currentMin = right;
            }
            if(arr[currentMin] >= arr[index])
            {
                break;
            }
            swap(arr, currentMin, index);
            index = currentMin;
        }
    }

 

实现方式三(直接构建堆)

关键代码:

   @Override
    protected void siftDown(int index)
    {
        int len = totalCount - 1;
        while(left(index) <= len)
        {
            int left = left(index);
            int right = right(index);
            if(left > len)
            {
                break;
            }
            int currentMin = left;
            if(right <= len && arr[currentMin] > arr[right])
            {
                currentMin = right;
            }
            if(arr[currentMin] < arr[index])
            {
                swap(arr, currentMin, index);
            }
            //进入下一个非叶子节点
            index++;
            
        }
    }

 

实现方式四(JDK中的实现)

1.siftUp方法:

protected void siftUp(int k, int x) 
    {
        while (k > 0) 
        {
            int parent = parent(k);
            int e = arr[parent];
            if (x >= e)
                break;
            arr[k] = e;
            k = parent;
        }
        arr[k] = x;
    }

 2.siftDown方法:

   /**
     * 指定index位置的值为x,并为x在堆中找到合适位置
     * @param index
     * @param x
     */
    private void siftDown(int index, int x) 
    {
        int half = totalCount >>> 1;        
        while (index < half) 
        {
            int currentMin = left(index);
            int right = right(index);
            if (right < totalCount && arr[currentMin] > arr[right])
                currentMin = right;
            if (x <= arr[currentMin])
                break;
            //将index位置设置为最小节点值
            arr[index] = arr[currentMin];
            //迭代
            index = currentMin;
        }
        //将最终值放入合适位置
        arr[index] = x;
    }

 

其他的一下关键方法

1.siftUp方法:

   @Override
    protected void siftUp(int index)
    {
        int parent = parent(index);
        while(index > 0 && arr[index] < arr[parent])
        {
            swap(arr, index, parent);
            index = parent;
            parent = parent(index);
        }
    }

 2.add方法:

   @Override
    public boolean add(int ele)
    {
        if(totalCount == arr.length)
        {
            //扩容
            grow();
        }
        
        int i = totalCount;
        arr[i] = ele;
        if(totalCount == 1)
        {
            return true;
        }
        
        //调整元素位置确保为小根堆
        siftUp(i);
        totalCount++;
        return true;
    }

 3.poll方法:

   @Override
    public int poll()
    {
        int result = arr[0];
        arr[0] = arr[--totalCount];
        siftDown(0);
        
        return result;
    }

 5.remove方法:

   @Override
    public int remove(int ele)
    {
        //内部数据为空
        if(totalCount < 1)
        {
            return -1;
        }
        
        //计算元素位置
        int index = indexOf(ele);
        if(index < 0)
        {
            return -1;
        }
        
        return removeAt(index);
    }

 6.removeAt方法:

   @Override
    protected int removeAt(int idx)
    {
        if(idx < 0 || idx >= totalCount)
        {
            return -1;
        }
        int result = arr[idx];
        
        //将删除元素与最后一个元素交换位置
        if(idx != totalCount -1)
        {
            arr[idx] = arr[totalCount - 1];
        }
        //位置交换之后队列长度减一
        totalCount--;
        //如果队列长度大于1,而且删除的元素位置不在队尾则重新调整堆
        if(totalCount > 1 && idx != totalCount)
        {
            siftDown(idx);
        }
        return result;
    }

 

 

 

0
0
分享到:
评论

相关推荐

    优先级队列(堆实现)

    本文将深入探讨优先级队列的概念、实现方式以及如何在实际编程中使用。 首先,理解二叉堆是理解优先级队列的关键。二叉堆分为最大堆和最小堆,最大堆的每个父节点的值都大于或等于其子节点的值,而最小堆则相反,每...

    对几种队列的总结

    在C++ STL中,`priority_queue`是一个标准模板库,提供了优先级队列的实现。 然后是**双端队列(deque,Double Ended Queue)**,它允许在队列的两端进行入队和出队操作。双端队列常用于栈的功能,如回溯算法,或者...

    java实现多级反馈队列算法,允许处理机空闲

    1. **创建优先级队列**:可以使用`PriorityBlockingQueue`来模拟不同优先级的队列,通过自定义比较器来确定优先级。 2. **时间片管理**:通过`ScheduledExecutorService`来定时检查当前运行的进程是否超时,如果超时...

    Java队列源码-simulation-queue-priory-pso:文章“队列优先级优化算法:用于集成过程的新颖任务调度”的源代码(Ja

    优先级队列在Java中通过`java.util.PriorityQueue`类实现,这个类是一个无界并发容器,它不保证队列的元素顺序,而是基于最小堆的数据结构来维护元素的顺序,使得每次删除元素时都是当前队列中优先级最高的元素。...

    java实现的基于jms协议的消息队列中间件,源码!

    Java实现的基于JMS(Java Message Service)协议的消息队列中间件是一种用于应用程序间异步通信的重要技术。消息队列允许应用程序将消息发送到队列而不必等待接收方的响应,提高了系统的可扩展性和容错性。JMS是Java...

    JAVA100例之实例67JAVA线程优先级

    3. **线程公平性**:在某些Java并发框架,如`java.util.concurrent`包中的`ThreadPoolExecutor`,可以配置为优先级队列,这样高优先级的线程会被优先处理,但这仍然取决于工作线程的数量和其他正在运行的任务。...

    编写程序实现基于优先级的时间片轮转调度算法

    时间片轮转调度算法是一种多任务调度方式,它的基本思想是将所有就绪进程放入一个队列中,每次选择队首进程执行,但只给它一定的时间片(通常很短)来运行。当时间片用完,进程会被暂停,放回队尾,然后选择下一个...

    阻塞队列实现生产者消费者模式Java开发Java经验技巧共

    2. **队列实现**:接着可能会讲解几种具体的阻塞队列实现,比如`ArrayBlockingQueue`是基于数组的有界队列,`LinkedBlockingQueue`基于链表,以及`PriorityBlockingQueue`是无界的优先级队列,它们各自的特点和适用...

    java实现的内存分配

    Java提供了几种不同的垃圾收集器,如Serial、Parallel、Concurrent Mark Sweep (CMS) 和G1等,它们各有优缺点,适用于不同的场景。例如,Serial GC适合小型应用,而CMS和G1则更适合大型并发环境。 此外,Java还提供...

    java实现操作系统处理机调度

    5. **多级反馈队列调度**:结合了前面几种策略,设置多个优先级队列,低优先级队列的进程如果在一定时间内得不到服务,则提升其优先级。Java实现时需要维护多个队列,并根据条件动态调整进程所在队列。 实现这些...

    简单的优先队列

    优先队列是一种特殊的队列,其中元素按照优先级顺序进行排列。在计算机科学中,它是一种数据结构,常用于处理需要快速访问...通过理解和应用这些知识,我们可以设计和实现高效的优先级队列系统,用于解决各种实际问题。

    huffman编码java实现

    在Java中实现哈夫曼编码涉及到几个关键步骤: 1. **构建哈夫曼树**: - 首先,我们需要一个表示二叉树节点的数据结构。在这个例子中,定义了一个名为`HuffmanTree33`的类,包含了左右子节点、权值和对应编码属性。...

    QOS队列和拥塞技术

    队列技术主要有以下几种: 1. **先进先出(FIFO)**:传统的队列管理方式,数据包按照到达的顺序进行排队和转发。这种简单的方法不提供任何优先级控制,因此对于需要QOS保证的应用效果较差。 2. **优先级队列(PQ...

    系统调度程序 先进先出 时间片 java

    在Java中实现这样的调度程序,开发者可能使用了线程的概念。Java的`Thread`类和`Runnable`接口允许创建并发执行的任务。通过定义`run()`方法,我们可以指定线程的行为。为了实现FIFO和时间片轮转,可能需要维护一个...

    操作系统模拟:多级反馈队列

    5. **队列数据结构**:为了实现多级队列,可能需要使用Java的`Queue`接口,例如`LinkedList`或`ArrayDeque`,来存储和管理线程。 6. **状态管理**:每个线程需要有一个状态表示(如新建、就绪、运行、阻塞、结束等...

    Android中的线程池与任务队列

    Android提供了几种不同的拒绝策略,如丢弃最旧的任务、抛出异常等。 4. 管理器(ThreadPoolExecutor):负责线程池的生命周期管理,如初始化、扩展、收缩以及关闭线程池。 任务队列(Task Queue)是线程池的重要...

    磁盘调度算法Java版(FCFS,SSTF,SCAN)

    在实际的Java实现中,可能需要维护一个根据寻道距离排序的优先级队列。虽然SSTF可以显著减少平均寻道时间,但它可能出现饥饿问题,即某些远距离的请求会被连续多次地推迟,导致系统响应时间变长。 3. **扫描(SCAN...

    调度算法 java源代码

    5. **多级反馈队列(MLFQ)**:结合了FCFS、SJF和RR,设置多个队列,不同队列的时间片长度不同,新进程进入最高优先级队列,若无法在当前时间片内完成,降入下一个队列。MLFQ兼顾了各种类型进程的需求,较为灵活。 ...

    模拟进程调度中的高优先级优先调度算法

    实现高优先级优先调度算法通常包括以下几个步骤: 1. **初始化**:系统启动时,为所有进程分配优先级。这可以通过多种方式实现,比如基于进程类型、内存需求、等待时间等标准。 2. **进程调度**:当处理器空闲时,...

Global site tag (gtag.js) - Google Analytics