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

基于Item类构建按名称排序的最大堆无输出问题求助

问题:按name排序的最大堆调用后无输出排查

我用包含name、price、category属性的Item类构建最大堆,按price排序的堆功能正常,但调用按name排序的Build_Max_By_Name函数后无任何输出。相关代码如下:

Item类定义

class Item
{
    int Price;

public:
    Item(string name, string category, int price);
    string itemName;
    string Category;

    string get_category();
// operators to compare between prices
    bool operator<(Item &another);
    bool operator>(Item &another);
    bool operator<=(Item &another);
    bool operator>=(Item &another);
// operators to compare between names
    bool operator>(string &another);
    bool operator<(string &another);
    bool operator<=(string &another_name);
    bool operator>=(string &another_name);
    void print();
    bool operator==(Item &another);
};

按price排序的堆化函数(功能正常)

void Heap::Max_heapify(int size, int i)
{
    int left = 2*i+1;
    int right = 2*i+2;
    int Max = i;

    if (heap[Max] < heap[left] and left < size)
    {
        Max = left;
    }
    if (heap[Max] < heap[right] and right < size)
    {
        Max = right;
    }

    if (Max != i)
    {
        swap(heap[i], heap[Max]);
        Max_heapify(size, Max);
    }
}
void Heap::Build_Max()
{
    for (int i = (heap.size() / 2 - 1); i >= 0; i--)
    {
        Max_heapify(heap.size(), i);
    }
}

按name排序的堆化函数(无输出)

void Heap::Max_heapify_By_Name(int size, int i)
{

    int left = 2*i+1;
    int right = 2*i+2;
    int Max = i;
    if ((heap[Max] < heap[left].itemName) and left <= size)
    {
        Max = left;
    }
    if ((heap[Max] < heap[right].itemName) and right <= size)
    {
        Max = right;
    }
    if (Max != i)
    {
        swap(heap[i], heap[Max]);
        Max_heapify_By_Name(size, Max);
    }
}
void Heap::Build_Max_By_Name()
{
    int n = heap.size();
    for (int i = floor(n / 2) - 1; i >= 0; i--)
    {
        cout << i << endl;
        Max_heapify_By_Name(n, i);
    }
}

Heap类定义

class Heap
{
    vector<Item> heap;

public:
    Heap(vector<Item>);
    void insert_item(Item item);
    void Delete_item(int index);
    int Get_parent(int num);
    int Get_Left_Chlid(int num);
    int Get_Right_Child(int num);
    void Insert_Item(Item item);
    void Heap_sort();    
    void Heap_sort_Name();
    void Max_heapify(int size ,int i );
    void Min_heapify(int i);
    void Build_Max();
    void Build_Min();
    void Max_heapify_By_Name(int size,int i);
    void Min_heapify_By_Name(int i);
    void Build_Max_By_Name();
    void Build_Min_By_Name();
    void print_heap();
};

main函数

int main()
{
    Item i1("item1", "food", 123);
    Item i2("item5", "food", 120);
    Item i3("item4", "food", 156);
    Item i4("item6", "food", 1234);
    Item i5("item3", "food", 122);
    Item i6("item2", "food", 111);
    Item i7("item7", "food", 161);
    vector<Item> arr;
    //
    arr.push_back(i1);
    arr.push_back(i2);
    arr.push_back(i3);
    arr.push_back(i4);
    arr.push_back(i5);
    arr.push_back(i6);
    arr.push_back(i7);
    //
    Heap a(arr);
    //
    a.Build_Max_By_Name();
    a.print_heap();
}

运算符重载实现(已验证正常)

bool Item::operator<(Item &another)
{ 
// to compare prices
    return (this->Price < another.Price);
}
bool Item::operator<(string &another_name)
{
    return (this->itemName < another_name);
}

问题排查与修复

1. 数组越界判断错误

Max_heapify_By_Name中,子节点边界判断用了left <= size和right <= size,但堆的有效下标范围是0到size-1,这会导致访问heap[size](超出vector的有效范围),触发未定义行为,程序可能崩溃或无输出。

修复:
将判断条件改为left < size和right < size,与按price排序的堆化函数保持一致:

void Heap::Max_heapify_By_Name(int size, int i)
{
    int left = 2*i+1;
    int right = 2*i+2;
    int Max = i;
    if (left < size && heap[Max] < heap[left].itemName)
    {
        Max = left;
    }
    if (right < size && heap[Max] < heap[right].itemName)
    {
        Max = right;
    }
    if (Max != i)
    {
        swap(heap[i], heap[Max]);
        Max_heapify_By_Name(size, Max);
    }
}

2. 堆构建循环起始值冗余调用floor

Build_Max_By_Name中,n是整数,n/2本身就是整数除法,调用floor完全多余,可能引发不必要的类型转换问题。

修复:
去掉floor,直接计算起始下标:

void Heap::Build_Max_By_Name()
{
    int n = heap.size();
    for (int i = (n / 2 - 1); i >= 0; i--)
    {
        cout << i << endl;
        Max_heapify_By_Name(n, i);
    }
}

3. 运算符重载的参数绑定问题

heap[Max] < heap[left].itemName调用的是Item::operator<(string&),但heap[left].itemName是右值,C++中右值不能绑定到非const引用参数,会导致编译错误或未定义行为。

修复:
将字符串比较的运算符重载参数改为const string&,同时将成员函数设为const(比较操作不修改对象):

// Item类声明修改
class Item
{
    // ... 其他成员 ...
    bool operator<(const string &another_name) const;
    // 同步修改其他字符串比较运算符的参数和const属性
};

// 运算符实现修改
bool Item::operator<(const string &another_name) const
{
    return (this->itemName < another_name);
}

4. 确认print_heap函数实现

如果修复后仍无输出,检查Heap::print_heap是否正确遍历heap向量并调用Item::print(),示例实现:

void Heap::print_heap()
{
    for (auto &item : heap)
    {
        item.print();
        cout << endl;
    }
}

同时确保Item::print()函数正确输出itemName等属性。

内容的提问来源于stack exchange,提问作者ahmed mohsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:24:56