第十一章(1).多路平衡归并排序
来源:互联网 发布:python是用来做什么的 编辑:程序博客网 时间:2024/06/06 13:27
#include < stdio.h >
#include < stdlib.h >#define k 5 //k路归并
#define MAXKEY 100 //最大关键字
#define MINKEY 0 //最小关键字typedef int KeyType ;
typedef int LoserTree[ k ] ; //败者树是其安全二叉树且不含叶子,可采用顺序存储结构
typedef struct {
KeyType key ;
int times ;
} ExNode , External[ k ] ; //外结点,只存放待归并记录的关键字void Input( External *b , int ik ) ;
void Output( External b , int ik ) ;void K_Merge( LoserTree *ls , External *b ) ;
void Adjust( LoserTree *ls , int s , External *b ) ;
void CreateLoserTree( LoserTree *ls , External *b ) ;
#include "Merge.h"
//在算法中避开了外存信息存放的细节,故有如下操作
void Input( External *b , int ik )
{
int Data[ k ][ 3 ] ={ { 6 , 15 , 25 } ,
{ 12 , 37 , 48 } ,
{ 10 , 15 , 16 } ,
{ 9 , 18 , 20 } ,
{ 20 , 22 , 40 } } ;
if( (*b)[ ik ].times < 3 )
{
(*b)[ ik ].key = Data[ ik ][ (*b)[ ik ].times ] ;
(*b)[ ik ].times ++ ;
}
else
(*b)[ ik ].key = MAXKEY ;
}void Output( External b , int ik ) //这里直接打印出来,而不是写至输出归并段
{
printf( "%d " , b[ ik ].key ) ;
}void K_Merge( LoserTree *ls , External *b )
{ //利用败者树ls将编号从0到k-1的k个输入归并段中的记录归并到输出归并段
//b[0]至b[k-1]为败者树上的k个叶子结点,分别存放k个输入归并段中当前记录的关键字
int i ;
KeyType q ;for( i = 0 ; i < k ; ++ i )
Input( b , i ) ; //分别从k个输入归并段读入当前第一个记录的关键字到外结点CreateLoserTree( ls , b ) ; //建败者树ls,选最小关键字b[ls[0]].key
while( (*b)[ (*ls)[0] ].key != MAXKEY )
{
q = (*ls)[ 0 ] ; //q指示当前最小关键字所在归并段
Output( *b , q ) ; //将编号为q的归并段中当前(关键字b[q]->key)的记录写至输出归并段Input( b , q ) ; //从编号为q的输入归并段中读入下一个记录的关键字
Adjust( ls , q , b ) ; //调整败者树,选择新的最小关键字
}
// Output( *b , (*ls)[ 0 ] ) ; //将含最大关键MAXKEY的记录写至输出归并段
}void Adjust( LoserTree *ls , int s , External *b )
{ //沿从叶子结点b[s]到根节点ls[0]的路径调整败者树
int t = ( s + k ) / 2 ; //ls[t]是b[s]的双亲结点
int temp ;while( t > 0 )
{
if( (*b)[ s ].key > (*b)[ (*ls)[ t ] ].key )
{
temp = (*ls)[ t ] ;
(*ls)[ t ] = s ;
s = temp ; //s指示新的胜者
}
t = t / 2 ;
}
(*ls)[ 0 ] = s ;
}void CreateLoserTree( LoserTree *ls , External *b )
{ //已知b[0]到b[k-1]为完全二叉树ls的叶子结点存有k个关键字,沿从叶子到根的k条路径将ls调整为败者树
int i ;(*b)[ k ].key = MINKEY ; //设置MINKEY为关键字可能的最小值
for( i = 0 ; i < k ; ++ i )
(*ls)[ i ] = k ; //设置ls中“败者”的初值for( i = k - 1 ; i >= 0 ; -- i )
Adjust( ls , i , b ) ; //依次从b[k-1],b[k-2]……b[0]出发调整败者
}void InitExternal( External *b )
{
int i ;
for( i = 0 ; i < k ; ++ i )
{
(*b)[ i ].times = 0 ;
}
}int main( )
{
LoserTree ls ;
External b ;
InitExternal( &b ) ;
K_Merge( &ls , &b ) ;
printf( "\n" ) ;return 0 ;
}
- 第十一章(1).多路平衡归并排序
- 海量数据排序,多路平衡归并算法及实现(外部文件排序算法)
- 败者树实现多路平衡归并外部排序算法
- 败者树实现多路平衡归并外部排序算法
- 胜者树与败者树, 多路平衡归并外部排序
- 多路归并排序
- 多路归并排序
- 多路归并排序
- 多路归并排序
- 多路归并排序
- 多路归并排序
- 归并排序(1)
- 归并排序(1)
- 归并排序(二路归并)
- 第十一章 排序
- VC++2012编程演练数据结构《35》多路平衡归并
- 7.7.3 多路平衡归并与败者树
- 归并排序(2路)
- 第十章(8).堆排序
- 第十章(9).归并排序(递归)
- 第十章(10).归并排序(非递归)
- 第十章(11).基数排序
- C++扫盲系列--第一个服务器程序
- 第十一章(1).多路平衡归并排序
- 第十一章(2).置换—选择排序
- 第六章(8)求集合的幂集
- 第六章(9).四皇后问题
- 第四章(4).KMP算法
- 第四章(5).建立词索引表
- 第三章(8).离散事件模拟
- UVA 437 -- The Tower of Babylon
- 内存访问错误