多路文件归并,败者树算法

来源:互联网 发布:免费网络推广平台 编辑:程序博客网 时间:2024/06/05 03:29

闲来无事,做了一个多路文件归并的工具,用败者树选择从多路输入中选择一个最小者,空间复杂度为O(K),K为归并输入的路数。该实现没有考虑最佳归并路径,等日后有空了再实现一个最佳归并路径的算法;

import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;public class MultiChannelMerge {public static class TNode {public int channel;public int value;public TNode(int c, int v) {channel = c;value = v;}}private int LEN = 0;private TNode[] loser;private int MAX = 0x7FFFFFFF;private int N = 0;private BufferedReader[] reader;public MultiChannelMerge(String[] files) throws FileNotFoundException {N = files.length;LEN = N + N -1;loser = new TNode[LEN];reader = new BufferedReader[N];try {// create buffered reader for each filefor ( int i=0; i<N; i++ ) {reader[i] = new BufferedReader(new FileReader(files[i]));}} catch (FileNotFoundException e) {close();throw e;}}/* * close all readers */private void close() {// close buffered readerfor ( int i=0; i<N; i++ ) {if ( reader[i] != null ) {try { reader[i].close(); } catch (IOException e1) {}}}}/* * copy content of 'sour' node to 'dest' node */private TNode cloneNode(TNode sour) {TNode dest = new TNode(sour.channel, sour.value);return dest;}/* * feed a number from channel 'c' and get the winner */public void feedTree(int c, TNode winner) throws IOException {String line = reader[c].readLine();winner.channel = c;winner.value = ( line != null ) ? Integer.valueOf(line) : MAX;int cur = N-1+c;do {cur = ( cur - 1 ) / 2;if ( loser[cur].value <= winner.value ) {swapNode(loser[cur],winner);}} while ( cur > 0 );}/* * init a loser tree */public void initTree(TNode res) throws IOException {TNode[] winner = new TNode[LEN];// read a number from each filefor ( int c=0; c<N; c++ ) {String line = reader[c].readLine();int v = ( line != null ) ? Integer.valueOf(line) : MAX;TNode node = new TNode(c,v);winner[N-1+c] = node;loser[N-1+c] = node;}// calculate winner and loser for each nodefor ( int k=N-2; k>=0; k-- ) {int left = ( k << 1 ) + 1, right = ( k << 1 ) + 2;int win, los;if ( winner[left].value <= winner[right].value ) {win = left; los = right;} else {win = right; los = left;}winner[k] = cloneNode(winner[win]);loser[k] = cloneNode(winner[los]);}res.channel = winner[0].channel;res.value = winner[0].value;}/* * multi-channel merge sort */public void mergeSort() throws IOException {try {TNode winner = new TNode(0,MAX);initTree(winner);while ( winner.value != MAX ) {System.out.printf("%d ", winner.value);feedTree(winner.channel, winner);}} catch (IOException e) {close();throw e;}}/* * swap the content of n1 and n2 */private void swapNode(TNode n1, TNode n2) {int temp_v = n1.value, temp_c = n1.channel;n1.value = n2.value; n1.channel = n2.channel;n2.value = temp_v; n2.channel = temp_c;}/** * @param args */public static void main(String[] args) {String[] file = {"c:\\temp\\a1.txt","c:\\temp\\a2.txt","c:\\temp\\a3.txt"};MultiChannelMerge instance = null;try {instance = new MultiChannelMerge(file);instance.mergeSort();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {instance.close();}}}


原创粉丝点击