基于四叉树的小顶堆(最小优先队列)

实现来自Go源码

 

从下往上调整堆

func siftupTimer(t []*timer, i int) bool {
   if i >= len(t) {
      return false
   }
   when := t[i].when
   tmp := t[i]
   for i > 0 { // 除非到达堆顶,否则每次和当前父节点进行比较,如果当前节点更小,那么交换
      p := (i - 1) / 4 // parent
      if when >= t[p].when {
         break
      }
      t[i] = t[p]
      t[i].i = i
      i = p
   }
   if tmp != t[i] {
      t[i] = tmp
      t[i].i = i
   }
   return true
}

从上往下调整堆

func siftdownTimer(t []*timer, i int) bool {
   n := len(t)
   if i >= n {
      return false
   }
   when := t[i].when
   tmp := t[i]
   for { // 这里的前一部分在确定哪个子节点最小,可以使用 for 循环遍历数组来优化
      c := i*4 + 1 // left child
      c3 := c + 2  // mid child
      if c >= n {
         break
      }
      w := t[c].when
      if c+1 < n && t[c+1].when < w {
         w = t[c+1].when
         c++
      }
      if c3 < n {
         w3 := t[c3].when
         if c3+1 < n && t[c3+1].when < w3 {
            w3 = t[c3+1].when
            c3++
         }
         if w3 < w {
            w = w3
            c = c3
         }
      }
      if w >= when { // 如果子节点最小值 >= 当前节点,则结束
         break
      }
      t[i] = t[c]
      t[i].i = i
      i = c
   }
   if tmp != t[i] {
      t[i] = tmp
      t[i].i = i
   }
   return true
}

不同情况的小顶堆调整
插入新元素时,放置到堆的末尾,基于这个元素向上调整堆。
删除某个元素时
1. 如果是最后一个元素,那么直接删除。
2. 否则,把最后一个元素置为当前元素,基于当前元素,先向上调整堆,再向下调整堆。

posted on 2023-02-19 19:50  王景迁  阅读(78)  评论(0编辑  收藏  举报

导航