k路合併 敗者樹演算法

2021-08-08 22:28:53 字數 1921 閱讀 2552

假定有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...