目次
src/runoob/heap/Heapify.java ファイルコード:
基本的なヒープソート
1. コンセプトと紹介
ヒープソート (Heapsort) は、ヒープのデータ構造を使用して設計されたソート アルゴリズムを指します。
ヒープは完全なバイナリ ツリーに近似する構造であり、同時に累積の性質も満たします。つまり、子ノードのキー値またはインデックスは常に親ノードより小さい (または大きい) ものです。
2. 適用される命令
ヒープを構築する以前のプロセスは、insert メソッドを呼び出し、シフトアップを使用してデータを 1 つずつヒープに挿入することでした。このアルゴリズムの時間計算量は O(nlogn) です。このセクションで紹介するヒープ ソートの構築プロセスはHeapifyと呼ばれ、アルゴリズムの時間計算量はO(n)です。
3. プロセス図
完全な二分木の重要な特性は、最初の非リーフ ノードのインデックスが、n/2から整数を取得して得られるインデックス値であることです。ここで、 nは要素の数です (配列インデックスが 1 から始まる場合)。 。
インデックス 5 の位置は最初の非リーフ ノードであり、最大ヒープの性質を満たすために、そこから 1 つずつ開始してルート ノードとして各要素に対してシフト ダウン操作を実行します。
シフトダウン操作がインデックス 5、22、62 で実行された後、ポジションが交換されます。
インデックス 4 要素に対してシフトダウン操作を実行します。
インデックス 3 要素に対してシフトダウン操作を実行します。
インデックス 2 要素に対してシフトダウン操作を実行します。
最後に、ルート ノードでシフト ダウン操作を実行すると、ヒープ ソート プロセス全体が完了します。
4. Java サンプルコード
ソース パッケージのダウンロード: https://www.runoob.com/wp-content/uploads/2020/09/runoob-algorithm-Heapify.zipをダウンロードします。
src/runoob/heap/Heapify.java ファイルコード:
package runoob.heap;
import runoob.sort.SortTestHelper;
/**
* ヒープの並べ替えには heapify を使用します
*/
public class Heapify<T extends Comparable> { protected T[] data; protected int count; protected int Capacity; // コンストラクター ,指定された配列を通じて最大のヒープを作成します // ヒープを構築するプロセス、時間計算量は O(n) public Heapify(T arr[]){ int n = arr.length; data = (T[])new Comparable [n+1]; Capacity = n; for( int i = 0 ; i < n ; i ++ ) data[i+1] = arr[i]; count = n; // 最初の非リーフ要素からノードの開始 for( int i = count/2 ; i >= 1 ; i -- ) shftDown(i);
}
// ヒープ内の要素の数を返します
public int size(){ return count; } // ヒープが空かどうかを示すブール値を返します public boolean isEmpty(){ return count == 0; } //最大 ヒープ項目に新しい要素を挿入します public void insert(T item){ assert count + 1 <= Capacity; data[count+1] = item; count ++; ShiftUp(count); } // から取り出しますmax heap ヒープの最上位要素、つまりヒープに格納されている最大データ public T extractMax(){ assert count > 0; T ret = data[1]; swap( 1 , count ); count --; ShiftDown (1); ret を返します。
}
// 最大ヒープの最上位要素を取得
public T getMax(){ assert( count > 0 ); return data[1]; } // ヒープ内のインデックス i および j を持つ 2 つの要素を交換 private void swap(int i, int j){ T t = データ[i]; データ[i] = データ[j]; データ[j] = t; } //************** ** ** //* 最大ヒープ コア ヘルパー関数 //******************** private void shftUp(int k){ while( k > 1 && data[ k/ 2].compareTo(data[k]) < 0 ){ swap(k, k/2); k /= 2; } } private void shftDown(int k){ while( 2*k <= count ){
int j = 2*k; // このサイクルでは、data[k] と data[j] の位置が交換されます
if( j+1 <= count && data[j+1].compareTo(data[j]) > 0 )
j ++;
// data[j] は data[2*k] と data[2*k+1] の最大値
if( data[k].compareTo(data[j]) >= 0 ) Break;
swap(k, j);
k = j;
}
}
// テスト heapify
public static void main(String[] args) { int N = 100; Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000) ; Heapify <Integer> heapify = new Heapify<Integer>(arr); // extractMax を使用して heapify 内のデータを段階的に抽出します // 抽出の順序は大きいものから小さいものへ行う必要があります
for( int i = 0 ; i < N ; i ++ ){ arr[i] = heapify.extractMax(); System.out.print(arr[i] + " "); } // arr 配列を確認しますは assert arr[i-1] >= arr[i] For( int i = 1 ; i < N ; i ++ ) } }