The Algorithms logo
The Algorithms
Acerca deDonar

Min Heap Two

S
import 'package:test/test.dart';

class MinHeap {
  List<int> heap;

  void buildHeap(List<int> array) {
    this.heap = _heapify(array);
  }

  List<int> _heapify(List<int> array) {
    int firstParent = (array.length - 2) ~/ 2;
    for (int i = firstParent; i >= 0; i--) {
      _siftDown(i, array.length - 1, array);
    }
    return array;
  }

  int peek() {
    if (!isEmpty()) {
      return this.heap[0];
    }
    return null;
  }

  bool isEmpty() {
    return this.heap.length == 0;
  }

  void _siftUp(int currentIndex) {
    int parentIndex = (currentIndex - 1) ~/ 2;
    while (
        parentIndex >= 0 && this.heap[parentIndex] > this.heap[currentIndex]) {
      _swap(parentIndex, currentIndex, this.heap);
      currentIndex = parentIndex;
      parentIndex = (currentIndex - 1) ~/ 2;
    }
  }

  void _siftDown(int currentIndex, int endIndex, List<int> heap) {
    int childOneIndex = (2 * currentIndex) + 1;
    int childTwoIndex;

    while (childOneIndex <= endIndex) {
      childTwoIndex =
          2 * currentIndex + 2 <= endIndex ? 2 * currentIndex + 2 : -1;
      int indexToSwap;
      if (childTwoIndex != -1 && heap[childTwoIndex] < heap[childOneIndex]) {
        indexToSwap = childTwoIndex;
      } else {
        indexToSwap = childOneIndex;
      }

      if (heap[currentIndex] > heap[indexToSwap]) {
        _swap(currentIndex, indexToSwap, heap);
        currentIndex = indexToSwap;
        childOneIndex = (2 * currentIndex) + 1;
      } else {
        break;
      }
    }
  }

  void insert(int value) {
    this.heap.add(value);
    _siftUp(this.heap.length - 1);
  }

  int remove() {
    if (!isEmpty()) {
      _swap(0, this.heap.length - 1, this.heap);
      int minElement = this.heap.removeLast();
      _siftDown(0, this.heap.length - 1, this.heap);
      return minElement;
    }
    return null;
  }

  void _swap(int left, int right, List<int> array) {
    int temp;
    temp = array[left];
    array[left] = array[right];
    array[right] = temp;
  }
}

void main() {
  MinHeap minheap = new MinHeap();
  List<int> array = [48, 12, 24, 7, 8, -5, 24, 391, 24, 56, 2, 6, 8, 41];
  minheap.buildHeap(array);
  test(('Test case 1'), () {
    expect(minheap.remove(), equals(-5));
    expect(minheap.isEmpty(), isFalse);
    minheap.insert(-100);
    expect(minheap.peek(), equals(-100));
    minheap.insert(-100);
    expect(minheap.remove(), equals(-100));
    expect(minheap.remove(), equals(-100));
  });

  test(('Test case 2'), () {
    array = [-7, 2, 3, 8, -10, 4, -6, -10, -2, -7, 10, 5, 2, 9, -9, -5, 3, 8];
    minheap = new MinHeap();
    minheap.buildHeap(array);
    expect(minheap.remove(), equals(-10));
    expect(minheap.peek(), equals(-10));
    minheap.insert(-8);
    expect(minheap.peek(), equals(-10));
    expect(minheap.remove(), equals(-10));
    expect(minheap.peek(), equals(-9));
    expect(minheap.isEmpty(), isFalse);
    minheap.insert(-8);
    expect(minheap.peek(), equals(-9));
  });
}