以下のためのパッケージ変更Day5; インポートjava.util.Arrays; インポートはjava.util.Comparator; インポートjava.util.PriorityQueue; / * * Q: *データ・ストリームの中央値を取得する方法? 数値が奇数データストリームから読み込まれた場合*は、中央値をソートした後、すべての値の中央に位置しています。 偶数値は、データストリームから読み出された場合*は、中央値は、注文の全ての中間値の後に2つの数の平均値です。 * *アイデア: *使用ヒープ、大根ヒープ、少しヒープルート。(ヒープルートを記憶するには大きすぎる少しのおかげで、ヒープの根は、小さい番号を格納する) 大ルートヒープを読み取るために*最初の数、 *後者の数、大きなコントラストルート上杭、以下であれば、大きなヒープルートにスタックの最上部、 *そうでなければ小さなヒープ領域であれば、トップルートのコントラスト小さな山によって、ルートが小さな山にヒープの最上部よりも大きいかどうか、に、小さなヒープルートにルートを試みます。それ以外の場合は、大規模なルートヒープに。 * * 2つのスタック> 1との間の差であれば、少数その中に、スタックの最上部を削除します。 * * / パブリック・ クラスCode04_MedianInDatastream { 公共の 静的 クラスMedianHolder { 優先度つきキュー <整数> のminheap。 優先度つきキュー <整数> maxHeap。 パブリックMedianHolder(){ この .minHeap = 新しい優先度つきキュー<> (); この .maxHeap = 新しい優先度つきキュー<>(新MaxHeapComparator()); } 公共 ボイドは(){修正 int型のカウント= maxHeap.size() - minHeap.sizeを(); もし(Math.abs(カウント)> 1 ){ 場合(> 0をカウント{) minHeap.add(maxHeap.poll()); } 他{ maxHeap.add(minHeap.poll()); } } } // ネイティブ!!!!!フルを検討します!!それを空にしますか? 公共 ボイド追加(INT NUM){ IF (maxHeap.isEmpty()){ maxHeap.add(NUM); 返す; } IF(NUM <= maxHeap.peek()){ // これは、大きなルートパイル上部よりも小さいことに留意されたい maxHeap .add(NUM); } 他 { // ませ試みは小さなヒープルートに置かれなかった、してみてください!!!試してみてください!!! もし(minHeap.isEmpty()){ minHeap.add(NUM)。 返します。 } の場合(NUM> = minHeap.peek()){ minHeap.add(NUM)。 } エルス{ maxHeap.add(NUM)。 } } 変更()。 } パブリック整数getMedian(){ int型 maxHeapSize = maxHeap.size()。 INT minHeapSize = minHeap.size()。 もし(maxHeap.isEmpty()&& minHeap.isEmpty()){ リターン ヌル; } 整数maxHeapHead = maxHeap.peek()。 整数minHeadHead = minHeap.peek()。 もし(((+ maxHeapSize minHeapSize)&1)== 0 ){ リターン(maxHeapHead minHeadHead +)/ 2 。 } 戻り minHeapSize> maxHeapSize?minHeadHead:maxHeapHead。 } } パブリック 静的 クラス MaxHeapComparator 実装コンパレータ<整数> { @Override 公共 のint比較(整数O1、O2整数){ // TODO自動生成方法スタブ 戻り O2 - O1。 } } // テスト用の パブリック 静的 INT [] getRandomArray(INT MAXLEN、INT maxValueの){ int型 [] RES = 新しい INT [(INT)(Math.random()* MAXLEN)+ 1 ]。 以下のために(int型!; I = res.length;私は= 0を私は++ ){ RES [i]を =(int型)(Math.random()* maxValueの); } リターンのres; } // テストのために、この方法は非効率的であるが、絶対的に正しい パブリック 静的 INT getMedianOfArray(INT [] ARR){ INT [] newArr = Arrays.copyOf(ARR、arr.length)。 Arrays.sort(newArr)。 INT半ば=(newArr.length - 1)/ 2 。 もし((newArr.length&1)== 0 ){ リターン(newArr [中間] + newArr [中間+ 1])/ 2 。 } 他{ 戻りnewArr [中間]を。 } } パブリック 静的 ボイドプリントアレイ(INT [] ARR){ ため(int型 i = 0; i = arr.length;!私++ ){ System.out.print([I] ARR "+" )。 } のSystem.out.println(); } パブリック 静的 ボイドメイン(文字列[]引数){ ブール ERR = 偽。 int型 testTimes = 200000 ; 以下のために(int型私= 0;私は= testTimes;!私は++ ){ int型のlen = 30 ; int型 maxValueの= 1000 ; INT [] ARR = getRandomArray(LEN、maxValueの)。 MedianHolder medianHold = 新しいMedianHolder(); 用(int型 J = 0; J = arr.length;!J ++ ){ medianHold.add(ARR [J])。 } であれば(medianHold.getMedian()=!getMedianOfArray(ARR)){ ERR = 真。 プリントアレイ(ARR)。 System.out.println(medianHold.getMedian())。 破ります; } } のSystem.out.println(ERR "ファックOops..what!":? "今日は^ _ ^美しい日です" ); } }