线段树

 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",最后我们又把这条线段删除之

posted @ 2013-08-28 11:53  老司机  阅读(262)  评论(2编辑  收藏  举报