数据结构实践——败者树归并模拟

2024-03-03 06:58

本文主要是介绍数据结构实践——败者树归并模拟,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文是针对[数据结构基础系列(10):外部排序]中的实践项目。

【项目】败者树归并模拟
  编写程序,模拟改者树实现5路归并算法的过程。
  设有5个文件,其中的记录的关键字如下:
  F0:{17,21,∞} F1:{5,44,∞} F2:{10,12,∞}F3: {29,32,∞} F4: {15,56,∞}
  要求将其归并为一个有序段并输出。
  假设这些输入文件数据保存在内存中,输出结果也不必输出到文件,而是在屏幕上输出即可。

参考解答

#include <stdio.h>
#define MaxSize 20          //每个文件中最多记录
#define K 5                 //5路平衡归并
#define MAXKEY 32767        //最大关键字值∞
#define MINKEY -32768       //最小关键字值-∞
typedef int InfoType;
typedef int KeyType;
typedef struct              //记录类型
{KeyType key;            //关键字项InfoType otherinfo;     //其他数据项,具体类型在主程中定义
} RecType;
typedef struct
{RecType recs[MaxSize];int currec;
} FileType;                 //文件类型
typedef int LoserTree[K];   //败者树是完全二叉树且不含叶子
RecType b[K];               //b中存放各段中取出的当前记录
FileType F[K];              //存放文件记录的数组
void initial()
{int i;                  //5个初始文件,当前读记录号为-1F[0].recs[0].key=17;F[0].recs[1].key=21;F[0].recs[2].key=MAXKEY;F[1].recs[0].key=5;F[1].recs[1].key=44;F[1].recs[2].key=MAXKEY;F[2].recs[0].key=10;F[2].recs[1].key=12;F[2].recs[2].key=MAXKEY;F[3].recs[0].key=29;F[3].recs[1].key=32;F[3].recs[2].key=MAXKEY;F[4].recs[0].key=15;F[4].recs[1].key=56;F[4].recs[2].key=MAXKEY;for (i=0;i<K;i++)F[i].currec=-1;
}
void input(int i,int &key)  //从F[i]文件中读一个记录到b[i]中
{F[i].currec++;key=F[i].recs[F[i].currec].key;
}
void output(int q)      //输出F[q]中的当前记录
{printf("输出F[%d]的关键字%d\n",q,F[q].recs[F[q].currec].key);
}
void Adjust(LoserTree ls,int s)
//沿从叶子节点b[s]到根节点ls[0]的路径调整败者树
{int i,t;t=(s+K)/2;          //ls[t]是b[s]的双亲节点while(t>0){if(b[s].key>b[ls[t]].key){i=s;s=ls[t];    //s指示新的胜者ls[t]=i;}t=t/2;}ls[0]=s;
}
void display(LoserTree ls)  //输出败者树
{int i;printf("败者树:");for (i=0;i<K;i++)if (b[ls[i]].key==MAXKEY)printf("%d(∞) ",ls[i]);else if (b[ls[i]].key==MINKEY)printf("%d(-∞) ",ls[i]);elseprintf("%d(%d) ",ls[i],b[ls[i]].key);printf("\n");
}
void CreateLoserTree(LoserTree ls)      //建立败者树
{int i;b[K].key=MINKEY;    //b[K]置为最小关键字for (i=0;i<K;i++)ls[i]=K;        //设置ls中“败者”的初值,全部为最小关键字段号for(i=K-1;i>=0;--i) //依次从b[K-1],b[K-2],…,b[0]出发调整败者Adjust(ls,i);
}
void K_Merge(LoserTree ls)  //利用败者树ls将进行K路归并到输出
{int i,q;for(i=0;i<K;++i)        //分别从k个输入归并段读入该段当前第一个记录的关键字到binput(i,b[i].key);CreateLoserTree(ls);    //建败者树ls,选得最小关键字为b[ls[0]].keydisplay(ls);while(b[ls[0]].key!=MAXKEY){q=ls[0];            //q指示当前最小关键字所在归并段output(q);          //将编号为q的归并段中当前(关键字为b[q].key)的记录输出input(q,b[q].key);  //从编号为q的输入归并段中读人下一个记录的关键字if (b[q].key==MAXKEY)printf("从F[%d]中添加关键字∞并调整\n",q);elseprintf("从F[%d]中添加关键字%d并调整\n",q,b[q].key);Adjust(ls,q);       //调整败者树,选择新的最小关键字display(ls);}
}
int main()
{LoserTree ls;initial();K_Merge(ls);printf("\n");return 0;
}

这篇关于数据结构实践——败者树归并模拟的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/768840

相关文章

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实