假定有k個有序陣列,每個陣列中含有n個元素,您的任務是將它們合併為單獨的乙個有序陣列,該陣列共有kn個元素。設計和實現 乙個有效的分治演算法解決k-路合併操作問題,並分析時間複雜度。
介於本人水平有限,在參考了許多大神的部落格後貼上自己的**;
public
class
multiplemerge ;
arr[1]=new
int;
arr[2]=new
int;
arr[3]=new
int;
arr[4]=new
int;
record=new
int[arr.length];
for(int i=0;i0;
}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()
return result;
}public
static
void
createlosertree()
b[k]=minkey;//全域性最小量
for(int i=0;i//設定ls中的敗者初值
ls[i]=k;//這樣第k+1項就是最小值,前k項充滿敗者樹
}for(int i=k-1;i>=0;i--)
//敗者樹建立完畢,最小關鍵字序號存入ls[0]
}private
static
void
adjust(int adjustindex)
parent=parent/2;
}ls[0]=adjustindex;//最後的敗者放在根節點,勝者放在0標位
}private
static
intget_next(int arrayindex)
return arr[arrayindex][record[arrayindex]++];
}
}
**主要的思路:
b陣列裡存著每個陣列的當前元素;
ls敗者樹陣列裡是存的是對b陣列下標的索引;
createlosertree():先將敗者樹充滿k,即預設第k+1項為全域性最小項,然後用前k項逐步調整,然後前k項充滿敗者樹。
在k_merge()中通過get_next()一步步adjust(),直到結果陣列填滿。
注意,get_next()方法當該歸併段取完後提供全域性最大,以保證所有元素被擠出敗者樹,最後樹里剩下的應該全是全域性最大。**
用敗者樹優化K路歸併排序
圖9.16給出的歸併過程屬於2路平衡歸併。做k路平衡歸併 k way balanced merging 時,如果有m個初始歸併段,則相應的歸併樹有 logkm 1層,南非要歸併 logkm 趟。做內部歸併時,在k個物件中選擇最小者,需要順序比較k 1次。每趟歸併u個物件需要做 u 1 k 1 次比較...
Python實現基於敗者樹的K路歸併排序
import random import os,sys 隨機生成不大於max的長度位n的列表 def genlist n,max result for i in range n print result return result 從給定的列表中獲取k個有序列表分組 def splitsortedl...
分治法 K路合併
假定有k個有序陣列,每個陣列中含有n個元素,您的任務是將它們合併為單獨的乙個有序陣列,該陣列共有kn個元素。設計和實現乙個有效的分治演算法解決k 路合併操作問題。divide exam2.cpp 定義控制台應用程式的入口點。include stdafx.h include include inclu...