<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>数据结构 on 孤筝の温暖小家</title><link>https://www.guzhengsvt.cn/ja/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/</link><description>Recent content from 孤筝の温暖小家</description><generator>Hugo</generator><language>ja</language><managingEditor>lvbowen040427@163.com (孤筝)</managingEditor><webMaster>lvbowen040427@163.com (孤筝)</webMaster><copyright>本ブログのすべての文書は、特に指定されていない限り、BY-NC-SAライセンスに従っています。引用の際は出典を明記してください！</copyright><lastBuildDate>Tue, 12 Dec 2023 14:56:33 +0800</lastBuildDate><atom:link href="https://www.guzhengsvt.cn/ja/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/index.xml" rel="self" type="application/rss+xml"/><item><title>データ構造実機実験レポート6——前順序・後順序による二分木のスレッド化、グラフの隣接行列と隣接リストの格納</title><link>https://www.guzhengsvt.cn/ja/post/code/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%AE%9E%E6%9C%BA%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A6%E5%89%8D%E5%BA%8F%E5%90%8E%E7%BB%AD%E5%B0%86%E4%BA%8C%E5%8F%89%E6%A0%91%E7%BA%BF%E7%B4%A2%E5%8C%96%E5%9B%BE%E7%9A%84%E9%82%BB%E6%8E%A5%E7%9F%A9%E9%98%B5%E5%92%8C%E9%82%BB%E6%8E%A5%E8%A1%A8%E7%9A%84%E5%AD%98%E5%82%A8/</link><pubDate>Tue, 12 Dec 2023 14:56:33 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/ja/post/code/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%AE%9E%E6%9C%BA%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A6%E5%89%8D%E5%BA%8F%E5%90%8E%E7%BB%AD%E5%B0%86%E4%BA%8C%E5%8F%89%E6%A0%91%E7%BA%BF%E7%B4%A2%E5%8C%96%E5%9B%BE%E7%9A%84%E9%82%BB%E6%8E%A5%E7%9F%A9%E9%98%B5%E5%92%8C%E9%82%BB%E6%8E%A5%E8%A1%A8%E7%9A%84%E5%AD%98%E5%82%A8/</guid><description>
<![CDATA[<h1>データ構造実機実験レポート6——前順序・後順序による二分木のスレッド化、グラフの隣接行列と隣接リストの格納</h1><p>著者: 孤筝(lvbowen040427@163.com)</p>
        
          <h2 id="前順序後順序による二分木のスレッド化">
<a class="header-anchor" href="#%e5%89%8d%e9%a0%86%e5%ba%8f%e5%be%8c%e9%a0%86%e5%ba%8f%e3%81%ab%e3%82%88%e3%82%8b%e4%ba%8c%e5%88%86%e6%9c%a8%e3%81%ae%e3%82%b9%e3%83%ac%e3%83%83%e3%83%89%e5%8c%96"></a>
前順序、後順序による二分木のスレッド化
</h2><h3 id="a-問題分析">
<a class="header-anchor" href="#a-%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
a. 問題分析
</h3><p>二分木の前順序スレッディングを実装する必要があります。スレッディングとは、二分リンクリストの空ポインタ領域を、特定の走査順序における前駆ノードまたは後続ノードを指すように変更する方法です。これにより、前順序、中順序、または後順序のいずれかのノードから開始することができ、根ノードからだけではなくなります。</p>
<h3 id="b-アルゴリズム設計">
<a class="header-anchor" href="#b-%e3%82%a2%e3%83%ab%e3%82%b4%e3%83%aa%e3%82%ba%e3%83%a0%e8%a8%ad%e8%a8%88"></a>
b. アルゴリズム設計
</h3><p>私たちのアルゴリズムはまず二分木を作成し、その後それをスレッド化します。スレッド化のプロセスは再帰関数によって実装され、この関数は各ノードを走査し、その左右の子ノードが存在するかどうかをチェックします。存在しない場合、その左/右ポインタを前/次のノードに指向させます。最後に、スレッド化が成功したかどうかを確認するため、中間順走査を行います。</p>
<p>以下はスレッド化のコードスニペットです：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="c1">// スレッドを作成する関数
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">createThread</span><span class="p">(</span><span class="n">Node</span><span class="o">*</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">p</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// ノードが空の場合、直接戻る
</span></span></span><span class="line"><span class="cl">        <span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">createThread</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">);</span> <span class="c1">// 左部分木を再帰的に処理
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 左子ノードが空の場合、左ポインタを前のノードに指向させ、左スレッドフラグを1に設定
</span></span></span><span class="line"><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">pre</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">ltag</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">pre</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">pre</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 前のノードの右子ノードが空の場合、その右ポインタを現在のノードに指向させ、右スレッドフラグを1に設定
</span></span></span><span class="line"><span class="cl">        <span class="n">pre</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">pre</span><span class="o">-&gt;</span><span class="n">rtag</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">pre</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span> <span class="c1">// 前のノードを更新
</span></span></span><span class="line"><span class="cl">    <span class="n">createThread</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">);</span> <span class="c1">// 右部分木を再帰的に処理
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="c-データ構造設計">
<a class="header-anchor" href="#c-%e3%83%87%e3%83%bc%e3%82%bf%e6%a7%8b%e9%80%a0%e8%a8%ad%e8%a8%88"></a>
c. データ構造設計
</h3><p>二分木のノードを表現するために、構造体を使用します。この構造体には、データフィールドと2つのポインタフィールドが含まれており、それぞれ左子ノードと右子ノードを指します。さらに、左右のポインタがスレッド化されているかどうかを示す2つのマークフィールドを追加しました。</p>
<p>以下はデータ構造のコードスニペットです：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="c1">// 二分木ノードの構造体を定義
</span></span></span><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">Node</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">data</span><span class="p">;</span> <span class="c1">// ノードのデータ
</span></span></span><span class="line"><span class="cl">    <span class="n">Node</span><span class="o">*</span> <span class="n">left</span><span class="p">;</span> <span class="c1">// 左子ノード
</span></span></span><span class="line"><span class="cl">    <span class="n">Node</span><span class="o">*</span> <span class="n">right</span><span class="p">;</span> <span class="c1">// 右子ノード
</span></span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ltag</span><span class="p">,</span> <span class="n">rtag</span><span class="p">;</span> <span class="c1">// 左右スレッドマーク
</span></span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><h3 id="d-デバッグプロセス">
<a class="header-anchor" href="#d-%e3%83%87%e3%83%90%e3%83%83%e3%82%b0%e3%83%97%e3%83%ad%e3%82%bb%e3%82%b9"></a>
d. デバッグプロセス
</h3><p>まず二分木を作成し、それをスレッド化します。その後、中順走査を行い、スレッド化が成功したかどうかを確認します。走査結果が期待通りの結果と一致すれば、スレッド化は成功したと判断できます。</p>
<p>以下はデバッグプロセスのコードスニペットです：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 二分木を作成
</span></span></span><span class="line"><span class="cl">    <span class="n">Node</span> <span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">,</span> <span class="n">n3</span><span class="p">,</span> <span class="n">n4</span><span class="p">,</span> <span class="n">n5</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">n1</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n2</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n2</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n4</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n3</span> <span class="o">=</span> <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n4</span> <span class="o">=</span> <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n5</span> <span class="o">=</span> <span class="p">{</span><span class="mi">5</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 二分木をスレッド化
</span></span></span><span class="line"><span class="cl">    <span class="n">createThread</span><span class="p">(</span><span class="o">&amp;</span><span class="n">n1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// スレッド化された二分木を中順走査
</span></span></span><span class="line"><span class="cl">    <span class="n">inOrder</span><span class="p">(</span><span class="o">&amp;</span><span class="n">n1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="e-出力結果">
<a class="header-anchor" href="#e-%e5%87%ba%e5%8a%9b%e7%b5%90%e6%9e%9c"></a>
e. 出力結果
</h3><p>プログラムの出力結果は二分木の中間順走査結果であるべきです。この例では、出力結果は <code>4 2 5 1 3</code> となるはずです。作成した二分木の中間順走査結果がこのシーケンスになります。</p>
<h3 id="f-ソースコード">
<a class="header-anchor" href="#f-%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89"></a>
f. ソースコード
</h3><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include&lt;iostream&gt;
</span></span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 二分木ノードの構造体を定義
</span></span></span><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">Node</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">data</span><span class="p">;</span> <span class="c1">// ノードのデータ
</span></span></span><span class="line"><span class="cl">    <span class="n">Node</span><span class="o">*</span> <span class="n">left</span><span class="p">;</span> <span class="c1">// 左子ノード
</span></span></span><span class="line"><span class="cl">    <span class="n">Node</span><span class="o">*</span> <span class="n">right</span><span class="p">;</span> <span class="c1">// 右子ノード
</span></span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ltag</span><span class="p">,</span> <span class="n">rtag</span><span class="p">;</span> <span class="c1">// 左右のスレッドマーク
</span></span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 前のノードを保存するためのグローバル変数preを定義
</span></span></span><span class="line"><span class="cl"><span class="n">Node</span><span class="o">*</span> <span class="n">pre</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// スレッドを作成する関数
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">createThread</span><span class="p">(</span><span class="n">Node</span><span class="o">*</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">p</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// ノードが空の場合、直接戻る
</span></span></span><span class="line"><span class="cl">        <span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">createThread</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">);</span> <span class="c1">// 左部分木を再帰的に処理
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 左子ノードが空の場合、左ポインタを前のノードに指向し、左スレッドマークを1に設定
</span></span></span><span class="line"><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">pre</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">p</span><span class="o">-&gt;</span><span class="n">ltag</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">pre</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">pre</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 前のノードの右子ノードが空の場合、その右ポインタを現在のノードに指向し、右スレッドマークを1に設定
</span></span></span><span class="line"><span class="cl">        <span class="n">pre</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">pre</span><span class="o">-&gt;</span><span class="n">rtag</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">pre</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span> <span class="c1">// 前のノードを更新
</span></span></span><span class="line"><span class="cl">    <span class="n">createThread</span><span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">);</span> <span class="c1">// 右部分木を再帰的に処理
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// スレッド二分木を中順走査する関数
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">inOrder</span><span class="p">(</span><span class="n">Node</span><span class="o">*</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">ltag</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 最も左のノードを見つける
</span></span></span><span class="line"><span class="cl">            <span class="n">p</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; &#34;</span><span class="p">;</span> <span class="c1">// ノードデータを出力
</span></span></span><span class="line"><span class="cl">        <span class="k">while</span> <span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">rtag</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 右ポインタがスレッドの場合、直接後続ノードにジャンプ
</span></span></span><span class="line"><span class="cl">            <span class="n">p</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">p</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">;</span> <span class="c1">// 右部分木を処理
</span></span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 二分木を作成
</span></span></span><span class="line"><span class="cl">    <span class="n">Node</span> <span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">,</span> <span class="n">n3</span><span class="p">,</span> <span class="n">n4</span><span class="p">,</span> <span class="n">n5</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">n1</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n2</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n2</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n4</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n3</span> <span class="o">=</span> <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n4</span> <span class="o">=</span> <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">n5</span> <span class="o">=</span> <span class="p">{</span><span class="mi">5</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 二分木をスレッド化
</span></span></span><span class="line"><span class="cl">    <span class="n">createThread</span><span class="p">(</span><span class="o">&amp;</span><span class="n">n1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// スレッド二分木を中順走査
</span></span></span><span class="line"><span class="cl">    <span class="n">inOrder</span><span class="p">(</span><span class="o">&amp;</span><span class="n">n1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="グラフの隣接行列と隣接リストの記憶">
<a class="header-anchor" href="#%e3%82%b0%e3%83%a9%e3%83%95%e3%81%ae%e9%9a%a3%e6%8e%a5%e8%a1%8c%e5%88%97%e3%81%a8%e9%9a%a3%e6%8e%a5%e3%83%aa%e3%82%b9%e3%83%88%e3%81%ae%e8%a8%98%e6%86%b6"></a>
グラフの隣接行列と隣接リストの記憶
</h2><h3 id="a-問題分析-1">
<a class="header-anchor" href="#a-%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90-1"></a>
a. 問題分析
</h3><p>私たちの目標は、C++でグラフの隣接行列と隣接リストの保存を実装することです。これには、配列（隣接行列用）とリンクリスト（隣接リスト用）という2つの異なるデータ構造が関わってきます。</p>
<h3 id="b-アルゴリズム設計-1">
<a class="header-anchor" href="#b-%e3%82%a2%e3%83%ab%e3%82%b4%e3%83%aa%e3%82%ba%e3%83%a0%e8%a8%ad%e8%a8%88-1"></a>
b. アルゴリズム設計
</h3><h4 id="隣接行列">
<a class="header-anchor" href="#%e9%9a%a3%e6%8e%a5%e8%a1%8c%e5%88%97"></a>
隣接行列
</h4><p>二次元配列<code>adj[MAX][MAX]</code>を使用してグラフの隣接行列を格納します。各要素<code>adj[i][j]</code>は、ノードiからノードjへの辺が存在するかどうかを示します。存在する場合、<code>adj[i][j] = 1</code>、そうでない場合は<code>adj[i][j] = 0</code>となります。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">max_edges</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">origin</span> <span class="o">&gt;&gt;</span> <span class="n">destin</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">((</span><span class="n">origin</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">destin</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">origin</span> <span class="o">&gt;=</span> <span class="n">n</span> <span class="o">||</span> <span class="n">destin</span> <span class="o">&gt;=</span> <span class="n">n</span> <span class="o">||</span> <span class="n">origin</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">destin</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">i</span><span class="o">--</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">adj</span><span class="p">[</span><span class="n">origin</span><span class="p">][</span><span class="n">destin</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="隣接リスト">
<a class="header-anchor" href="#%e9%9a%a3%e6%8e%a5%e3%83%aa%e3%82%b9%e3%83%88"></a>
隣接リスト
</h4><p>連結リストの配列<code>list&lt;int&gt; *adj</code>を使用してグラフの隣接リストを格納します。各要素<code>adj[i]</code>は、ノードiに隣接するすべてのノードを格納する連結リストです。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">Graph</span><span class="o">::</span><span class="n">addEdge</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">w</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">adj</span><span class="p">[</span><span class="n">v</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">w</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="c-データ構造設計-1">
<a class="header-anchor" href="#c-%e3%83%87%e3%83%bc%e3%82%bf%e6%a7%8b%e9%80%a0%e8%a8%ad%e8%a8%88-1"></a>
c. データ構造設計
</h3><h4 id="隣接行列-1">
<a class="header-anchor" href="#%e9%9a%a3%e6%8e%a5%e8%a1%8c%e5%88%97-1"></a>
隣接行列
</h4><p>二次元配列<code>int adj[MAX][MAX]</code>を使用して隣接行列を格納します。<code>MAX</code>はグラフ内のノードの最大数です。</p>
<h4 id="隣接リスト-1">
<a class="header-anchor" href="#%e9%9a%a3%e6%8e%a5%e3%83%aa%e3%82%b9%e3%83%88-1"></a>
隣接リスト
</h4><p>リンクリストの配列<code>list&lt;int&gt; *adj</code>を使用して隣接リストを格納します。<code>V</code>はグラフ内のノードの数です。</p>
<h3 id="d-デバッグプロセス-1">
<a class="header-anchor" href="#d-%e3%83%87%e3%83%90%e3%83%83%e3%82%b0%e3%83%97%e3%83%ad%e3%82%bb%e3%82%b9-1"></a>
d. デバッグプロセス
</h3><p>コードの実装とデバッグの過程で、まず入力された辺が有効であることを確認しました。入力された辺が無効な場合（例えば、存在しないノードを参照している場合）、ユーザーに通知し、再入力を促します。</p>
<p>隣接行列または隣接リストに辺を追加する際には、配列やリンクリストの範囲外インデックスにアクセスしようとしないように、エラーチェックを使用しました。</p>
<h3 id="e-出力結果-1">
<a class="header-anchor" href="#e-%e5%87%ba%e5%8a%9b%e7%b5%90%e6%9e%9c-1"></a>
e. 出力結果
</h3><p>最後に、隣接行列または隣接リストを出力して、コードが正しいかどうかを確認できます。隣接リストの場合、各ノードのリンクリストを走査し、すべての隣接ノードを出力します。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">Graph</span><span class="o">::</span><span class="n">printGraph</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">v</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="n">V</span><span class="p">;</span> <span class="n">v</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;</span><span class="se">\n</span><span class="s"> Adjacency list of vertex &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">v</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;</span><span class="se">\n</span><span class="s"> head &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">x</span> <span class="p">:</span> <span class="n">adj</span><span class="p">[</span><span class="n">v</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">            <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;-&gt; &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">printf</span><span class="p">(</span><span class="s">&#34;</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="f-ソースコード-1">
<a class="header-anchor" href="#f-%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89-1"></a>
f. ソースコード
</h3><h4 id="隣接行列による格納">
<a class="header-anchor" href="#%e9%9a%a3%e6%8e%a5%e8%a1%8c%e5%88%97%e3%81%ab%e3%82%88%e3%82%8b%e6%a0%bc%e7%b4%8d"></a>
隣接行列による格納
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include&lt;iostream&gt;
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MAX 20
</span></span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="n">adj</span><span class="p">[</span><span class="n">MAX</span><span class="p">][</span><span class="n">MAX</span><span class="p">];</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="n">n</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">create_graph</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">i</span><span class="p">,</span> <span class="n">max_edges</span><span class="p">,</span> <span class="n">origin</span><span class="p">,</span> <span class="n">destin</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Enter number of nodes : &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_edges</span> <span class="o">=</span> <span class="n">n</span> <span class="o">*</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">max_edges</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Enter edge &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; (-1 -1 to quit) : &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">origin</span> <span class="o">&gt;&gt;</span> <span class="n">destin</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">((</span><span class="n">origin</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">destin</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">origin</span> <span class="o">&gt;=</span> <span class="n">n</span> <span class="o">||</span> <span class="n">destin</span> <span class="o">&gt;=</span> <span class="n">n</span> <span class="o">||</span> <span class="n">origin</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">destin</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Invalid edge!</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">i</span><span class="o">--</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">adj</span><span class="p">[</span><span class="n">origin</span><span class="p">][</span><span class="n">destin</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="隣接リストによる格納">
<a class="header-anchor" href="#%e9%9a%a3%e6%8e%a5%e3%83%aa%e3%82%b9%e3%83%88%e3%81%ab%e3%82%88%e3%82%8b%e6%a0%bc%e7%b4%8d"></a>
隣接リストによる格納
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include&lt;iostream&gt;
</span></span></span><span class="line"><span class="cl"><span class="cp">#include&lt;list&gt;
</span></span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Graph</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">V</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">list</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">*</span><span class="n">adj</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">public</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">Graph</span><span class="p">(</span><span class="kt">int</span> <span class="n">V</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="nf">addEdge</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">w</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="nf">printGraph</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Graph</span><span class="o">::</span><span class="n">Graph</span><span class="p">(</span><span class="kt">int</span> <span class="n">V</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="o">-&gt;</span><span class="n">V</span> <span class="o">=</span> <span class="n">V</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">adj</span> <span class="o">=</span> <span class="k">new</span> <span class="n">list</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">[</span><span class="n">V</span><span class="p">];</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">Graph</span><span class="o">::</span><span class="n">addEdge</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">w</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">adj</span><span class="p">[</span><span class="n">v</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">w</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">Graph</span><span class="o">::</span><span class="n">printGraph</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">v</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="n">V</span><span class="p">;</span> <span class="n">v</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;</span><span class="se">\n</span><span class="s"> Adjacency list of vertex &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">v</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;</span><span class="se">\n</span><span class="s"> head &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">x</span> <span class="p">:</span> <span class="n">adj</span><span class="p">[</span><span class="n">v</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">            <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;-&gt; &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">printf</span><span class="p">(</span><span class="s">&#34;</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
        
        <hr><p>この記事は2023-12-12に<a href='https://www.guzhengsvt.cn/'>孤筝の温暖小家</a>で公開され、最終更新日は2023-12-12です</p><p>本ブログのすべての文書は、特に指定されていない限り、BY-NC-SAライセンスに従っています。引用の際は出典を明記してください！</p>]]></description><category>Code</category></item></channel></rss>