跳过正文

数据结构与算法-6-堆

·426 字· loading · loading ·
Masterlong
作者
Masterlong
熬夜,但是世界之夜
目录
数据结构与算法 - 这篇文章属于一个选集。
§ 8: 本文

堆Heap / 优先队列(ADT,closely related) #

基本操作

  • Insert(enqueue)
  • removeFirst(dequeue)

实现

  • LIST, BST

数据结构-存储

Def
#

完全二叉树

#
  • 任何结点的值$$\leq$$孩子:小堆
  • 任何结点的值$$\geq$$孩子:大堆

因为堆是CBT,所以一般用数组形式

物理定义:

$${k_0,k_2,k_2,...,k_n}有k_1\leq k_{2i+1} 且k_1\leq k_{2i+2}, i=0,1,2,...,n/2-1 (小堆)$$

大堆,同理

一个数组+2个整型变量可描述一个堆

  • 数组放元素
  • maxSize约束大小
  • size实际结点数

基本操作

  • insert
  • remove
  • removeFirst
  • buildHeap

上代码

// Heap class
template <typename E, typename Comp> class heap {
private:
    E* Heap; // Pointer to the heap array
    int maxsize; // Maximum size of the heap
    int n; // Number of elements now in the heap
    // Helper function to put element in its correct place
    // 对于左右子树已经是堆的完全二叉树,调整整棵树变为堆
    void siftdown(int pos) {
        while (!isLeaf(pos)) { // Stop if pos is a leaf
        int j = leftchild(pos); int rc = rightchild(pos);
        if ((rc < n) && Comp::prior(Heap[rc], Heap[j]))
        j = rc; // Set j to greater child’s value
        if (Comp::prior(Heap[pos], Heap[j])) return; // Done
        swap(Heap, pos, j);
        pos = j; // Move down
    }
    }
public:
    heap(E* h, int num, int max) // Constructor
    { Heap = h; n = num; maxsize = max; buildHeap(); }
    int size() const // Return current heap size
    { return n; }
    bool isLeaf(int pos) const // True if pos is a leaf
    { return (pos >= n/2) && (pos < n); }
    int leftchild(int pos) const
    { return 2*pos + 1; } // Return leftchild position
    int rightchild(int pos) const
    { return 2*pos + 2; } // Return rightchild position
    int parent(int pos) const // Return parent position
    { return (pos-1)/2; }
    void buildHeap() // Heapify contents of Heap
    { for (int i=n/2-1; i>=0; i--) siftdown(i); }
    // Insert "it" into the heap
    void insert(const E& it) {
    Assert(n < maxsize, "Heap is full");
    int curr = n++;
    Heap[curr] = it; // Start at end of heap
    // Now sift up until curr’s parent > curr
    while ((curr!=0) &&
    (Comp::prior(Heap[curr], Heap[parent(curr)]))) {
    swap(Heap, curr, parent(curr));
    curr = parent(curr);
    }
    }
    // Remove first value
    E removefirst() {
    Assert (n > 0, "Heap is empty");
    swap(Heap, 0, --n); // Swap first with last value
    if (n != 0) siftdown(0); // Siftdown new root val
    return Heap[n]; // Return deleted value
    }
    // Remove and return element at specified position
    E remove(int pos) {
    Assert((pos >= 0) && (pos < n), "Bad position");
    if (pos == (n-1)) n--; // Last element, no work to do
    else
    {
    swap(Heap, pos, --n); // Swap with last value
    while ((pos != 0) &&
    (Comp::prior(Heap[pos], Heap[parent(pos)]))) {
    swap(Heap, pos, parent(pos)); // Push up large key
    pos = parent(pos);
    }
    if (n != 0) siftdown(pos); // Push down small key
    }
    return Heap[n];
	}
};

建堆

给定一个CBT,求一个堆:从下往上/从后往前,对每个结点siftdown

数据结构与算法 - 这篇文章属于一个选集。
§ 8: 本文

相关文章

数据结构与算法-5-哈夫曼树
·85 字· loading · loading
数据结构与算法-4-树
·1738 字· loading · loading
数据结构与算法-4-树-作业1
·80 字· loading · loading