堆
简单堆的特点
1) 第一个点是根结点
2) 头指针指向根结点
3) 本质是一个树
4) 第 I 号节点的左儿子是第I * 2 号,右儿子是第I * 2 + 1号
5) 第I 层元素一定比第I + k ( k>0 ) 层优
堆的建立与维护
1) 每次入队一个元素(假设编号为k)
2) 将此入队元素与其父节点(编号(int)(k/2))进行对比
3) 若该元素最优,swap二者,进行2)
这称为上浮
堆的取出
1) 一般来说每次取堆顶的一个元素
2) 取得该元素后删除该元素
3) 删除堆顶元素的方法:拷贝队末元素至堆顶
4) 删除队末元素所占空间
5) 把堆顶元素下沉
下沉操作
1) 将该元素与其子节点(编号(int)(k*2)与(int)(k*2+1))进行比较
2) 若该元素非最优,swap二者,进行1)
下面是代码,小根堆的
# include <iostream>
# include <fstream>
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cmath>
# include <algorithm>
# include <vector>
# include <deque>
# include <list>
using namespace std ;
template <class type>
class tree
{
public :
deque <type> q ;
tree () ;
void get ( type ) ;
void down_load ( int ) ;
void up_date ( int ) ;
void swap ( int , int ) ;
void print () ;
private :
int size ;
} ;
tree <int> t ;
int temp;
void work () ;
int main ()
{
freopen ( "堆.in" , "r" , stdin ) ;
freopen ( "堆.out" , "w" , stdout ) ;
work () ;
}
void work ()
{
while ( cin >> temp )
{
t.get ( temp ) ;
t.print () ;
}
}
template <class type>
void tree <type>::get ( type the )
{
size ++ ;
cout << "got " << the << '\n' ;
this->q.push_back ( the ) ;
up_date ( this->size ) ;
cout << '\n' ;
return ;
}
template <class type>
void tree <type>::up_date ( int the )
{
while ( the / 2 != 0 && q[ the ] > q[ the / 2 ] )
{
cout << "up_date " << q[ the ] << " " << q[ the / 2 ] << '\n' ;
cout << " " << the << " " << the / 2 << '\n' ;
swap ( the , the / 2 ) ;
the /= 2 ;
}
return ;
}
template <class type>
void tree <type>::down_load ( int the )
{
while ( the * 2 <= q.size () && q[ the ] < q[ the * 2 ]
|| the * 2 + 1 <= q.size () && q[ the ] < q[ the * 2 + 1 ] )
{
if ( the * 2 <= q.size () && q[ the ] < q[ the * 2 ] )
{
swap ( the , the * 2 ) ;
the *= 2 ;
}
if ( the * 2 + 1 <= q.size () && q[ the ] < q[ the * 2 + 1 ] )
{
swap ( the , the * 2 + 1 ) ;
the = the * 2 + 1 ;
}
}
}
template <class type>
void tree <type>::swap ( int a , int b )
{
cout << "swap " << q[ a ] << " of " << q[ b ] << '\n' ;
type c = q[ a ] ;
q[ a ] = q[ b ] ;
q[ b ] = c ;
return ;
}
template <class type>
tree <type>::tree ()
{
q.push_back ( 0 ) ;
size = 0 ;
return ;
}
template <class type>
void tree <type>::print ()
{
int _matrix_2 = 1 , ii = 1 , jj = 1 , kk = 1 ;
while ( ii <= size )
{
for( jj = ii ; jj <= size && jj<= ii + kk - 1 ; jj ++ )
cout << q[ jj ] << "(" << q[ jj / 2 ] << ") " ;
ii = jj ;
kk *= 2 ;
cout << '\n' ;
}
}
加了判定函数以后的模板是这样
# include <iostream>
# include <fstream>
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cmath>
# include <algorithm>
# include <vector>
# include <deque>
# include <list>
using namespace std ;
template <class type>
class tree
{
public :
deque <type> q ;
tree () ;
void get ( type ) ;
void down_load ( int , bool ( * )( const type& , const type& ) ) ;
void up_date ( int , bool ( * )( const type& , const type& ) ) ;
void swap ( int , int ) ;
void print () ;
private :
int size ;
} ;
tree <int> t ;
bool cmp ( const int& , const int& ) ;
int temp;
void work () ;
int main ()
{
freopen ( "堆.in" , "r" , stdin ) ;
freopen ( "堆.out" , "w" , stdout ) ;
work () ;
}
void work ()
{
while ( cin >> temp )
{
t.get ( temp ) ;
t.print () ;
}
}
template <class type>
void tree <type>::get ( type the )
{
size ++ ;
this->q.push_back ( the ) ;
up_date ( this->size , cmp ) ;
return ;
}
bool cmp ( const int &aa , const int &bb )
{
return aa > bb ;
}
template <class type>
void tree <type>::up_date ( int the , bool ( *pp )( const type& , const type& ) )
{
while ( the / 2 != 0 && ( *pp )( q[ the ] , q[ the / 2 ] ) )
{
swap ( the , the / 2 ) ;
the /= 2 ;
}
return ;
}
template <class type>
void tree <type>::down_load ( int the , bool ( *pp )( const type& , const type& ) )
{
while ( the * 2 <= q.size () && ( ! ( *pp )( q[ the ] , q[ the * 2 ] ) )
|| the * 2 + 1 <= q.size () && ( ! ( *pp )( q[ the ] , q[ the * 2 + 1 ] ) ) )
{
if ( the * 2 <= q.size () && ( ! ( *pp )( q[ the * 2 ] , q[ the ] ) ) )
{
swap ( the , the * 2 ) ;
the *= 2 ;
}
else
{
swap ( the , the * 2 + 1 ) ;
the = the * 2 + 1 ;
}
}
}
template <class type>
void tree <type>::swap ( int a , int b )
{
type c = q[ a ] ;
q[ a ] = q[ b ] ;
q[ b ] = c ;
return ;
}
template <class type>
tree <type>::tree ()
{
q.push_back ( 0 ) ;
size = 0 ;
return ;
}
template <class type>
void tree <type>::print ()
{
int _matrix_2 = 1 , ii = 1 , jj = 1 , kk = 1 ;
while ( ii <= size )
{
for( jj = ii ; jj <= size && jj<= ii + kk - 1 ; jj ++ )
cout << q[ jj ] << "(" << q[ jj / 2 ] << ") " ;
ii = jj ;
kk *= 2 ;
cout << '\n' ;
}
}