一个自定义的堆数据结构

这段代码实现了一个自定义的堆数据结构(MyHeap),它支持插入、删除和重新排序操作。堆内部使用ArrayList存储元素,并使用HashMap存储元素的索引,以便快速查找和更新。堆的大小由heapSize变量维护。堆的比较规则由传入构造函数的Comparator对象决定。

以下是代码中各个方法的功能和细节分析:

  1. isEmpty():检查堆是否为空,即堆的大小是否为0。
  2. size():返回堆的大小。
  3. contains(T key):检查堆中是否包含指定的元素。
  4. push(T value):向堆中插入一个元素。首先将元素添加到ArrayList中,然后将其索引添加到HashMap中,最后调用heapInsert()方法调整堆的结构。
  5. pop():从堆中删除并返回最小元素(或最大元素,取决于Comparator的实现)。首先获取堆顶元素,然后将其与最后一个元素交换,接着从ArrayList和HashMap中移除这两个元素,最后调用heapify()方法调整堆的结构。
  6. resign(T value):重新调整指定元素的堆位置。首先获取元素的索引,然后调用heapInsert()heapify()方法进行调整。
  7. heapInsert(int index):将指定索引处的元素向上移动,直到满足堆的性质。
  8. heapify(int index, int heapSize):将指定索引处的元素向下移动,直到满足堆的性质。
  9. swap(int i, int j):交换ArrayList中两个指定索引处的元素,并更新HashMap中的索引映射。
  10. 这个堆是大根堆还是小根堆取决于Comparator的实现

    具体分析如下:

  11. 堆的插入过程:根据代码中的heapInsert方法,新元素总是从堆的末尾插入,随后通过不断地与其父节点比较并交换位置,直到满足堆的性质为止。如果comparator.compare(heap.get(index), heap.get((index - 1) / 2)) < 0,说明新插入的元素小于其父节点,对于小根堆则需要继续向上调整,而对于大根堆则不需要。
  12. 堆的删除过程:从pop方法来看,方法返回的是heap.get(0),即堆的第一个元素。在删除操作后,会执行heapify方法来重新调整堆的结构以维护堆的性质。如果comparator.compare(heap.get(largest), heap.get(index)) < 0,则交换这两个元素,并继续向下调整,这是符合小根堆性质的操作。
  13. Comparator的角色:堆的创建和操作过程中,Comparator决定了元素的排序方式。如果Comparator定义的是小于号(<),则堆为小根堆;反之如果定义的是大于号(>),则堆为大根堆。考虑到代码片段中使用了<符号,这暗示了它更可能是一个小根堆。
  14. 代码实现细节:从代码看,pushpop方法的操作都是基于小根堆的逻辑来实现的。例如,在push方法中,新元素是从底部向上进行调整,而在pop方法中,顶部元素被替换后,从顶部向下进行调整,这是典型的小根堆操作。总结,根据上述分析,特别是Comparator的使用和堆的操作逻辑,可以确认这是一个小根堆
    import java.io.PushbackInputStream;
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.HashMap;
    
    public class Test4 {
        public static class MyHeap<T>{
            private ArrayList<T> heap;
            private HashMap<T , Integer> indexMap;
            private int heapSize;
            private Comparator<? super T>comparator;
    
    
        public MyHeap(Comparator<? super T> com) {
            heap = new ArrayList<>();
            indexMap = new HashMap<>();
            heapSize = 0;
            comparator = com;
        }
    
        public boolean isEmpty(){
            return heapSize==0;
        }
    
        public int size(){
            return heapSize;
        }
    
        public boolean contains(T key){
            return indexMap.containsKey(key);
        }
    
        public void push(T value){
            heap.add(value);
            indexMap.put(value , heapSize);
            heapInsert(heapSize++);
        }
    
        public T pop(){
            T ans =  heap.get(0);
            int end = heapSize-1;
            swap(0 , end);
            heap.remove(end);
            indexMap.remove(ans);
            heapify(0 , --heapSize);
            return ans;
        }
    
        public void resign(T value){
            int valueIndex = indexMap.get(value);;
            heapInsert(valueIndex);
            heapify(valueIndex , heapSize);
        }
    
        private void heapInsert(int index){
         while(comparator.compare(heap.get(index) ,  heap.get( (index - 1)/2) ) < 0 ){
                swap(index , (index -1)/2);
                index = (index-1)/2;
            }
        }
    
        private void heapify(int index , int heapSize){
            int left = index*2 +1;
            while (left <heapSize){
                int largest = left +1 <heapSize && (comparator.compare(heap.get(left +1), heap.get(left)) <0) ? left+1 :left;
                largest = comparator.compare(heap.get(largest) , heap.get(index)) < 0 ? largest :index;
                if(largest == index){
                    break;
                }
                swap(largest , index);
                index = largest;
                left = index*2 +1;
            }
        }
    
        private void swap(int i ,int j){
            T o1 = heap.get(i);
            T o2 = heap.get(j);
            heap.set(i , o2);
            heap.set(j , o1);
            indexMap.put(o1 , j);
            indexMap.put(o2 , i);
            }
        }
    }
    
  • 33
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值