优先队列(堆)

19 阅读1分钟

优先队列

优先队列的实现可以使用堆,堆的实现可以用数组。堆是完全二叉树(除了最后一层,其他层都是满的,最后一层从左到右填)。如果用数组实现,从0开始,左节点是2n+1,右节点是2n+2.如果是最大堆的话,nums[n]>nums[2n+1]&&nums[n]>nums[2n+2]。
在java中,有优先队列相关的定义。PriorityQueue类。

  1. 添加元素是add(),或者offer();
  2. 获取顶端元素peek();
  3. 一出一个元素 remove(object);
  4. 移除并返回顶端元素,poll();
  5. 遍历的时候要先获取size,然后使用for(int i=0;i<size;i++);

自己实现优先队列

leetcode_215

给一个数组,然后找到第K大的数。这里可以使用优先队列做。也可以使用快排的方法来做。还可以用根据题意创建一个特别大的数组,int[] arr = new int[20000].第三种方法挺快的,能超过100%的用户。是我在一次面试的时候,紧张到忘记了优先队列如何实现,然后使用第三种方法。

优先队列
public int findKthLargest(int[] nums, int k) {
    int heapSize = nums.length;
    buildMaxHeap(nums, heapSize);
    int kNum = nums[0];
    for (int i = 0; i < k; i++) {
        kNum = nums[0];
        nums[0] = nums[heapSize - 1];
        heapSize--;
        heapify(nums, 0, heapSize);
    }
    return kNum;
}

public void buildMaxHeap(int[] nums, int heapSize) {
    int half = heapSize / 2 - 1;
    for (int i = half; i >= 0; i--) {
        heapify(nums, i, heapSize);
    }
}

public void heapify(int[] nums, int index, int heapSize) {
    int left = index * 2 + 1, right = index * 2 + 2, largest = index;
    if (left < heapSize && nums[left] > nums[largest]) {
        largest = left;
    }
    if (right < heapSize && nums[right] > nums[largest]) {
        largest = right;
    }
    if (largest != index) {
        swap(nums, largest, index);
        heapify(nums, largest, heapSize);
    }
}

public void swap(int[] nums, int i, int j) {
    int temp = nums[i];
    nums[i] = nums[j];
    nums[j] = temp;
}