序文コンピュータ サイエンスでは、ツリーは広く使用されている抽象データ型 (ADT) であり、非線形データ構造の一種です。ツリー、特にバイナリツリーはコンピューター分野で広く使用されています。 ツリー関連の概念:
1. バイナリツリー概念: 各ノードに最大 2 つのサブツリーが含まれるツリーは、バイナリ ツリーと呼ばれます。 1.1. 二分木の走査バイナリ ツリーのトラバーサルには、深さトラバーサルと幅トラバーサルの 2 種類があります。深さトラバーサルには、事前順序、インオーダー、事後順序の 3 つのトラバーサル方法があります。 幅方向のトラバーサルは、レイヤーごとに順番にトラバーサルするレベル方向のトラバーサルです。 4 つのトラバーサルの主なアイデアは次のとおりです。
たとえば、a+b*(cd)-e/f という式はバイナリ ツリーで表されます。 それらを個別にトラバースします。
1.2. jsを使用してバイナリツリーを表現するバイナリ ツリーを表すには、js オブジェクトを使用します。オブジェクトには、left、value、right の 3 つのプロパティがあり、それぞれ左サブツリー、値、右サブツリーを表します。上記の例 a+b*(cd)-e/f は、js を使用して次のように表すことができます。 var ツリー = { 価値: '-'、 左: { 値: '+', 左: { 値: 'a' }, 右: 価値: '*'、 左: { 値: 'b' }, 右: 価値: '-'、 左: { 値: 'c' }, 右: 値: 'd' } } } }, 右: 価値: '/'、 左: { 値: 'e' }, 右: 値: 'd' } } } 1.3 事前順序探索アルゴリズム前書き: 方法は 2 つあります。最初の方法は非常に簡単で、再帰を直接使用する方法です。 関数 preOrder(treeNode) { if(ツリーノード) { console.log(treeNode.value); // 出力は、このノードにアクセスすることを意味します preOrder(treeNode.left); ツリーノードを右にプリオーダーします。 } } アルゴリズムは非常にシンプルです。まずルート ノードをトラバースし、次に左のサブツリーを再帰的にトラバースします。左のサブツリーをトラバースした後、右のサブツリーを再帰的にトラバースします。 2番目の非再帰的走査 関数 preOrder(treeNode) { if(ツリーノード) { var stack = [treeNode]; // バイナリツリーをスタックにプッシュします while (stack.length !== 0) { treeNode = stack.pop(); // スタックの先頭を取得します。 document.getElementById('text').appendChild(document.createTextNode(treeNode.value)); // ノードにアクセスします。 if(treeNode.right) stack.push(treeNode.right); // 右のサブツリーをスタックにプッシュします。 if(treeNode.left) stack.push(treeNode.left); // 左のサブツリーをスタックにプッシュします。 } } } 2 つ目は、スタックの考え方を使うことです。ご存知のとおり、スタックは先入れ後出しのデータ構造です。最初にルート ノードをスタックにプッシュし、次にスタックの先頭を取り、ルート ノードにアクセスして、右と左のサブツリーをそれぞれスタックにプッシュします。最初に左側からアクセスする必要があるため、右側を最初にスタックにプッシュする必要があります。そのため、最初に右側のサブツリーをスタックにプッシュし、次にスタックが空になるまでスタックを取り出すループを実行します。 1.4. 順序探索アルゴリズム順序再帰アルゴリズム: 関数InOrder(treeNode) { if(ツリーノード) { ツリーノードの左端に順序を付けます。 document.getElementById('text').appendChild(document.createTextNode(treeNode.value)); ツリーノードの右端に順序を付けます。 } } 事前順序再帰アルゴリズムと同じ考え方だが、訪問したノードの位置が異なる 2番目のタイプ: 関数InOrder(ノード) { if(ノード) { var stack = []; // 空のスタックを作成する // スタックが空でないかノードが空でない場合は、while (stack.length !== 0 || node) { をループします。 if (node) { //ノードが空でない場合 stack.push(node); //ノードをスタックにプッシュします node = node.left; //左のサブツリーを現在のノードとして使用します } else { //左のサブツリーが空です。つまり、左のサブツリーはありません node = stack.pop(); //ノードを取り出します document.getElementById('text').appendChild(document.createTextNode(node.value)); node = node.right; // 右ノードを現在のノードとして使用します} } } } 非再帰的順序アルゴリズムの考え方は、現在のノードをスタックにプッシュし、次に左のサブツリーをトラバースし、左のサブツリーが存在する場合は、左のサブツリーが空になるまでスタックにプッシュし続け、前のノードにアクセスし、右のサブツリーをスタックにプッシュすることです。 1.5. 後順序探索アルゴリズム1つ目: 再帰的トラバーサルアルゴリズム 関数 postOrder(ノード) { if (node) { // バイナリツリーが空かどうかを判断します postOrder(node.left); // 左のサブツリーを再帰的にトラバースします postOrder(node.right); // 右のサブツリーを再帰的にトラバースします document.getElementById('text').appendChild(document.createTextNode(node.value)); } } 2番目: 非再帰的トラバーサルアルゴリズム 関数 postOrder(ノード) { if (node) { //バイナリツリーが空かどうかを判断var stack = [node]; //バイナリツリーをスタックにプッシュvar tmp = null; //キャッシュ変数を定義while (stack.length !== 0) { //スタックが空でない場合はループしますtmp = stack[stack.length - 1]; //スタックの最上位の値をtmpに保存if (tmp.left && node !== tmp.left && node !== tmp.right) { //左のサブツリーがある場合、node !== tmp.left && node !== tmp.right は、左と右のサブツリーを繰り返しスタックにプッシュすることを回避するためですstack.push(tmp.left); //左のサブツリーノードをスタックにプッシュします} else if (tmp.right && node !== tmp.right) { //ノードに右のサブツリーがある場合stack.push(tmp.right); //右のサブツリーをスタックにプッシュします} else { document.getElementById('text').appendChild(document.createTextNode(stack.pop().value)); ノード = tmp; } } } } ここでは、最後にポップおよびプッシュされたノードを記録するために tmp 変数が使用されます。アイデアとしては、まずルート ノードと左のツリーをスタックにプッシュし、次に左のツリーを取り出し、右のツリーをプッシュして取り出し、最後にルート ノードを取り出すというものです。 以下は、このアルゴリズムを使用して前のバイナリツリーをトラバースするプロセスです。
1.6. レイヤーごとのトラバーサルアルゴリズム関数breadthTraversal(ノード) { if (node) { //バイナリツリーが空かどうかを判断var que = [node]; //バイナリツリーをキューに入れますwhile (que.length !== 0) { //キューが空かどうかを判断node = que.shift(); //キューからノードを取得しますdocument.getElementById('text').appendChild(document.createTextNode(node.value)); //取得したノードの値を配列に保存しますif (node.left) que.push(node.left); //左のサブツリーが存在する場合は、左のサブツリーをキューに入れますif (node.right) que.push(node.right); //右のサブツリーが存在する場合は、右のサブツリーをキューに入れます} } } 配列を使用してキューをシミュレートし、最初にルート ノードをキューに配置します。キューが空でない場合は、ループを実行します。キューからノードを取り出し、ノードに左サブツリーがある場合は、ノードの左サブツリーをキューに格納します。ノードに右サブツリーがある場合は、ノードの右サブツリーをキューに格納します。 2. アルゴリズムに関する質問1.1. 二分木の最大深さバイナリツリーが与えられた場合、その最大深さを見つけます。 バイナリ ツリーの深さは、ルート ノードから最も遠いリーフ ノードまでの最長パス上のノードの数です。 たとえば、次のバイナリ ツリーは深さ 3 を返します。
再帰アルゴリズム:再帰アルゴリズムの考え方は非常にシンプルです。まず、左のサブツリーの最も深い層を取得し、次に右のサブツリーの最も深い層を取得し、それらの最大値がツリーの深さになります。 var maxDepth = function(ルート) { ルートの場合 0を返します。 } 定数 leftDeep = maxDepth(root.left) + 1; 定数 rightDeep = maxDepth(root.right) + 1; Math.max(leftDeep, rightDeep) を返します。 }; /* 最大深度(ルート) = 最大深度(ルート.左) + 1 = 2 最大深度(ルート.左) = 最大深度(ルート.左.左) + 1 = 1 最大深度(ルートの左端) = 0; 最大深度(ルート) = 最大深度(ルート.右) + 1 = 3 最大深度(ルート.右) = 最大深度(ルート.右.右) + 1 = 2 最大深度(ルート.右.右) = 最大深度(ルート.右.右.右) + 1 = 1 最大深度(ルート右右右) = 0 */ 1.2. 二分木のすべてのパスバイナリ ツリーが与えられた場合、ルート ノードからリーフ ノードまでのすべてのパスを返します。 例えば:
再帰メソッドの使用: var binaryTreePaths = function(ルート) { if (!root) は [] を返します。 定数res = []; 関数 dfs(curNode, curPath) { if(!curNode.left && !curNode.right) { res.push(curPath); } 左のノードの場合 dfs(curNode.left, `${curPath}->${curNode.left.value}`) } 右のノードの場合 dfs(curNode.right、`${curPath}->${curNode.right.value}`) } } dfs(ルート、`${root.value}`); res を返します。 }; 要約するJS を使用してバイナリ ツリー トラバーサル アルゴリズムを実装する方法に関するこの記事はこれで終わりです。JS バイナリ ツリー トラバーサル アルゴリズムに関する関連コンテンツをさらにご覧になりたい場合は、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: MySQL マスタースレーブレプリケーションと読み取り書き込み分離の詳細な説明
落とし穴1. ネット上の多くのチュートリアルでは環境変数を設定するファイル名はmy.iniと書いてあ...
目次1. NFS-Ganeshaの紹介2. NFS-Ganeshaの設定3. NFS-Ganesha...
効果画像: 1. ファイルをインポートする<script src="js/jquer...
この記事では、例を使用して、MySQL ビューの作成 (CREATE VIEW) と使用上の制限につ...
今日、MySQL データベースをコンピューターに再度インストールしました。システムを再インストールす...
最近、ブルートフォース攻撃によるサーバのクラッキングが頻発しています。侵入行為を大まかに分析し、よく...
1. はじめにコンテナはサンドボックス メカニズムを使用して相互に分離します。コンテナ内にデプロイさ...
1. はじめに要件は、特定の時間範囲内で、1 時間ごとのデータと前の 1 時間ごとのデータの差と比率...
目次1. 問題のあるSQL文たとえば、次の図のような質問をした人がいました。 問題は次のように要約で...
ビンログBinLog は、データベース テーブル構造の変更 (テーブルの作成、変更など) とテーブル...
1つ目:通常動作 選択 SUM(ddd) AS count_days、 場合 aa.days >...
昨日 HTML を少し学んだばかりで、JD.com の検索バーを作るのが待ちきれませんでした。 作っ...
この記事では、JavaScriptでシンプルな時計を実装するための具体的なコードを参考までに紹介しま...
目次並べ替えクエリの最適化変更されたばかりのデータ行を繰り返し取得しないようにする遅延ロードされた結...
序文mysql がデフォルトのデータベース パスを変更したため、サービスを開始できませんでした。ログ...