k路合并_败者树算法
来源:互联网 发布:中国向何处去 知乎 编辑:程序博客网 时间:2024/06/16 00:39
假定有k个有序数组,每个数组中含有n个元素,您的任务是将它们合并为单独的一个有序数组,该数组共有kn个元素。设计和实现 一个有效的分治算法解决k-路合并操作问题,并分析时间复杂度。
介于本人水平有限,在参考了许多大神的博客后贴上自己的代码;
public class MultipleMerge { public static void main(String[] args) { // TODO Auto-generated method stub arr=new int[K][]; arr[0]=new int[]{-1,0,2,2,3,4,5,88}; arr[1]=new int[]{-4,1,2,4,6,8,10,11,23,45}; arr[2]=new int[]{-3,1,4,5,61,72,82,99}; arr[3]=new int[]{5,6,7,8,9,10}; arr[4]=new int[]{-5,3,66,88}; record=new int[arr.length]; for(int i=0;i<arr.length;i++){ totalCount+=arr[i].length; record[i]=0; } System.out.println(Arrays.toString(K_merge())); } static int[][] arr=null;//多段合并的数据,每行必须有序 static final int K=5;//数组行数 static int[] record=null;//记录每个归并段出去了多少个元素 static int totalCount=0;//记录所有元素的个数 static final int MINKEY=-100; static final int MAXKEY=100; static int[] ls=new int[K];//败者树 static int[] b=new int[K+1]; /* * 败者树是完全二叉树,因此数据结构可以采用一维数组。 * 其元素个数为k个叶子结点、k-1个比较结点、1个冠军结点共2k个。 * ls[0]为冠军结点,ls[1]--ls[k-1]为比较结点,ls[k]--ls[2k-1]为叶子结点 */ //ls数组是建立的败者树,ls[i]的值是b数组的下标 public static int[] K_merge(){ /* * ls[0]~ls[k-1]是败者树的内部比较节点 * b[0]~b[k-1]分别存储k个数组的当前记录 */ createLoserTree(); int[] result=new int[totalCount]; int k=0; int q=0; while(k!=totalCount){ q=ls[0];//最小元素在b数组中的下标号 result[k++]=b[q];//将最小的元素存入结果数组 b[q]=Get_next(q);//补位 adjust(q);//调整 } return result; } public static void createLoserTree() { for (int i = 0; i < K; i++) { b[i]=Get_next(i);//从第i个数组中读取下一个对象 } b[K]=MINKEY;//全局最小量 for(int i=0;i<K;i++){//设置ls中的败者初值 ls[i]=K;//这样第k+1项就是最小值,前k项充满败者树 } for(int i=K-1;i>=0;i--){ //从b[k-1]到b[0]调整败者 adjust(i); } //败者树创建完毕,最小关键字序号存入ls[0] } private static void adjust(int adjustIndex) { //根据上一步确定的最小元素的下标调整败者树 int temp=0; int parent=(adjustIndex+K)/2;//父节点 while(parent>0){//没有达到树根则继续 if(b[adjustIndex]>b[ls[parent]]){ //如果待调整的元素大于父节点则其变成败者 temp=ls[parent]; ls[parent]=adjustIndex; adjustIndex=temp; } parent=parent/2; } ls[0]=adjustIndex;//最后的败者放在根节点,胜者放在0标位 } private static int Get_next(int arrayIndex) { //导入最小元素对应数组的下一个元素 if(record[arrayIndex]==arr[arrayIndex].length){ return MAXKEY;//当该归并段取完了返回一个全局最大 } return arr[arrayIndex][record[arrayIndex]++]; } }
**主要的思路:b[]数组里存着每个数组的当前元素;ls[]败者树数组里是存的是对b数组下标的索引;createLoserTree():先将败者树充满K,即默认第K+1项为全局最小项,然后用前K项逐步调整,然后前K项充满败者树。在K_merge()中通过Get_next()一步步adjust(),直到结果数组填满。注意,Get_next()方法当该归并段取完后提供全局最大,以保证所有元素被挤出败者树,最后树里剩下的应该全是全局最大。**
阅读全文
1 0
- k路合并_败者树算法
- k路归并(败者树,记录败者)
- k路归并(败者树,记录败者)
- 败者树 K-路归并排序
- 败者树 K-路归并排序
- 败者树 K-路归并排序
- k路归并 - 败者树实现
- 多路文件归并,败者树算法
- 用败者树优化K路归并排序
- python实现k路归并排序,败者树
- 归并算法、赢者树、败者树
- 利用败者树k路数平衡归并
- 使用败者树对k段归并段进行k-路平衡归并
- 败者树实现多路平衡归并外部排序算法
- 败者树实现多路平衡归并外部排序算法
- 胜者树 败者树 K-路最佳归并树 高效外部排序
- python算法--败者树详细实现
- 败者树
- [简单题]Human Readable Time(Python 实现)
- Linux常用命令
- 使用webpack犯过的一个错误
- jdk_API中文文档下载汇总
- HDU3247-(AC自动机+spfa+状压dp)
- k路合并_败者树算法
- C++常见面试题(三)-static总结
- 2426: [HAOI2010]工厂选址
- Python的基础语法(具体程序示例)
- leetcode---search-in-rotated-sorted-array---查找
- Solr Date类型的哪些你不得不了解的细节
- minGW下载与编译器安装
- erlang基础入门
- [BZOJ 2818] Gcd 线性筛+欧拉函数前缀和