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

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

相关文章

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

redis数据结构之String详解

《redis数据结构之String详解》Redis以String为基础类型,因C字符串效率低、非二进制安全等问题,采用SDS动态字符串实现高效存储,通过RedisObject封装,支持多种编码方式(如... 目录一、为什么Redis选String作为基础类型?二、SDS底层数据结构三、RedisObject