zoukankan      html  css  js  c++  java
  • 线段树

     1 #ifndef _SEG_TREE_H_
     2 #define _SEG_TREE_H_
     3 
     4 #include <iostream>
     5 #include <cassert>
     6 #include <cstring>
     7 #include <iomanip>
     8 
     9 typedef struct seg_node
    10 {
    11     int left, right;
    12     int mid;
    13     int cover;//the segment is weather existed
    14     /* some useful data*/
    15     /* ....... */
    16     seg_node():left(0),right(0),mid(0),cover(0){}
    17 }seg_node;
    18 class seg_tree
    19 {
    20 private:
    21     seg_node *array;
    22     int len;
    23 
    24     void _build(int left, int right, int index);
    25     void _insert(int left, int right, int index);
    26     bool _del(int left, int right, int index);
    27 public:
    28     seg_tree(int left, int right); // [left, right)
    29     seg_tree(const seg_tree&);
    30     seg_tree& operator = (const seg_tree&);
    31     void insert(int left, int right);
    32     bool del(int left, int right);
    33 
    34     friend void print_segtree(std::ostream& os, const seg_tree& st, int index, int depth);
    35     friend bool operator == (const seg_tree& st1, const seg_tree& st2);
    36 };
    37 
    38 void print_segtree(std::ostream& os, const seg_tree& st, int index = 0, int depth = 0);
    39 bool operator == (const seg_tree& st1, const seg_tree& st2);
    40 
    41 #endif
      1 #include "./seg_tree.h"
      2 
      3 /***************************************
      4 * _build(int left, int right, int index)
      5 ***************************************/
      6 void seg_tree::_build(int left, int right, int index)
      7 {
      8     int mid = (left + right) / 2;
      9     array[index].left = left, array[index].right = right;
     10     array[index].mid = mid, array[index].cover = 0;
     11     if(left + 1 != right)
     12     {
     13         _build(left, mid, index*2+1);//insert left tree
     14         _build(mid, right, index*2+2);//insert right tree
     15     }
     16 }
     17 /***************************************
     18 * _insert(int left, int right, int index)
     19 ***************************************/
     20 void seg_tree::_insert(int left, int right, int index)
     21 {
     22     if(array[index].left == left && array[index].right == right)
     23     {
     24         array[index].cover = 1;
     25         return;
     26     }
     27     if(right <= array[index].mid)
     28         _insert(left, right, index*2+1);
     29     else if(left >= array[index].mid)
     30         _insert(left, right, index*2+2);
     31     else
     32     {
     33         _insert(left, array[index].mid, index*2+1);
     34         _insert(array[index].mid, right, index*2+2);
     35     }
     36 }
     37 /***************************************
     38 * _del(int left, int right, int index)
     39 ***************************************/
     40 bool seg_tree::_del(int left, int right, int index)
     41 {
     42     if(left >= right)
     43         return false;
     44     if(array[index].left + 1 == array[index].right)//leaf
     45     {
     46         int cover = array[index].cover;
     47         array[index].cover = 0;
     48         return cover;
     49     }
     50     if(array[index].cover)
     51     {
     52         array[index].cover = 0;
     53         array[index*2+1].cover = 1;
     54         array[index*2+2].cover = 1;
     55     }
     56     if(right <= array[index].mid)
     57         return _del(left, right, index*2+1);
     58     else if(left >= array[index].mid)
     59         return _del(left, right, index*2+2);
     60     else
     61         _del(left, array[index].mid, index*2+1) && 
     62         _del(array[index].mid, right, index*2+2);
     63 }
     64 /***************************************
     65 * seg_tree(int left, int right)
     66 ***************************************/
     67 seg_tree::seg_tree(int left, int right)
     68 {
     69     len = (right - left) * 3;
     70     array = new seg_node[len]();
     71     assert(array);
     72     _build(left, right, 0);
     73 }
     74 /***************************************
     75 * seg_tree(const seg_tree&)
     76 ***************************************/
     77 seg_tree::seg_tree(const seg_tree& st)
     78 {
     79     if(*this == st)
     80         return;
     81     len = st.len;
     82     delete[] array;
     83     array = new seg_node[len];
     84     assert(array);
     85     memcpy(array, st.array, sizeof(seg_node)*len);    
     86 }
     87 /***************************************
     88 * operator = (const seg_tree&)
     89 ***************************************/
     90 seg_tree& seg_tree::operator = (const seg_tree& st)
     91 {
     92     if(*this == st)
     93         return *this;
     94     len = st.len;
     95     delete[] array;
     96     array = new seg_node[len];
     97     assert(array);
     98     memcpy(array, st.array, sizeof(seg_node)*len);
     99 }
    100 /***************************************
    101 * insert(int left, int right)
    102 ***************************************/
    103 void seg_tree::insert(int left, int right)
    104 {
    105     _insert(left, right, 0);
    106 }
    107 /***************************************
    108 * del(int left, int right)
    109 ***************************************/
    110 bool seg_tree::del(int left, int right)
    111 {
    112     return _del(left, right, 0);
    113 }
    114 
    115 /***************************************
    116 * print_segtree(std::ostream& os, const seg_tree& st, int index, int depth)
    117 ***************************************/
    118 void print_segtree(std::ostream& os, const seg_tree& st, int index/*=0*/, int depth/*=0*/)
    119 {
    120     if(    !os 
    121         || st.array[index].left >= st.array[index].right 
    122         || st.array[index].left < st.array[0].left
    123         || st.array[index].right > st.array[0].right)
    124         return;
    125     print_segtree(os, st, index*2+1, depth+5);
    126     os<<std::setw(depth)<<"["<<st.array[index].left<<" ,"<<st.array[index].right<<")"
    127     <<":"<<(st.array[index].cover?"existed":"")<<std::endl;
    128     print_segtree(os, st, index*2+2, depth+5);
    129 }
    130 /***************************************
    131 * operator == (const seg_tree& st1, const seg_tree& st2)
    132 ***************************************/
    133 bool operator == (const seg_tree& st1, const seg_tree& st2)
    134 {
    135     if(st1.len != st2.len)
    136         return false;
    137     return memcmp(st1.array, st2.array, st1.len*sizeof(seg_node)) == 0;
    138 }

    下面是测试代码

     1 #include "./seg_tree.h"
     2 #include <iostream>
     3 using namespace std;
     4 
     5 int main(int argc, char const *argv[])
     6 {
     7     seg_tree st(1,10);
     8     print_segtree(cout, st);
     9     cout<<endl;cout<<endl;
    10     st.insert(3,10);
    11     print_segtree(cout, st);
    12     cout<<endl;cout<<endl;
    13     st.del(3,10);
    14     print_segtree(cout, st);
    15     return 0;
    16 }

    首先生成一棵范围在[1, 10)之间的树

    然后添加线段[3, 10)之后会在线段后面显示"existed",最后我们又把这条线段删除之

  • 相关阅读:
    chrome 插件备份
    github下载单个文件
    idea插件备份
    外卖类应用的竞争与趋势
    使用终端和Java API对hbase进行增删改查操作
    分布式文件系统的布局、文件查找
    Java上机实验报告(4)
    Java上机实验报告(3)
    Java上机实验报告(2)
    Java上机实验报告(1)
  • 原文地址:https://www.cnblogs.com/zxh1210603696/p/3286871.html
Copyright © 2011-2022 走看看