2016-12-19 24 views
1

min heapデータ構造を実装するために次のプログラムを書きましたが、期待される出力が得られません。C++の出力順序

#include <iostream> 
#include <iomanip> 
#include <vector> 

using namespace std; 

class MinHeap 
{ 
    vector<int> heap; 
    int size; 

public: 
    MinHeap() 
    { 
     //cout<<"asc"; 
     size=0; 
    } 

    void insert(int n); 
    void heapify(int i); 
    int extract_min(); 

    int get_size() 
    { 
     return size; 
    } 
}; 

void MinHeap::insert(int n) 
{ 
    int i=size, parent; 
    parent=(i-1)/2; 
    heap.push_back(n); 
    size++; 

    while(i>0) 
    { 
     if(heap[i]<heap[parent]) 
     { 
      swap(heap[i], heap[parent]);    
     } 
     else 
      break; 
     i=parent; 
     parent=(i-1)/2; 
    } 
} 

void MinHeap::heapify(int i) 
{ 
    int left=2*i+1, right=2*i+2, min_index=i; 

    if(left<size && heap[left]<heap[min_index]) 
     min_index=left; 
    if(right<size && heap[right]<heap[min_index]) 
     min_index=right; 
    if(min_index!=i) 
    { 
     swap(heap[i], heap[min_index]); 
     heapify(min_index); 
    } 
} 

int MinHeap::extract_min() 
{ 
    int i=size-1, temp; 

    if(i>=0) 
    { 
     temp=heap[0]; 
     heap[0]=heap[i]; 
     size--; 
     heapify(0); 

    } 
    return temp; 
} 



int main() 
{ 

    int n, i, last=0, val, j; 
    MinHeap h; 
    h.insert(10); 
    h.insert(5); 
    h.insert(7); 
    h.insert(1); 
    cout<<h.extract_min()<<" "<<h.extract_min()<<" "<<h.extract_min()<<" "<<h.extract_min(); 
    // cout<<h.extract_min()<<"\n"; 
    // cout<<h.extract_min()<<"\n"; 

    return 0; 
} 

出力:10 7 5 1

予想される出力:1 5 7 10

私はコメント行で行ったように私は、(別のラインでそれらを印刷するとき、私は、期待される出力を得ることがメインのreturn 0以上)。

私はあまりにも些細なことを逃した場合は申し訳ありません。

+2

はまた、(例えば[ 'のstd :: make_heap']として、標準ライブラリはすでにヒープを管理するためのいくつかの機能を持っていることに注意してくださいhttp://en.cppreference.com/w/cpp/algorithm/make_heap )。 – Holt

+0

ありがとうございます。それは、 'Min Heap'のために使うライブラリである' Max Heap'を構築していると言います(あるいは適切な 'comp'関数を引数として与えるだけですか?)。 – shiva

+0

適切な 'comp'(例えば、' std :: greater ')を提供するだけです。 – Holt

答えて

4

h.extract_min()は明らかに変数hを変更します。したがって、ここでは、1つのステートメント内で同じ変数の複数の変更があります。残念ながら、C++標準では文の実行順序が指定されていないので、h.extract_min()への別の呼び出しは必ずしも左から右の方法で実行されるわけではありません(実際には右から左への順序ですが、ループを使用して検討し、正しい出力および読み取り可能なコードを持っている

:ほぼすべてのC++の演算子(のオペランドの評価の

for (int i = 0; i < 4; ++i) { 
    cout << h.extract_min() << ' '; 
} 
+0

これは 'C++標準では文の実行順序を指定していません。' 'cout'内の文を意味していますか? – shiva

+0

@shivaはい。 '<< h.extract_min() 'は、いくつかの関数呼び出しを持つ文です(' 'h.extract_min()' ')。それらの間に複数の '<<"演算子があります。すべての関数呼び出しは、任意の順序で実行できます。 – alexeykuzmin0

0

注文を関数呼び出し式の関数の引数の評価の順序を含むと任意の式内の部分式の評価の順序)は不特定である。コンパイラは、任意の順序でオペランドを評価することができ、同じ式が再度評価されるときに別の順序を選択することができます。

http://en.cppreference.com/w/cpp/language/eval_order

関連する問題