基本的なヒープソート(Javaサンプルコード)

目次

 

基本的なヒープソート

1. コンセプトと紹介

2. 適用される命令

3. プロセス図

4. Java サンプルコード

src/runoob/heap/Heapify.java ファイルコード:


 

基本的なヒープソート

1. コンセプトと紹介

ヒープソート (Heapsort) は、ヒープのデータ構造を使用して設計されたソート アルゴリズムを指します。

ヒープは完全なバイナリ ツリーに近似する構造であり、同時に累積の性質も満たします。つまり、子ノードのキー値またはインデックスは常に親ノードより小さい (または大きい) ものです。

2. 適用される命令

ヒープを構築する以前のプロセスは、insert メソッドを呼び出し、シフトアップを使用してデータを 1 つずつヒープに挿入することでした。このアルゴリズムの時間計算量は O(nlogn) です。このセクションで紹介するヒープ ソートの構築プロセスはHeapifyと呼ばれ、アルゴリズムの時間計算量はO(n)です。

3. プロセス図

完全な二分木の重要な特性は、最初の非リーフ ノードのインデックスが、n/2から整数を取得して得られるインデックス値であることです。ここで、 nは要素の数です (配列インデックスが 1 から始まる場合)。 。

 

8533aeaabb8bcf09d2f2cd103cd9ff0e.png

インデックス 5 の位置は最初の非リーフ ノードであり、最大ヒープの性質を満たすために、そこから 1 つずつ開始してルート ノードとして各要素に対してシフト ダウン操作を実行します。

シフトダウン操作がインデックス 5、22、62 で実行された後、ポジションが交換されます。

 

5e791e13029e315ffdf601d7dac7837f.png

インデックス 4 要素に対してシフトダウン操作を実行します。

 

78f5380da0c82c652b1bc821a8b0236e.png

インデックス 3 要素に対してシフトダウン操作を実行します。

 

d88f077f5f376a8aeaf89f450e7d57ff.png

インデックス 2 要素に対してシフトダウン操作を実行します。

 

61f8df73255048aae76de8b24454c38e.png

最後に、ルート ノードでシフト ダウン操作を実行すると、ヒープ ソート プロセス全体が完了します。

 

dc779b8bcc78fd27af078d7b2f4d7819.png

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 ++ )     } }








 

おすすめ

転載: blog.csdn.net/2301_78835635/article/details/132163995