Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 二叉搜索树最佳拟合Alg.:输出不正确_C++_Find_Binary Search Tree_Bin Packing_Best Fit - Fatal编程技术网

C++ 二叉搜索树最佳拟合Alg.:输出不正确

C++ 二叉搜索树最佳拟合Alg.:输出不正确,c++,find,binary-search-tree,bin-packing,best-fit,C++,Find,Binary Search Tree,Bin Packing,Best Fit,免责声明:这是学校作业 嘿,大家好。我花了两周的时间在这个垃圾箱打包程序上,我还有最后一个障碍要克服:我的二叉搜索树的find函数给了我不正确的结果 BinarySearchTree.cpp #include "BinarySearchTree.h" void BinarySearchTree::insert(int capacity, int binNumber) { // Insert the Pair into the tree. Overwrite existing /

免责声明:这是学校作业

嘿,大家好。我花了两周的时间在这个垃圾箱打包程序上,我还有最后一个障碍要克服:我的二叉搜索树的find函数给了我不正确的结果

BinarySearchTree.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;
}
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);
   }
}
BinPacking.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;
}
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);
   }
}
预期产出

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 
电流输出

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()
中:

无论如何,擦除不在树中的节点是非法的,因此唯一有效的终止条件是找到该节点

找到要擦除的节点后,以下伪代码应正确旋转树:

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;

你没有建立“最佳元素”的逻辑。只有在完全匹配时才返回非空节点。当对象大小与初始箱子大小不匹配时,代码如何工作?当你决定把东西装进垃圾箱时,你会怎么做?它的大小改变了,所以它在树中的位置也需要改变。实际上,我刚刚意识到我有一个旧版本的代码。我刚修改过。输出也已更新。好的,您的搜索现在看起来很好。但是,一旦你把一个对象分配到一个箱子里,你会怎么做呢?箱子的剩余容量将减少,因此箱子在搜索树中的位置需要更改。您还没有向我们展示在
find()
节点之后要做什么。好的,我刚刚添加了我的最佳拟合算法,它显示了在找到节点后会发生什么。这看起来很有希望。
擦除
做什么,以及
插入
做什么?前3个对象已打包,但它显示“分段错误(内核转储)”。好的,现在我需要更仔细地查看其余的擦除代码。我看到你在那里分配了一个新元素,这是不必要的。它总是一个“旋转”。你必须找到合适的偏心点才能旋转到被删除元素的位置。好的,我将在上面放一些伪代码,说明当你删除一个键时应该如何处理“旋转”。这是伪代码,你必须把它重新编译成你自己的程序。我将使用这个伪代码,希望这件事能得到解决。我非常感谢你在这方面的帮助,Joe Z。希望伪代码有意义。你应该能够画出图表,看看它是如何工作的。