SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
 All Classes Namespaces Files Functions Variables Typedefs Friends
sdsl/include/sdsl/louds_tree.hpp
Go to the documentation of this file.
00001 /* sdsl - succinct data structures library
00002     Copyright (C) 2012 Simon Gog
00003 */
00008 #ifndef INCLUDED_SDSL_LOUDS_TREE
00009 #define INCLUDED_SDSL_LOUDS_TREE
00010 
00011 #include "int_vector.hpp"
00012 #include "util.hpp"
00013 #include <ostream>
00014 
00016 namespace sdsl
00017 {
00018 
00020 class louds_node
00021 {
00022     public:
00023         typedef bit_vector::size_type size_type;
00024     private:
00025         size_type m_nr;         // node number
00026         size_type m_pos;  // position in the LOUDS
00027     public:
00028         const size_type& nr;
00029         const size_type& pos;
00030 
00031         louds_node(size_type f_nr=0, size_type f_pos=0):m_nr(f_nr), m_pos(f_pos),nr(m_nr),pos(m_pos) {}
00032 
00033         bool operator==(const louds_node& v)const {
00034             return m_nr == v.m_nr and m_pos ==v.m_pos;
00035         }
00036 
00037         bool operator!=(const louds_node& v)const {
00038             return !(v==*this);
00039         }
00040 };
00041 
00042 std::ostream& operator<<(std::ostream& os, const louds_node& v);
00043 
00045 
00056 template<class BitVector = bit_vector, class SelectSupport1 = typename BitVector::select_1_type, class SelectSupport0 = typename BitVector::select_0_type>
00057 class louds_tree
00058 {
00059     public:
00060         typedef bit_vector::size_type   size_type;
00061         typedef louds_node                              node_type;
00062         typedef BitVector                               bit_vector_type;
00063         typedef SelectSupport1                  select_1_type;
00064         typedef SelectSupport0                  select_0_type;
00065 
00066     private:
00067         bit_vector_type m_bv;                   // bit vector for the LOUDS sequence
00068         select_1_type   m_bv_select1;   // select support for 1-bits on m_bv
00069         select_0_type   m_bv_select0;   // select support for 0-bits on m_bv
00070     public:
00071         const bit_vector_type& bv;      // const reference to the LOUDS sequence
00072 
00074         template<class Cst, class CstBfsIterator>
00075         louds_tree(const Cst& cst, const CstBfsIterator begin, const CstBfsIterator end):m_bv(), m_bv_select1(), m_bv_select0(), bv(m_bv) {
00076             bit_vector tmp_bv(4*cst.leaves_in_the_subtree(*begin) , 0); // resize the bit_vector to the maximal
00077             // possible size 2*2*#leaves in the tree
00078             size_type pos = 0;
00079             for (CstBfsIterator it = begin; it != end;) {
00080                 tmp_bv[pos++] = 1;
00081                 size_type size = it.size();
00082                 ++it;
00083                 pos += it.size()+1-size;
00084             }
00085             tmp_bv.resize(pos);
00086             util::assign(m_bv, tmp_bv);
00087             util::init_support(m_bv_select1, &m_bv);
00088             util::init_support(m_bv_select0, &m_bv);
00089         }
00090 
00092         node_type root() const {
00093             return louds_node(0, 0);
00094         }
00095 
00097         size_type nodes()const {
00098             return m_bv.size()/2;
00099         }
00100 
00102 
00104         bool is_leaf(const node_type& v) const {
00105             // node is the last leaf        or  has no children, so m_bv[v.pos]==1
00106             return (v.pos+1 == m_bv.size()) or m_bv[v.pos+1];
00107         }
00108 
00110 
00113         size_type degree(const node_type& v) const {
00114             if (is_leaf(v)) {  // handles boundary cases
00115                 return 0;
00116             }
00117             // position of the next node  - node position - 1
00118             return m_bv_select1(v.nr+2) - v.pos - 1;
00119         }
00120 
00122 
00127         node_type child(const node_type& v, size_type i)const {
00128             size_type pos   = v.pos+i; // go to the position of the child's zero
00129             // (#bits = pos+1) - (#1-bits = v.nr+1)
00130             size_type zeros = pos+1 - (v.nr+1);
00131             return louds_node(zeros, m_bv_select1(zeros+1));
00132         }
00133 
00135         node_type parent(const node_type& v)const {
00136             if (v == root()) {
00137                 return root();
00138             }
00139             size_type zero_pos   = m_bv_select0(v.nr);
00140             size_type parent_nr  = (zero_pos+1) - v.nr - 1;
00141             return node_type(parent_nr, m_bv_select1(parent_nr+1));
00142         }
00143 
00145         size_type id(const node_type& v)const {
00146             return v.nr;
00147         }
00148 };
00149 
00150 }// end namespace sdsl
00151 
00152 #endif // end file