繁体   English   中英

C语言中的二叉树仓包装算法

[英]Binary Tree Bin Packing Algorithm in C

我正在尝试做什么:

我看到了这个算法,它是用javascript制作的,我正在尝试将Packing Blocks into a Fixed Rectangle C中Packing Blocks into a Fixed Rectangle 。在我的代码中,如下所示,我从.txt读取数据。 这部分没有问题,我只是制作一个指向struct Blocks的指针数组,然后我对它进行排序。 在那之后我完全像文章中的代码,相同的逻辑,这就是错误发生的地方。

我的代码:

#include "stdio.h"
#include "stdlib.h"

typedef struct Block
{
    struct Node* fit;
    int width;
    int height;
    int x;
    int y;
    int id;
} Block;

typedef struct Node {
    struct Node* down;
    struct Node* right;
    int used;   
    int width;
    int height;
    int x;
    int y;
} Node;

Node *findNode(Node *root, int w, int h);
Node *splitNode(Node **root, int w, int h);

int main()
{
    FILE *file;
    char line[80];
    Block **blocks; 
    int totalBoards, boardWidth, boardHeight, totalBlocks;
    int i = 1, j;

    Node *root = malloc(sizeof(Node));
    root->x = 0;
    root->y = 0;
    root->used = 0;
    root->id = 0;

    fopen_s(&file, "blocks.txt", "r");

    // Reading the file
    while (fgets(line, 80, file)) {
        if (i == 1) {
            sscanf_s(line, "%d\n", &totalBoards);
        } else if (i == 2) {
            sscanf_s(line, "%d\n", &boardWidth);
            root->width = boardWidth;
        } else if (i == 3) {
            sscanf_s(line, "%d\n", &boardHeight);
            root->height = boardHeight;
        } else if (i == 4) {
            sscanf_s(line, "%d\n", &totalBlocks);
            blocks = malloc(totalBlocks * sizeof(Block *));

        } else {            
            int w, h;
            blocks[i - 5] = malloc(sizeof(Block));
            sscanf_s(line, "%d %d", &w, &h);
            blocks[i - 5]->width = w;
            blocks[i - 5]->height = h;
            blocks[i - 5]->id = i - 5;
        }

        i++;
    }

    //Bubble sort
    for (i = 0; i < totalBlocks; i++) {

        for (j = 0; j < totalBlocks - i - 1; j++)

            if (blocks[j]->height < blocks[j + 1]->height) {                
                Block *b = blocks[j];
                blocks[j] = blocks[j + 1];
                blocks[j + 1] = b;
            }
    }

    // THE IMPORTANT PART
    // The logic used by the algorithm
    // fit function
    for (i = 0; i < totalBlocks; i++) {
        Block *block = blocks[i];   
        Node *node;
        if (node = findNode(root, block->width, block->height)) {
            block->fit = splitNode(&node, block->width, block->height);
        }
    }

    //Print the blocks
    for (i = 0; i < totalBlocks; i++) {
        Block *block = blocks[i];
        if (block->fit) {           
            printf("x %d y %d\n", blocks[i]->fit->x, blocks[i]->fit->y);
        }
    }

    return 0;
}

Node *findNode(Node *root, int w, int h) {
    printf("%d", root->id);
    if (root->used == 1) {
        //Error Here
        return findNode(root->down, w, h) || findNode(root->right, w, h);
    }
    else if ((w <= root->width) && (h <= root->height)) {
        return root;
    }
    else {
        return NULL;
    }
}

Node *splitNode(Node **root, int w, int h) {

    (*root)->used = 1;
    (*root)->down = malloc(sizeof(Node));
    (*root)->down->right = malloc(sizeof(Node));
    (*root)->down->down = malloc(sizeof(Node));
    (*root)->down->x = (*root)->x;
    (*root)->down->y = (*root)->y + h;
    (*root)->down->width = (*root)->width;
    (*root)->down->height = (*root)->height - h;
    (*root)->down->used = 0;
    (*root)->down->id = idCount;
    idCount++;


    (*root)->right = malloc(sizeof(Node));
    (*root)->right->right = malloc(sizeof(Node));
    (*root)->right->down = malloc(sizeof(Node));
    (*root)->right->x = (*root)->x + w;
    (*root)->right->y = (*root)->y;
    (*root)->right->width = (*root)->width - w;
    (*root)->right->height = (*root)->height;
    (*root)->right->used = 0;
    (*root)->right->id = idCount;
    idCount++;

    return *root;
}

错误:

在这部分中, findNode返回的Node出错了

if (node = findNode(root, block->width, block->height)) {
    block->fit = splitNode(&node, block->width, block->height);
}

当它被返回时

return findNode(root->down, w, h) || findNode(root->right, w, h);

因为我在splitNode使用splitNode node

block->fit = splitNode(&node, block->width, block->height);

node所有属性都是NULL并且它导致错误。

问题:

本文的代码中,它返回以下内容

return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);

在C我回来了

return findNode(root->right, w, h) || findNode(root->down, w, h);

我认为错误就在这里。

解决方案?

我认为return ___ || ___ return ___ || ___对两种语言都不一样。 所以我有两个问题:

  1. return ___ || ___ return ___ || ___在两种语言中做同样的事情吗? 如果没有,有什么区别以及javascript中该代码的C代码等价物是什么?
  2. 我的代码出了什么问题? 为什么会发生错误并且没有像javascript代码那样返回正确的节点?

你假设||是正确的 在JavaScript和C中有不同的语义。

在JavaScript中, a || b a || b返回a ,如果a是“truthy”和b ,如果afalsy

同时在C中, a || b a || b是一个布尔表达式。 它将始终返回truefalse而不是原始表达式。

例如, 5 || 0 5 || 0在JavaScript中为5 ,在C中为1

替换return findNode(root->right, w, h) || findNode(root->down, w, h); return findNode(root->right, w, h) || findNode(root->down, w, h);

Node *answer = findNode(root->right, w, h);
if (answer) return answer;
else return findNode(root->down, w, h);

应该管用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM