基于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
相关产品推荐
相关产品推荐

