You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义模板化Priority Queue的Push/Pop函数异常排查求助

嘿,我帮你找到了问题的根源——两个关键错误组合在一起,导致你的优先级队列输出完全不符合预期。咱们一步步拆解:

第一个致命错误:Top函数完全写反了

你的top()函数返回的是数组最后一个元素value[siz-1],但最大堆的堆顶元素应该是数组的第一个元素value[0]啊!这直接导致你打印的根本不是优先级最高的元素,而是队列里的最后一个元素。

修正后的Top函数应该是这样:

V top() const {
    // 最好加个非空判断,避免空队列访问出错,比如:
    // if (empty()) throw std::runtime_error("Priority queue is empty");
    return value[0];
}

第二个核心错误:Pop函数逻辑完全偏离堆的实现规则

你的Pop函数做了完全相反的操作,正确的最大堆Pop流程应该是:

  1. 取出堆顶元素(要返回的优先级最高值)
  2. 把队列最后一个元素移到堆顶位置
  3. 缩小队列大小
  4. 将这个新堆顶元素下沉到合适的位置(和左右子节点比较,交换到符合堆性质的位置)

但你的代码先从堆顶开始用子节点覆盖父节点,这会直接丢失元素、破坏堆结构,后续的操作自然全错了。

下面是修复后的Pop函数:

template <class V>
V MyPriorityQueue<V>::pop() {
    // 先保存堆顶元素,最后返回
    V val = value[0];
    // 把最后一个元素移到堆顶,替代被取出的元素
    value[0] = value[siz - 1];
    // 队列大小减一
    siz--;
    
    // 开始下沉操作:把堆顶元素放到正确位置
    int index = 0;
    while (true) {
        int left_child = 2 * index + 1;
        int right_child = 2 * index + 2;
        int largest_node = index; // 记录当前最大的节点索引
        
        // 比较左子节点和当前节点,更新最大节点
        if (left_child < siz && value[left_child] > value[largest_node]) {
            largest_node = left_child;
        }
        // 比较右子节点和当前最大节点,更新最大节点
        if (right_child < siz && value[right_child] > value[largest_node]) {
            largest_node = right_child;
        }
        
        // 如果当前节点已经是最大的,说明下沉完成,退出循环
        if (largest_node == index) {
            break;
        }
        
        // 交换当前节点和最大子节点
        swap(value[index], value[largest_node]);
        // 继续向下处理
        index = largest_node;
    }
    
    return val;
}

验证修复效果

把Top和Pop函数都修正后,用你原来的测试代码运行:

MyPriorityQueue<int> pq;
pq.push(14);
pq.push(6);
pq.push(3);
pq.push(19);
pq.push(9);

while(!pq.empty()) {
    cout << pq.top() << endl;
    pq.pop();
}

就能得到预期的输出:19 → 14 → 9 → 6 → 3。

另外提一句,你的Push函数逻辑是对的,扩容和上浮操作都没问题,不用修改~

内容的提问来源于stack exchange,提问作者Haider Bokhari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:01:35