Java异常处理及优先级队列

一、异常

Java中的异常都继承自Throwable类,从Throwable派生出Error和Exception,Error一般是JVM抛出的错误,比如StackOverFlowError,OutOfMemoryError,这些错误是无法挽回的,只能结束当前Java进程的执行;
Exception异常是Java应用抛出的,分为编译时期可检测的异常(如IOException)和运行时期的异常(NullPointerException),编译时期可检测的异常必须要处理,否则编译器会报错误,而运行时期的异常RuntimeException不需要强制处理,Exception异常一般可以通过捕获处理以后,程序可以继续正常执行。

1、throws:
声明当前函数的异常,但却并不处理这个异常,而是把异常抛给该函数的调用方。
2、throw:
抛出异常。
3、try{…}catch…:
其中try是把可能出现异常的部分括起来,如果都正常,就将try中的代码正常运行,并跳过catch语句继续向下执行;如果try里面的代码运行时发生了异常,那么try中剩下的部分就不执行了,而是跳到catch语句继续向下执行。
4、catch:
捕获相应的类型异常对象,catch块可以出现多个,catch块运行完,代码直接向下运行。
5、常见异常及结构如图:
在这里插入图片描述
6、优先级队列
优先级队列是基于二叉堆原理的优先级队列,队列用动态数组实现。他是非阻塞、非线程安全的。

插入:
(1)如果当前元素个数达到数组长度,则扩容。如果数组长度小于64,直接扩容1倍,否则扩容0.5倍;
(2)增加元素个数;
(3)上浮操作,找到合适的位置插入。在上浮的时候,如果comparator存在则用它确定优先级,否则用自然顺序确定优先级。

删除:
(1)获取最后一个元素
(2)将待删除的位置i和最后一个元素做下沉操作
(3)如果没有执行下沉操作,那么表示待删除的位置i是叶节点,需要通过上浮调整二叉堆
(4)执行上浮操作

代码实现:

public class PriorityQueue<T extends Comparable<T>> {
    private T[] queue;
    private int index; // 记录有效元素的个数

    public PriorityQueue(){
        this.queue = (T[])new Comparable[10];
    }

    // 入优先级队列
    public void push(T val){
        if(full()){
            this.queue = Arrays.copyOf(queue, queue.length*2);
        }

        if(index == 0){
            queue[index] = val;
        } else {
            siftUp(index, val); // 新插入的元素,要进行堆的上浮操作
        }
        index++;
    }
    /**
     * 堆的上浮函数
     */
    private void siftUp(int i, T val) {
        while(i > 0){
            int j = (i-1)/2;
            if(queue[j].compareTo(val) < 0){
                queue[i] = queue[j];
                i = j;
            } else {
                break;
            }
        }
        queue[i] = val;
    }
    // 出优先级队列
    public T pop(){
        if(empty())
            return null;
        T oldval = queue[0];
        --index;
        if(index > 0){
            siftDown(0, queue[index]); // 删除元素,进行堆的下沉操作
        }
        return oldval;
    }
    /**
     * 堆的下沉函数
     */
    private void siftDown(int i, T val) {
        for(int j=2*i+1; j<index; j=j*2+1){
            if(j+1 < index && queue[j+1].compareTo(queue[j]) > 0){
                j++;
            }
            if(queue[j].compareTo(val) > 0){
                queue[i] = queue[j];
                i = j;
            } else {
                break;
            }
        }
        queue[i] = val;
    }
    boolean full(){
        return index == queue.length;
    }
    boolean empty(){
        return index == 0;
    }
    public static void main(String[] args) {
        PriorityQueue<Integer> que = new PriorityQueue<>();
        Random rd = new Random();
        for (int i = 0; i < 20; i++) {
            que.push(rd.nextInt(100));
        }

        while(!que.empty()){
            System.out.print(que.pop() + " ");
        }
        System.out.println();
}

其中上浮下沉的过程与上篇堆排序中过程类似,故不详细解释。

发布了45 篇原创文章 · 获赞 11 · 访问量 4833

猜你喜欢

转载自blog.csdn.net/weixin_44187963/article/details/93317553