Szukaj…


Wprowadzenie

Sterta binarna to kompletne drzewo binarne, które spełnia właściwość porządkowania sterty. Kolejność może być jednego z dwóch typów: właściwość min-heap: wartość każdego węzła jest większa lub równa wartości jego rodzica, z elementem minimalnej wartości u podstawy.

Przykład

Sterty min

        1
      /   \
     2     3
    / \   / \
   4   5 6   7

Powyższe drzewo jest stertą min, ponieważ korzeń jest minimum wśród wszystkich węzłów w drzewie. Po tej samej właściwości znajdują się wszystkie węzły w drzewie.

Max-Heap

        7
      /   \
     6     5
    / \   / \
   4   3 2   1

Powyższe drzewo jest stertą maksymalną, ponieważ korzeń jest maksymalny wśród wszystkich węzłów w drzewie. Po tej samej właściwości znajdują się wszystkie węzły w drzewie.

Operacje obsługiwane przez Min-Heap

  1. getMin () - Zwraca element główny. Ponieważ jest to pierwszy element w tablicy, możemy pobrać minimalny element w O(1)

  2. extractMin () - Usuwa minimalny element ze sterty. Ponieważ po usunięciu elementu drzewo musi spełniać właściwość Min-Heap, dlatego wykonywana jest operacja ( heapify ) w celu zachowania właściwości drzewa. To zajmuje O(logn)

  3. dereaseKey () - Zmniejsza wartość klucza. Złożoność czasu dla tej operacji wynosi O(logn)

  4. insert () - Klucz jest zawsze wstawiany na końcu drzewa. Jeśli dodany klucz nie jest zgodny z właściwością sterty, musimy przeskoczyć w górę, aby drzewo spełniało właściwość sterty. Ten krok zajmuje O(logn) czas.

  5. delete () - Ten krok zajmuje czas O(logn) Aby usunąć klucz, najpierw musimy zmniejszyć wartość klucza do wartości minimalnej, a następnie wyodrębnić tę wartość minimalną.

Zastosowanie sterty

  1. Sortuj sterty
  2. Kolejka priorytetowa

Sterta jest używana w wielu algorytmach graficznych, takich jak Dijkstra's Shortest Path i Prim's Minimum Spanning Tree .

Implementacja w Javie

public class MinHeap {
    
    int hArr[];
    int capacity;
    int heapSize;
    
    public MinHeap(int capacity){
        this.heapSize = 0;
        this.capacity = capacity;
        hArr = new int[capacity];
    }
    
    public int getparent(int i){
        return (i-1)/2;
    }
    
    public int getLeftChild(int i){
        return 2*i+1;
    }
    
    public int getRightChild(int i){
        return 2*i+2;
    }
    
    public void insertKey(int k){
        if(heapSize==capacity)
            return;
        
        heapSize++;
        int i = heapSize-1;
        hArr[i] = k;
        
        while(i!=0 && hArr[getparent(i)]>hArr[i]){
            swap(hArr[i],hArr[getparent(i)]);
            i = getparent(i);
        }
    }
    
    public int extractMin(){
        if(heapSize==0)
            return Integer.MAX_VALUE;
        
        if(heapSize==1){
            heapSize--;
            return hArr[0];
        }
        
        int root = hArr[0];
        hArr[0] = hArr[heapSize-1];
        heapSize--;
        MinHeapify(0);
        
        return root;
    }
    
    public void decreaseKey(int i , int newVal){
        hArr[i] = newVal;
        while(i!=0 && hArr[getparent(i)]>hArr[i]){
            swap(hArr[i],hArr[getparent(i)]);
            i = getparent(i);
        }
    }
    
    public void deleteKey(int i){
        decreaseKey(i, Integer.MIN_VALUE);
        extractMin();
    }
    
    public void MinHeapify(int i){
        int l = getLeftChild(i);
        int r = getRightChild(i);
        int smallest = i;
        if(l<heapSize && hArr[l] < hArr[i])
            smallest = l;
        if(l<heapSize && hArr[r] < hArr[smallest])
            smallest = r;
        
        if(smallest!=i){
            swap(hArr[i], hArr[smallest]);
            MinHeapify(smallest);
        }
    }
    
    public void swap(int x, int y){
        int temp = hArr[x];
        hArr[x] = hArr[y];
        hArr[y] = temp;
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow