最大ヒープにPがCの親ノードである場合、Pのキー(値)よりも大きいか、または(に等しい:コンピュータサイエンスでは、ヒープは満足ヒーププロパティこと専門ツリーベースのデータ構造であります)未満又は分ヒープ内(に等しい)ヒープのC. A共通実装の鍵は、ツリーが完全二分木であるバイナリヒープ、です。(でウィキペディアより引用 https://en.wikipedia.org/wiki/Heap_(data_structure))
あなたの仕事は、与えられた完全なバイナリツリーがヒープであれば言うことです。
入力仕様:
各入力ファイルには、1つのテストケースが含まれています。各場合について、最初の行は、2つの正の整数与える:M(≤100)、試験されるべき木の数を、およびN(1 <N ≤1,000)、それぞれのツリーにおけるキーの数、。次いで、M行の各々は、完全二分木のレベル順トラバーサル順序を与え、(すべてのINTの範囲内)N異なる整数キーが含まれ、従います。
出力仕様:
それぞれ与えられた木のために、ラインに印刷する Max Heap
ことが最大ヒープである場合、または Min Heap
最小ヒープのため、または Not Heap
それがすべてではヒープではない場合。そして、次の行に木の後順トラバーサルシーケンスを印刷。すべての数値は、スペースで区切られ、先頭または行の末尾に余分なスペースがありませんしなければなりません。
サンプル入力:
3 8
98 72 86 60 65 12 23 50
8 38 25 58 52 82 70 60
10 28 15 12 34 9 8 56
サンプル出力:
Max Heap
50 60 65 72 12 23 86 98
Min Heap
60 58 52 38 82 70 25 8
Not Heap
56 12 34 28 9 8 15 10
質問の意味:
ツリートラバーサルシーケンスに、それはヒープであるかどうかを判断、ヒープが大きいか小さい屋根の上スタックです。ツリーの出力後順トラバーサル〜
ソリューション:
入力プログラムは、キュートラバーサルの成果を借りるときはしばらく建て再帰的に先行順木出力以来、原子炉のタイプの決意、。
暴力あまりにも面倒な方法で、誰かの家下記のコード。。。
この質問の考え方はしやすいが、あまり熟練した成果ですが、成果は通常2つの方法があります::成果と貢献リストの配列は、参照成果の2つのメソッドを
ACコード:
書式#include <iostreamの> の#include <アルゴリズム> 書式#include <キュー> の#include <スタック> 使用して 名前空間をSTD。 整数M、N。 構造体ノード{ INT V。 ノード L *、* R。 }。 キュー <ノード*> Q; int型の合計= 0 ; ノード * newnode(INT X){ // 新建一个节点 ノード* newnode = 新しいノード。 newnode - > V = X; newnode - > L = newnode-> R = NULL; リターンnewNode; } ボイド後順(ルートノード*&){ // 後順 IF(ディレクトリroot-> L)後順(ディレクトリroot-> L); IF(ディレクトリroot-> R&LT)後順(ディレクトリroot-> R&LT); SUM ++。// スペースを追加するかどうかを計算するための COUT <<ディレクトリroot-> Vを; のiF(!= SUM N-)COUT << " " ; 他 COUT << てendl; } int型のmain(){ CIN >> M >> N-。 INT X、 ノード・ルート、 のための(INT I = 1 ; I <= M、I ++){ のInt F = 0 ; //は。大いに昇順1 ながら(!Q.empty())q.pop(); のための(INT J = 1 J <= N; J ++ ){ CIN >> X; IF(J == 1 ){ ルート = newNode(X); q.push(根); 続行; } ながら(!q.empty()){ // 配列キュートラバーサルが有するより便利である ノードA * = q.front (); ノード * B = newNode(X)。 IF(A-> L == NULL){ A - > L = B; } そう IF(A-> R&LT == NULL){ A - > = R&LT B; } そうでなければ{ q.pop(); // もし約ノードチームヘッドがアウトキューヘッドの離れてそれを入れ、次いで充填し 続け; } q.push(B); IF(F == 0 && A-> V <X){ // 解釈ツリータイプ F = 。1 ; // 。大幅に上昇1 } 他 IF(F == 0A- &&> V> X){ F = 2 ; // 2に下降 } 他 IF(F == 1 && A-> V> X){ F = - 1 ; // 条件を満たしていません- 1 } 他 IF(F == 2 && A-> V < X){ F = - 1 ; } BREAK ; //がジャンプすることを忘れない } } SUM = 0 ; IF(F == 1 ){ COUT << " 最小ヒープ" << ENDL。 } そう であれば(F == 2 ){ COUT << " 最大ヒープ" << ENDL。 } 他の裁判所未満<< " 未ヒープ" << てendl; 後順(ルート)。 } 戻り 0 。 }
実績のない簡単な方法:
最初は、V [0]、Vに従って、[1]の大小比較が大きいか小さい屋根の上であってもよい決定し、割り当てられたフラグが1であり、-1、最初のトラバーサル順序に従って、0からN / 2-1すべての子を[有しますノード]それはフラグ= 0が、これはヒープではないことを示しますが、その子ノードが満たされない場合、フラグの要件を満たすためではない判断。出力スタックかどうかのフラグ、大トップスタックまたは小トップスタックと後順トラバーサルインデックストラバーサル指数* 2 + 1それぞれのインデックス* 2 + 2、すなわちその左右子供、トラバース出力ルートが左後及び右サブツリー接合後、すなわち完全予約限定!〜
書式#include <iostreamの> の#include <ベクトル> 使用して 名前空間はstdを、 整数M、N。 ベクトル < int型 > V。 ボイド後順(int型のインデックス){ 場合(インデックス> = n)のリターン; 後順(指数 * 2 + 1 )。 後順(指数 * 2 + 2 )。 printf(" %dの%sの"、V [インデックス]、インデックス== 0?" \ nは":" "); } int型のmain(){ scanf関数(" %D%D "、&M、&N) v.resize(N) 以下のために(INT iが= 0 ; I <M、I ++ ){ ため(INT J = 0 ; nはJ <; J ++)のscanf(" %dの"、&V [J])。 INTフラグ= V [ 0 ]> V [ 1 ]?1: - 1 。 用(INT J = 0 ; J <N / 2、J ++){ intは =左J * 2 + 1、右= J * 2 + 2 。 もし(フラグ== 1 &&(V [J] <V [左] ||(右<N && V [J] <V [右])))フラグ= 0 。 もし(フラグ== - 1 && [左](V [J]> V ||(右<N && V [J]> V [右])))フラグ= 0 。 } であれば(フラグ== 0)のprintf(" ませんヒープ\ n " ); 他のprintf(" %sのヒープ\ N "、" マックス":" 分" ); 後順(0 )。 } 戻り 0 。 }