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

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

相关文章

SpringBoot项目中Maven剔除无用Jar引用的最佳实践

《SpringBoot项目中Maven剔除无用Jar引用的最佳实践》在SpringBoot项目开发中,Maven是最常用的构建工具之一,通过Maven,我们可以轻松地管理项目所需的依赖,而,... 目录1、引言2、Maven 依赖管理的基础概念2.1 什么是 Maven 依赖2.2 Maven 的依赖传递机

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

Docker集成CI/CD的项目实践

《Docker集成CI/CD的项目实践》本文主要介绍了Docker集成CI/CD的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、引言1.1 什么是 CI/CD?1.2 docker 在 CI/CD 中的作用二、Docke

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<