二进制搜索树最佳拟合算法:输出不正确
Binary Search Tree Best Fit Alg.: Incorrect Output
免责声明:这是学校作业
大家好。我已经在这个Bin Packing程序上辛苦工作了两周,我还有最后一个障碍要克服:我的二进制搜索树的查找功能给了我不正确的结果。
二进制搜索树.cpp
#include "BinarySearchTree.h"
void BinarySearchTree::insert(int capacity, int binNumber)
{
// Insert the Pair into the tree. Overwrite existing
// pair, if any, with same key.
// find place to insert
BinaryTreeNode *p = root,
*pp = NULL;
while (p != NULL)
{// examine p->capacity
pp = p;
// move p to a child
if (capacity <= p->capacity)
p = p->leftChild;
else
p = p->rightChild;
}
// get a node for the Pair and attach to pp
BinaryTreeNode *newNode = new BinaryTreeNode (capacity, binNumber);
if (root != NULL) // the tree is not empty
if (capacity <= pp->capacity)
pp->leftChild = newNode;
else
pp->rightChild = newNode;
else
root = newNode; // insertion into empty tree
treeSize++;
}
void BinarySearchTree::erase(BinaryTreeNode *n)
{
// Delete the pair, if any, whose key equals n.
// search for node with key theKey
BinaryTreeNode *p = root,
*pp = NULL;
while (p != NULL && p->capacity != n->capacity)
{// move to a child of p
pp = p;
if (n->capacity < p->capacity)
p = p->leftChild;
else
p = p->rightChild;
}
if (p == NULL)
return; // no pair with key theKey
// restructure tree
// handle case when p has two children
if (p->leftChild != NULL && p->rightChild != NULL)
{// two children
// convert to zero or one child case
// find largest element in left subtree of p
BinaryTreeNode *s = p->leftChild,
*ps = p; // parent of s
while (s->rightChild != NULL)
{// move to larger element
ps = s;
s = s->rightChild;
}
// move largest from s to p, can't do a simple move
// p->capacity= s->capacity as key is const
BinaryTreeNode *q = new BinaryTreeNode (s->capacity,s->binNumber, p->leftChild, p->rightChild, p->parent);
if (pp == NULL)
root = q;
else if (p == pp->leftChild)
pp->leftChild = q;
else
pp->rightChild = q;
if (ps == p) pp = q;
else pp = ps;
delete p;
p = s;
}
// p has at most one child
// save child pointer in c
BinaryTreeNode *c;
if (p->leftChild != NULL)
c = p->leftChild;
else
c = p->rightChild;
// delete p
if (p == root)
root = c;
else
{// is p left or right child of pp?
if (p == pp->leftChild)
pp->leftChild = c;
else pp->rightChild = c;
}
treeSize--;
delete p;
}
BinaryTreeNode* BinarySearchTree::find(const int objectSize) const
{
// Return pointer to pair with smallest key >= objectSize.
// Return NULL if no element has key >= objectSize.
BinaryTreeNode *currentNode = root,
*bestElement = NULL; // element with smallest key
// >= theKey found so far
// search the tree
while (currentNode != NULL) {
// is currentNode->capacity a candidate?
if (currentNode->capacity >= objectSize)
{
// smaller keys in left subtree only
bestElement = currentNode;
currentNode = currentNode->leftChild;
}
else if (currentNode->capacity < objectSize)
{
// no, currentNode->capacity is too small
// try right subtree
currentNode = currentNode->rightChild;
}
}
return bestElement;
}
BinaryTreeNode.h
struct BinaryTreeNode
{
public:
BinaryTreeNode *leftChild;
BinaryTreeNode *rightChild;
BinaryTreeNode *parent;
int capacity;
int binNumber;
BinaryTreeNode() {leftChild = rightChild = parent = NULL;}
BinaryTreeNode(const int& c, const int& b):capacity(c), binNumber(b)
{
leftChild = rightChild = parent = NULL;
}
BinaryTreeNode(const int& c, const int& b, BinaryTreeNode* l, BinaryTreeNode* r, BinaryTreeNode* p):capacity(c), binNumber(b)
{
leftChild = l;
rightChild = r;
parent = p;
}
};
BinPacking.cpp
void BinPacking::bestFitPack(int *objectSize, int numberOfObjects, int binCapacity)
{// Output best-fit packing into bins of size binCapacity.
// objectSize[1:numberOfObjects] are the object sizes.
int n = numberOfObjects;
int binsUsed = 0;
BinarySearchTree theTree; // tree of bin capacities
BinaryTreeNode theBin;
// pack objects one by one
for (int i = 1; i <= n; i++)
{// pack object i
// find best bin
BinaryTreeNode *bestBin = theTree.find(objectSize[i]);
if (bestBin == NULL)
{// no bin large enough, start a new bin
theBin.capacity = binCapacity;
theBin.binNumber = ++binsUsed;
}
else
{// remove best bin from theTree
theBin = *bestBin;
theTree.erase(bestBin);
}
cout << "Pack object " << i << " in bin " << theBin.binNumber << endl;
// insert bin in tree unless bin is full
theBin.capacity -= objectSize[i];
if (theBin.capacity > 0)
theTree.insert(theBin.capacity, theBin.binNumber);
}
}
用户输入到主(未显示)
# of objects = 12
Bin capacity = 6
Sizes of objects:
object 1 = 2
object 2 = 5
object 3 = 5
object 4 = 1
object 5 = 1
object 6 = 3
object 7 = 4
object 8 = 6
object 9 = 2
object 10 = 5
object 11 = 6
object 12 = 1
预期输出
Pack object 1 in bin 1
Pack object 2 in bin 2
Pack object 3 in bin 3
Pack object 4 in bin 2
Pack object 5 in bin 3
Pack object 6 in bin 1
Pack object 7 in bin 4
Pack object 8 in bin 5
Pack object 9 in bin 4
Pack object 10 in bin 6
Pack object 11 in bin 7
Pack object 12 in bin 1
电流输出
Pack object 1 in bin 1
Pack object 2 in bin 2
Pack object 3 in bin 3
Pack object 4 in bin 3
Pack object 5 in bin 3
Pack object 6 in bin 1
Pack object 7 in bin 4
Pack object 8 in bin 5
Pack object 9 in bin 4
Pack object 10 in bin 6
Pack object 11 in bin 7
Pack object 12 in bin 6
我知道我快要完成这项任务了。我知道问题出在哪里,但我一直没能解决。求你了,你能帮我吗?
错误出现在代码的erase()
:中
while (p != NULL && p->capacity != n->capacity)
{// move to a child of p
pp = p;
if (n->capacity < p->capacity)
p = p->leftChild;
else
p = p->rightChild;
}
因为您要传入一个特定的节点来擦除,因为树中的多个bin可以具有相同的当前剩余容量,并且因为您的"最佳bin"逻辑返回递归中的最后一个最佳匹配,你的erase()
函数可能会erase()
错误的节点,事实上很可能会。(如果你的匹配代码总是返回第一个"最佳匹配",我不确定你会有问题,尽管代码很脆弱。)
如果同等容量的垃圾箱真的无法区分,这实际上就不是问题了。然而,代码中的每个bin都有一个唯一的binNumber
,因此您会在您所说的分配到的bin和实际擦除和重新插入的bin之间断开连接。
由于您要传递一个指向树中某个元素的指针,因此您应该直接在这里进行指针比较。
while (p != n)
{// move to a child of p
pp = p;
if (p->capacity >= N->capacity)
p = p->leftChild;
else
p = p->rightChild;
}
删除不在树中的节点无论如何都是非法的,因此唯一有效的终止条件是找到该节点。
一旦你找到了要擦除的节点,下面的伪代码应该正确地旋转树:
if (pp->capacity >= n->capacity)
parent_to_me = &pp->leftChild;
else
parent_to_me = &pp->rightChild;
if (!node->leftChild && !node->rightChild)
{
// point to nothing
*parent_to_me = NULL;
} else if (node->leftChild)
{
if (!node->rightChild)
{
// left child, but no right child:
// promote left child to self
*parent_to_me = node->leftChild;
} else
{
// left and right children: Make right child the
// right child of the right-most left sub-child.
// Replace myself with left child.
Node *rmlsc = node->leftChild;
while (rmlsc->rightChild)
rmlsc = rmlsc->rightChild;
rmlsc->rightChild = node->rightChild;
*parent_to_me = node->leftChild;
}
} else
*parent_to_me = node->rightChild;
相关文章:
- Windows 10命令提示符的输出不正确
- C++ - 为什么 unicode 输出不正确?
- 我的叉子输出不正确
- C++使用 CEIL 和长度输出不正确的值
- 使用 iconv 进行 UTF8 转换的输出不正确
- C strftime()输出不正确
- 当行数和列不匹配时,输出不正确
- C++ 嵌套循环输出不正确
- 矩阵和矢量乘法,输出不正确的产品
- 我对这个问题有问题,我的输出不正确
- 上一个较大的数字代码中的输出不正确
- 二进制搜索树的输出不正确
- 拆解输出不正确(BeaEngine)
- 最大输出不正确
- 基本合并排序中的输出不正确
- 更改声明顺序时输出不正确
- Base64 转换器的输出不正确
- 使用 find_first_of() 和 substr() 分隔字符串,但我得到的输出不正确
- 对字符串进行索引时输出不正确
- .wav C++数据输出不正确