#include<stdio.h>
#include<iostream>
#define max_size 1000
//创建线段树
void create_tree(int arr[], int tree_arr[], int node, int start, int end)
{
if (start == end)
{
tree_arr[node] = arr[start];
return;
}
int mid = (start + end) / 2;
int left_node = node * 2 + 1;
int right_node = node * 2 + 2;
create_tree(arr, tree_arr, left_node, start, mid);
create_tree(arr, tree_arr, right_node, mid + 1, end);
tree_arr[node] = tree_arr[left_node] + tree_arr[right_node];
}
//修改线段树
void update_tree(int arr[], int tree_arr[], int node, int start, int end, int index, int val)
//index为修改数组arr的下标,val为修改后的值
{
if (start == end) //找到叶子节点
{
arr[index] = val;
tree_arr[node] = val;
return;
}
int mid = (start + end) / 2;
int left_node = 2 * node + 1;
int right_node = 2 * node + 2;
if (index >= start && index <= mid)
{
update_tree(arr, tree_arr, left_node, start, mid, index, val);
}
else
{
update_tree(arr, tree_arr, right_node, mid + 1, end,index,val);
}
tree_arr[node] = tree_arr[left_node] + tree_arr[right_node];
}
//求区间[L,R]的和
int query_tree(int arr[], int tree_arr[], int node, int start, int end,int L, int R)
{
printf("start=%d\n", start);
printf("end=%d\n", end);
printf("\n");
if (end<L || start>R)
{
return 0;
}
else if (start >= L && end <= R)
{
return tree_arr[node];
}
else if (start == end)
{
return tree_arr[node];
}
int mid = (start + end) / 2;
int left_node = 2 * node + 1;
int right_node = 2 * node + 2;
int left_sum = query_tree(arr, tree_arr, left_node, start, mid, L, R);
int right_sum = query_tree(arr, tree_arr, right_node, mid + 1, end, L, R);
return left_sum + right_sum;
}
//删除数组下标为index的节点
void delete_tree(int arr[], int tree_arr[], int node, int start, int end, int index)
{
if (start == end)
{
tree_arr[node] = 0;
arr[index] = 0;
return;
}
int mid = (start + end) / 2;
int left_node = 2 * node + 1;
int right_node = 2 * node + 2;
if (index >= start && index <= mid)
{
delete_tree(arr, tree_arr, left_node, start, mid, index);
}
else
{
delete_tree(arr, tree_arr, right_node, mid+1, end, index);
}
}
int main()
{
int size = 6;
int arr[] = { 1,3,5,7,9,11 };
int tree_arr[max_size] = { 0 };
create_tree(arr, tree_arr, 0, 0, size - 1);
printf("创建线段树为:\n");
for (int i = 0; i < 15; i++)
{
printf("tree_arr[%d]=%d\n", i, tree_arr[i]);
}
update_tree(arr, tree_arr, 0, 0, size - 1, 4, 6);
printf("修改线段树为:\n");
for (int i = 0; i < 15; i++)
{
printf("tree_arr[%d]=%d\n", i, tree_arr[i]);
}
printf("线段树区间求值:\n");
int result=query_tree(arr, tree_arr, 0, 0, size - 1, 1,5 );
printf("%d\n", result);
printf("删除节点:\n");
delete_tree(arr, tree_arr, 0, 0, size - 1, 3);
for (int i = 0; i < 6; i++)
{
printf("arr[%d]=%d\n", i, arr[i]);
}
for (int i = 0; i < 15; i++)
{
printf("tree_arr[%d]=%d\n", i, tree_arr[i]);
}
return 0;
}
线段树的相关操作
最新推荐文章于 2022-10-02 20:42:03 发布