首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >分段树挑战

分段树挑战
EN

Code Review用户
提问于 2016-06-24 02:51:14
回答 1查看 72关注 0票数 2

下面是带有示例驱动文件的段树的实现(我没有创建更新函数,因为我不需要它来完成我所做的事情)。

我是极客健忘的超级粉丝,但我不明白为什么此链接会做出如此复杂的实现。我没有用高度或者计算最大尺寸来建造我的。更不用说,它们的结构实际上不是一棵树,而是一个整数数组。

我在寻找我实现得好的东西和我没有实现好的东西。

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>

typedef struct segment_tree_node_s
{
  struct segment_tree_node_s * left;
  struct segment_tree_node_s * right;
  int start;
  int end;
  int sum;
} segment_tree_node_t;

typedef struct segment_tree_s
{
  segment_tree_node_t * root;
} segment_tree_t;

int build_tree(segment_tree_node_t **, int, int);
int query_tree(segment_tree_node_t *, int, int);

static const int ra[] = {1,3,5,7,9,11};
int main(int argc, char * argv[])
{
  segment_tree_t * new_tree = (segment_tree_t *) malloc(sizeof(segment_tree_t));
  int length = sizeof(ra)/sizeof(ra[0]);
  int sum = build_tree(&new_tree->root, 0, length - 1);
  int sum_2 = query_tree(new_tree->root, 0, 0); 
  int sum_3 = query_tree(new_tree->root, 0, 1); 
  int sum_4 = query_tree(new_tree->root, 0, 2); 
  int sum_5 = query_tree(new_tree->root, 0, 3); 
  int sum_6 = query_tree(new_tree->root, 0, 4); 
  int sum_7 = query_tree(new_tree->root, 1, 5); 
  int sum_8 = query_tree(new_tree->root, 2, 4); 
  int sum_9 = query_tree(new_tree->root, 4, 5); 
  int sum_10 = query_tree(new_tree->root, 5, 5); 

  printf("Sum of tree [0-5]: %d\n", sum);
  printf("Sum of tree [0-0]: %d\n", sum_2);
  printf("Sum of tree [0-1]: %d\n", sum_3);
  printf("Sum of tree [0-2]: %d\n", sum_4);
  printf("Sum of tree [0-3]: %d\n", sum_5);
  printf("Sum of tree [0-4]: %d\n", sum_6);
  printf("Sum of tree [1-5]: %d\n", sum_7);
  printf("Sum of tree [2-4]: %d\n", sum_8);
  printf("Sum of tree [4-5]: %d\n", sum_9);
  printf("Sum of tree [5-5]: %d\n", sum_10);

  return 0;
}

int build_tree(segment_tree_node_t ** node, int start, int end)
{
  *node = (segment_tree_node_t *)malloc(sizeof(segment_tree_node_t));
  (*node)->sum = 0;

  if(start != end)
  {
    (*node)->start = start;
    (*node)->end   = end;
    int mid = start + (end - start)/2;
    return (*node)->sum = build_tree(&((*node)->left), start, mid) + build_tree(&((*node)->right), mid + 1, end);   
  }
  else
  {
    (*node)->start = start;
    (*node)->end   = end;
    (*node)->sum = ra[start];
    return ra[start];
  }
}

int query_tree(segment_tree_node_t * node, int start, int end)
{
    /* Total overlap */
    if(node->start >= start && node->start <= end)
    {
        if(node->end <= end && node->end >= start)
            return node->sum;
    }

    /* Partial overlap */
    if((start >= node->start && start <= node->end) || (end >= node->end && end <= node->start) || (start <= node->start && end >= node->start))
            return query_tree(node->left, start, end) + query_tree(node->right, start, end);

    /* No overlap */
    return 0;
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-06-25 05:57:38

边界检查简化

您的边界检查代码过于复杂。这一总重叠检查:

/*总重叠*/ if(节点->启动>=启动&节点->开始<=结束){if(节点->结束<=结束&节点->结束>=开始)返回节点->sum;}

可减为:

代码语言:javascript
运行
复制
/* Total overlap */
if(node->start >= start && node->end <= end)
{
    return node->sum;
}

在这部分重叠检查中:

/*部分重叠*/ if((启动>=节点-> start && start <=节点-> end )\x (end >=节点-> end &end <=节点->start <=节点->start&end >=节点->start))

我注意到,这三个条件中的第二个总是计算为false。其他一些部分也是不必要的。事实上,整件事可以改写为:

代码语言:javascript
运行
复制
/* Partial overlap */
if (start <= node->end && end >= node->start)

使用globals

函数build_tree()直接引用数组ra。最好将该数组作为参数传递进来。否则,该函数不能用于任何其他段树。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/132917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档