下面是带有示例驱动文件的段树的实现(我没有创建更新函数,因为我不需要它来完成我所做的事情)。
我是极客健忘的超级粉丝,但我不明白为什么此链接会做出如此复杂的实现。我没有用高度或者计算最大尺寸来建造我的。更不用说,它们的结构实际上不是一棵树,而是一个整数数组。
我在寻找我实现得好的东西和我没有实现好的东西。
#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;
}
发布于 2016-06-25 05:57:38
您的边界检查代码过于复杂。这一总重叠检查:
/*总重叠*/ if(节点->启动>=启动&节点->开始<=结束){if(节点->结束<=结束&节点->结束>=开始)返回节点->sum;}
可减为:
/* 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。其他一些部分也是不必要的。事实上,整件事可以改写为:
/* Partial overlap */
if (start <= node->end && end >= node->start)
函数build_tree()
直接引用数组ra
。最好将该数组作为参数传递进来。否则,该函数不能用于任何其他段树。
https://codereview.stackexchange.com/questions/132917
复制相似问题