• 算法_优先队列


      优先队列是一种数据结构,它支持删除最大元素和插入元素.可以利用优先队列实现对于数组的高效排序.

      数据结构二叉堆能够很好的实现优先队列的操作,在二叉堆的数组中,每个节点都大于等于它的子节点,这种情况被称为堆有序.而根节点将是堆有序的二叉树中的最大结点.在一个二叉堆中,位置k的节点的父节点的位置为[k/2],而它的两个子节点的位置则分别为2k,2K+1.这样在不使用指针的情况下,我们可以通过计算树的索引实现在树中的上下移动,a[k]向上一层就是a[k/2],向下一层就是令k等于2k或是2k+1.

      下面是基于堆的优先队列的基本实现:

    public class MaxPQ<Key extends Comparable<Key>> {
        private Key[] pq;
        private int N;
        public MaxPQ(int maxN) {
            pq=(Key[])new Comparable[maxN+1];
        }
        public boolean isEmpty() {
            return N==0;
        }
        public int size() {
            return N;
        }
        public void insert(Key v) {
            pq[++N]=v;
            swim(N);
        }
        private void swim(int k )/*在堆底插入元素的时候,所对应的上浮操作.*/ {
            while(k>1&&less(k/2,k)) {
                exch(k/2,k);
                k=k/2;
            }
        }
        public Key delMax() {
            Key max=pq[1];
            exch(1,N--);    //将其和最后一个结点交换
            pq[N+1]=null;    //防止对象游离
            sink(1);        //回复堆的有序性
            return max;  
        }
        private void sink(int i) {
            while(2*i<=N) {
                int j=2*i;
                if(j<N&&less(j,j+1)) j++;
                if(!less(i,j)) break;
                exch(i,j);
                i=j;
            }
        }
        public void exch(int i, int k) {
            Key t=pq[i];
            pq[i]=pq[k];
            pq[k]=t;
        }
        private boolean less(int i, int k) {
            return pq[i].compareTo(pq[k])<0;
        }
    }

      对于一个N个元素的基于堆的优先级队列,插入元素操作只需不超过lgN+1次比较,删除最大元素的操作只需不超过2lgN次比较.

      通过基于二叉堆的优先队列,可以实现对于数组的排序,开始的时候我们只需要扫描数组中的一半的元素,因此我们可以跳过大小为1的子堆,最后我们在位置1上调用sink方法,扫描结束.堆排序的实现算法如下:

    public static void sort(Comparable[] a) {
            int N=a.length;
            for(int k=N/2;k>=1;k--) {
                sink(a,k,N);
            }
            while(N>1) {
                exch(a,1,N--);
                sink(a,1,N);
            }
        }

      这段代码中,for循环构造了堆,然后while循环将最大的元素a[1]和a[N]交换,然后如此重复直到堆变空,第二阶段将堆中的最大元素删除,然后放入堆缩小后数组空出来的位置.这种算法被称为堆排序算法.将N个元素排序堆排序只需少于2NlgN+2N次比较.(2N来自于堆构造,2NlgN来自于每次下沉操作最大可能需要的比较).

  • 相关阅读:
    正则表达式的学习笔记
    apply()的使用
    for循环性能测试
    js基础复习~Array对象
    判断值是否为undefined
    layui 单选框取消选中
    layui 表单验证
    火狐浏览器下,表头边框无效
    css3 宽度百分比减去固定宽度 无效问题
    javaScript中的 call 和 apply
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5645927.html
Copyright © 2020-2023  润新知