堆
2012-08-05 14:55
411 查看
简单堆的特点
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' ;
}
}
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' ;
}
}
相关文章推荐
- dos 日期时间格式设置使用小结(Date和Time)
- DOS批处理之DATE命令的使用方法详解
- ExtJs的Date格式字符代码
- PHP中Date获取时间不正确怎么办
- Insert Date and Time into Access
- cmd tree命令 以树形格式罗列文件
- tree 以树形格式罗列文件
- date.parse在IE和FF中的区别
- 使用 MySQL Date/Time 类型
- JavaScript Date对象使用总结
- js树形控件脚本代码
- PHP中Date()时间日期函数的使用方法小结
- php date与gmdate的获取日期的区别
- JavaScript 笔记二 Array和Date对象方法
- oracle date 类型字段的处理方法
- JavaScript Date对象 日期获取函数
- Java中Date类和Calendar类的常用实例小结
- Linux下date命令,格式化输出,时间设置方法
- java获取Date时间的各种方式汇总
- HP Z800 Workstation - Configuring RAID devices (HP Z800 做磁盘Raid1,Raid0的阵列)