栈和队列

36 阅读1分钟

单调队列

使用双端队列Dequ实现单调队列。
for循环遍历数组,每次往队尾加入一个数之前,先将队尾小于它的元素全部出队。这样可以保证队尾到队头是递增的。队头是当前最值。

单调队列不是一成不变的,而是不同场景不同写法,总之要保证队列里单调递减或递增的原则,所以叫做单调队列。

结合滑动窗口最大值题目。单调队列加入的元素是数组下标,用来判断窗口边界。每到一个新窗口,按照单调队列方法在队尾加入元素之后,还要处理队头元素,保证其在新窗口范围内。

        for (int i = k; i < nums.length; i++) {
            while (!deque.isEmpty() && nums[i] > nums[deque.peekLast()]) {
                deque.pollLast();
            }
            deque.offer(i);
            // make sure : window[i-k+1,i], 
            while (deque.peekFirst() < i - k + 1) deque.pollFirst();
            res[count++] = nums[deque.peekFirst()];
        }

优先队列

PriorityQueue(优先队列)  采用的是堆排序,实际上是一个堆(不指定Comparator时默认为最小堆),即升序,队头元素最小。 堆排序只能保证根是最大(最小),整个堆并不是有序的。

例子:

@Test
public void testPriorityQueue(){
    //默认采用的是最小堆实现的
    PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>(){
        public int compare(Integer a, Integer b){
            return a-b; //if a>b 则交换,升序
        }
    });
    queue.offer(13);
    queue.offer(9);
    int len = queue.size();
    for(int i=0;i<len;i++){
        System.out.println(queue.poll());
    }
    //输出 9  13
}
   

  • 自定义类型
public class PriorityQueueTest{        
    public static void main(String args[]){  
        PriorityQueue<People> queue = new PriorityQueue<People>(11,  
                new Comparator<People>() {  
                  public int compare(People p1, People p2) {  
                    return p2.age - p1.age;  
                  }  
                });       
              
        for (int i = 1; i <= 10; i++) {  
            queue.add(new People("张"+ i, (new Random().nextInt(100))));  
        }  
        while (!queue.isEmpty()) {  
              System.out.println(queue.poll().toString());  
        }  
    }  
}  
  
class People {   
    String name;  
    int age;  
    public People(String name, int age){  
        this.name = name;  
        this.age = age;  
    }      
    public String toString() {  
        return "姓名:"+name + " 年龄:" + age;  
    }  
}  

优先队列遍历

  PriorityQueue的iterator()不保证以任何特定顺序遍历队列元素。若想按特定顺序遍历,先将队列转成数组,然后排序遍历。

      Object[] nn=q.toArray();
      Arrays.sort(nn);