• Java数据结构之堆结构,基于泛型类中泛型数组的创建


    首先创建Node类型作为堆的元素类型

    class Node{
        public int nod;
        public int value;
        public Node(int nod, int value) {
            this.nod = nod;
            this.value = value;
        }
        
        public String toString() {
            return ""+value;
        }
    }

    堆结构的元素必须能够比较,定义Node类的比较器

    class NodeComparator implements Comparator<Node>{
        @Override
        public int compare(Node o1, Node o2) {
            return o1.value - o2.value;
        }
    }

    首先明确,在Java里面要创建泛型数组需要借助import java.lang.reflect.Array;

    创建类HeapExample1,其构造函数之一为:

        @SuppressWarnings("unchecked")
        public HeapExamples1(Class<T> type, boolean minheap, Comparator<T> cmpr) {
            this.minheap = minheap;
            this.heap = (T[]) Array.newInstance(type, DEFAULT_CAPACITY);
            this.cmpr = cmpr;
        }

      其中this.heap是T[]类型,创建泛型数组的方法是(T[]) Array.newInstance(type, DEFAULT_CAPACITY);

      其中type应为Node.class,DEFAULT_CAPACIT是数组长度。事实上这句话的意思就是this.heap = new T[DEFAULT_CAPACITY];然而这么做是会报错的,Java不允许通过new关键字创建泛型数组,具体原因可以百度。

      不过数组长度不代表数组的元素个数,数组长度是底层数组长度,如果不够需要扩容,而元素个数为private int heapLength;。和栈结构类同,除了确定长度的底层数组之外(如果不够再扩容),还定义了栈指针表示栈的高度,用于判断是否为空,或者是否溢出。

      堆结构的基本操作为插入,删除,返回元素个数,判断是否为空。还有自上而下调整和自下而上调整。插入和删除的过程中,通过调整操作来保证堆结构始终有序,事实上堆结构也是优先队列的基础。

    堆结构的完整代码为:

    public class HeapExamples1<T> {
    
        private boolean minheap;
        private T[] heap;
        private Comparator<T> cmpr;
        private int heapLength;
        
        private int DEFAULT_CAPACITY = 0x10; // 默认容量16
        
        @SuppressWarnings("unchecked")
        public HeapExamples1(Class<T> type, boolean minheap, Comparator<T> cmpr) {
            this.minheap = minheap;
            this.heap = (T[]) Array.newInstance(type, DEFAULT_CAPACITY);
            this.cmpr = cmpr;
        }
    
        public HeapExamples1(Class<T> type, boolean minheap) {
            this(type, minheap, null);
        }
    
        public HeapExamples1(Class<T> type) {
            this(type, true, null);
        }
    
        public HeapExamples1(Class<T> type, boolean minheap, T[]values, Comparator<T> cmpr) {
            this(type, minheap, cmpr);
            for (int i = 0; i < values.length; i++)
            {
                this.insert(values[i]);
    //            this.printHeap();
            }
        }
        
        public boolean isEmpty() {
            return this.heapLength == 0;
        }
        public int size() {
            return this.heapLength;
        }
        public void printHeap(){
            for (int i = 0; i < heapLength; i++) {
                System.out.print(heap[i].toString()+", ");
            }
            System.out.println("
    ");
        }
        
        public void insert(T x) {
            this.heap[this.heapLength++] = x;
            for (int i = this.heapLength/2-1;i>0; i = (i-1)/2)
                shif(i);
            shif(0);
        }
        
        @SuppressWarnings("unchecked")
        public void shif(int parent) {
            //Page289
            int end = this.size() - 1;
            int child = 2 * parent + 1;
            T value = this.heap[parent];
            while (child <= end) {
                int comp = 0;
                if (child < end) {
                    T left = this.heap[child], right = this.heap[child+1];
                    if (this.cmpr == null)
                        comp = ((Comparable<T>)left).compareTo(right);
                    else
                        comp = this.cmpr.compare(left, right);
                    if(this.minheap ? comp>0 : comp<0)
                        child++;
                }
                if (this.cmpr==null)
                    comp = ((Comparable<T>)value).compareTo(this.heap[child]);
                else
                    comp = this.cmpr.compare(value, this.heap[child]); 
                if (this.minheap ? comp>0 : comp<0) {
                    this.heap[parent] = this.heap[child];
                    parent = child;
                    child = 2*parent+1;
                }else {
                    break;
                }
            }
            this.heap[parent] = value;
        }
        
        public T removeRoot() {
            //Page290
            if (this.isEmpty())
                return null;
            T x = (T)this.heap[0];
            this.heap[0] = this.heap[this.heapLength-1];
            
            this.heap[this.heapLength-1] = null;
            this.heapLength--;
            
            if(this.heapLength>1)
                shif(0);
            return x;
        }
    
        public static void main(String[] args) {
            Node[] nodes = {new Node(0, 3),new Node(1,44),new Node(2,38),new Node(4,47),new Node(5,15),
                    new Node(6,36), new Node(8,27), new Node(7,26),new Node(9,2)};
            System.out.println("大顶堆");
            HeapExamples1<Node> pq = new HeapExamples1<Node>(Node.class, true, nodes, new NodeComparator());
            System.out.println("堆的内容:");
            pq.printHeap();
            System.out.println("按顺序输出:");
            while (!pq.isEmpty()) {
                Node temp = pq.removeRoot();
                System.out.println("(value:"+temp.value+", nod:"+temp.nod+")");
            }
            
        }
    }

    结果:

    大顶堆
    堆的内容:
    2, 3, 27, 15, 44, 38, 36, 47, 26,

    按顺序输出:
    (value:2, 9)
    (value:3, 0)
    (value:15, 5)
    (value:26, 7)
    (value:27, 8)
    (value:36, 6)
    (value:38, 2)
    (value:44, 1)
    (value:47, 4)

  • 相关阅读:
    POJ 2031 Building a Space Station (最小生成树)
    HDU 1875 畅通工程再续 (最小生成树)
    HDU 1233 还是畅通工程 (最小生成树)
    POJ 1679 The Unique MST (最小生成树)
    js调试工具console详解
    使用阿里云集成包快速搭建LAMP+FTP教程
    PHP使用纯真IP数据库
    mysql配置文件my.cnf解析
    Javascript常用函数收集(不定期更新)
    性能测试工具:AB
  • 原文地址:https://www.cnblogs.com/zhaoke271828/p/14521954.html
Copyright © 2020-2023  润新知