スタックとヒープの並べ替え:なぜ速い速いソート・ヒープ行をしませんでしたか?
スタック(HEAP)その場で、時間計算量はO(nlogn)ソートアルゴリズムであります
実際のソフトウェア開発では、高速なパフォーマンスがなぜ良いのヒープ・ソートよりもランクの?
ヒープを理解するには?
ミートこれら2つの点がヒープであります
- ヒープは完全2分木であります
- ヒープの各ノードの値は、サブツリーの各ノードのために等しい(またはそれ以下)の値よりも大きくなければなりません。
各ノードの値は、より大きいまたは「ビッグトップスタック」と呼ばれる値ツリーの各ノードで同じサブスタック、そうでない場合は「小パイルトップ」であります
ヒープを達成するためにどのように?
どのオペレーティングスタックをサポートしていますか?あなたは、ヒープを保存する場合は?
単に配列インデックスによって、記憶された左、右の子ノードポインタは、左の子ノードとノードの親ノードを見つけることができる格納する配列のための完全なバイナリツリー、
アレイiは、ノード標識2Iである左の子ノードの添え字+ 2I親ノードの1標識右の子ノードである標識されているノードのI / 2の
コアスタック動作は、スタック要素と削除素子(典型的には、大きなスタックトップ)のスタックの上部を挿入することです
1.スタック要素を挿入するには
要素を挿入した後、新たに挿入された要素が比較的大きいような、条に準拠していない(ヒープの二つの特徴を満たすために継続することが、新しい要素が最後にヒープに挿入される場合、ヒープの特性を満たしていない必要があります私たちはもう一度プロパティを聞かせて満たすように調整する必要があるので)の特性、のヒープと呼ばれるプロセス
ノードがアップまたはダウン、経路に沿って配置され、コントラスト、及びその後の交換の2つの反応器の種類、下からおよび上から下まで、メソッドからスタックアップの話があります
public class Heap{
private int[] a ; //数组,从下标1开始存储数据
private int n; //堆可以存储的最大数据个数
private int count;// 堆中已经存储的数据个数
public Heap(int capacity){
a = new int[capacity + 1];
n = capacity;
count = 0;
}
public void insert(int data){
if(count >= n ) return;//堆满了
++count;
a[count] = data;
int i = count;
while(i/2 > 0 && a[i] > a[i/2]){ //自下往上堆化
swap(a,i,i/2); //swap()函数作用:交换小标为i 和i/2的两个元素
i=i/2;
}
}
}
ヒープ要素の上部を取り外します2。
スタックの先頭に最後のノード、及び上から下にある大小関係まで満たされるまで、比較親と子ノードと同様の方法で、親 - 子ノードは、親ノードと子ノードとの大小関係、2つのノード交換を満たしていませんヒープの方法。
我々は、アレイ内の最後の要素を除去し、プロセスのヒープ、全てのスワップ動作において、NO「ホール」
public void removeMax(){
if(count == 0) return -1; //堆中没有数据
a[1] = a[count]; //把最后一个元素放到堆顶
--count; //堆的规模-1
heapify(a,count,1); //堆化完成,count是长度
}
public void heapify(int[] a ,int n ,int i){ //自上往下堆化
while(true){
int maxPos = i ;
if(i*2 <= n && a[i] < a[i*2]) maxPos = i*2+1;
if(maxPos == i) break;
swap(a ,i ,maxPos);
i = maxPos;
}
}
完全なバイナリのツリーNノードを含むツリーのlog2n高さを超えて、ノードのスタックがコンパレータに処理経路に沿って配置されていないので、すなわちOツリーの高さに時間比例との複合体のスタック(log2n)は、交換、スタックの要素と時間複雑さの削除要素の充填上部を挿入すると、O(LOGN)であります
ヒープの並べ替えを実装する方法?
スタックの構築と、ソート:時間複雑度順に並べ替えO(nlogn)、二つの主要な段階へのプロセスダウンのヒープ一種であります
1.内蔵ヒープ
スタックの配列を作成する場所は、元の配列で動作しています
A:挿入スタック思想の要素、最初に一つだけのスタックデータをそれを想定し、インデックスデータが1である、挿入呼び出し、添字2 N順次スタックに挿入されたデータは、この意志データ編成n個のデータのパイルアップ
II:我々は非リーフノードから直接起動、それはのヒープを回すことができるように対話ダウンリーフノードのみが、自分自身と自分自身を比較することができます
public static void buildHeap(int[] a ,int n){
for (int i = n/2 ; i >= 1 ;--i){
heapify(a,n,i);
}
}
private static void heapify(int[] a ,int n,int i){
while(true){
int maxPos = i;
if(i*2 <= n && a[i] < a[i*2]) maxPos = i*2;
if(i*2+1 <= n && a[maxPos] < a[i*2+1]) maxPos = i*2+1;
if(maxPos == i) break;
swap(a,i,maxPos);
i = maxPos;
}
}
、スタックのN / 2〜1データから始まるスタックの下位n / 2 + 1〜n個のノードであるリーフノードを示すことは必要がありません
実際には、スタックの構築プロセスヒープソートの時間計算量はO(N)であります
ヒープのないリーフノードは、カウントダウンからのノードの第2の層とを積層し始めている必要があり、プロセスのヒープ内の各ノードは、ノードの数は、比較するために必要とノードとの交換は、高さkに比例します。
2.ソート
ヒープの建設後、データアレイの構成は、ヒープの大きなトップの特性に応じてあります
配列の最初の要素は、ヒープ要素の除去の上部、添字nはの要素である場合、インデックス位置における最大の要素を置く交換の最後の要素と最大要素であり、ヒープの最上部、であり、nはスタックの最上部、およびスタック要素のその後再構築する残りのn-1の要素のスタックを、スタックした後、再取る上部に、N-1、の位置に、マークがあるまで、繰り返し1要素
//n表示数据的个数,数组a中的数据从下标1到n的位置
public static void sort(int[] a ,int n){
buildHeap(a,n);
int k = n;
while (k > 1){
swap(a,1,k);
--k;
heapify(a,k,1);
}
}
ソートのヒープソートアルゴリズムは、ソート処理ので、動作ノードと交換スタックのスタック上の最後のノードの存在は、それが同じ相対的な順序の元データの値を変更することが可能となり、安定していません
実際の開発では、なぜこれほどの高速並列処理のヒープソートのパフォーマンス?
:ヒープソートデータ・アクセス・モードは、高速友情行としてではありません
高速行が順次データをアクセスし、ヒープ・ソート・データがアクセスされる跳躍
II:同じデータ、ソート処理のために、データ交換ヒープソートアルゴリズムは、より高速な行数よりも