我制作了一个涉及二叉搜索树的程序。基本上,我将一组输入整数分成“箱”,以使每个箱的内容求和时它们的值相等。
#include <iostream>
#include <vector>
#ifndef DEBUG
#define DEBUG 0
#endif
using namespace std;
class Node {
private:
int weight = 0;
Node* leftNode;
Node* rightNode;
int bin = 0;
public:
Node() {}
Node(int weight) {
this->weight = weight;
}
void printContents() {
cout << weight << " ";
if(leftNode) leftNode->printContents();
if(rightNode) rightNode->printContents();
}
void addNode(Node* node) {
if(node->getWeight() <= this->weight) {
if(leftNode) leftNode->addNode(node);
else leftNode = node;
} else {
if(rightNode) rightNode->addNode(node);
else rightNode = node;
}
}
Node* getNode(int weight) {
if(!hasChildren()) {
if(this->weight == weight && bin == 0) return this;
else return nullptr;
} else {
Node* n = nullptr;
if(this->weight == weight && bin == 0) {
n = this;
}
Node* child;
if(leftNode && weight <= this->weight) {
child = leftNode->getNode(weight);
} else if(rightNode && weight > this->weight) {
child = rightNode->getNode(weight);
} else {
child = nullptr;
}
if(child) {
return child;
}
else return n;
}
}
bool hasChildren() {
if(leftNode || rightNode) return true;
else return false;
}
int getWeight() {
return weight;
}
void setBin(int bin) {
this->bin = bin;
}
int getBin() {
return bin;
}
void unbin() {
bin = 0;
}
void operator=(Node* node) {
this->weight = node->weight;
this->leftNode = node->leftNode;
this->rightNode = node->rightNode;
this->bin = node->bin;
}
};
class Bin {
private:
int binNum = 0;
int weight = 0;
int targetWeight = 0;
vector<Node*> nodes;
public:
Bin(int binNum, int targetWeight) {
this->binNum = binNum;
this->targetWeight = targetWeight;
}
void addNode(Node* node) {
weight += node->getWeight();
node->setBin(binNum);
nodes.push_back(node);
}
Node* removeLatestNode() {
Node* n = nodes.back();
weight -= n->getWeight();
nodes.pop_back();
n->unbin();
return n;
}
int getWeight() {
return weight;
}
bool isFull() {
if(weight == targetWeight) return true;
else return false;
}
bool willBeOverloaded(int x) {
if(weight + x > targetWeight) return true;
else return false;
}
};
void organize(Node* rootNode, int bins, int weightPerBin) {
#if DEBUG
cout << "Weight per bin: " << weightPerBin << endl;
#endif
for(int i = 1; i <= bins; i++) {
Bin bin(i, weightPerBin);
int x = weightPerBin;
while(!bin.isFull()) {
while(x > 0) {
Node* n = rootNode->getNode(x);
if (n) {
#if DEBUG
cout << "bin " << i << " : ";
cout << n->getWeight() << endl;
#endif
if (!bin.willBeOverloaded(n->getWeight())) {
#if DEBUG
cout << "adding to bin " << i << " : " << n->getWeight() << endl;
#endif
bin.addNode(n);
x = weightPerBin - bin.getWeight();
if(bin.isFull()) break;
} else {
x--;
}
} else {
x--;
}
}
if(!bin.isFull()) {
Node* n = bin.removeLatestNode();
#if DEBUG
cout << "removing from bin " << i << " : " << n->getWeight() << endl;
#endif
x = n->getWeight() - 1;
}
}
}
}
int getWeightPerBin(int* weights, int n, int bins) {
int weight = 0;
for(int i = 0; i < n; i++) {
weight += weights[i];
}
return weight/bins;
}
int main() {
int n;
int *weights;
int bins;
cin >> n;
weights = new int[n];
for(int i = 0; i < n; i++)
cin >> weights[i];
cin >> bins;
Node nodes[n];
nodes[0] = new Node(weights[0]); //the root node
for(int i = 1; i < n; i++) {
nodes[i] = new Node(weights[i]);
nodes[0].addNode(&nodes[i]);
}
organize(&nodes[0], bins, getWeightPerBin(weights, n, bins));
for(int i = 0; i < n; i++) {
cout << nodes[i].getBin() << " ";
}
return 0;
}
我在CLion IDE中开发了该程序,它运行完美。最近,我发现Xcode也可以用于开发C ++程序,因此我尝试将其与完全相同的代码一起使用。但是当我运行该程序时,它总是返回:
它返回一个名为EXC_BAD_ACCESS的错误,这是我第一次遇到该错误。我是一名具有Java良好背景的学生,目前正在为课程学习C ++。我对C ++的了解有限,我想知道这个问题是由于Xcode还是由于我的代码固有。
答案 0 :(得分:0)
您无需初始化leftNode
和rightNode
-它们不是 神奇地初始化为nullptr
,因此调用类似
void printContents() {
cout << weight << " ";
if(leftNode) leftNode->printContents();
if(rightNode) rightNode->printContents();
}
将具有未定义的行为。
我建议您在使用变量之前先对其进行初始化。