<?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/zh-tw/tags/%E8%B3%87%E6%96%99%E7%B5%90%E6%A7%8B/</link><description>Recent content from 孤筝の温暖小家</description><generator>Hugo</generator><language>zh-tw</language><managingEditor>lvbowen040427@163.com (孤筝)</managingEditor><webMaster>lvbowen040427@163.com (孤筝)</webMaster><copyright>本部落格所有文章除特別聲明外，均採用 BY-NC-SA 授權協議。轉載請註明出處！</copyright><lastBuildDate>Tue, 12 Dec 2023 15:00:26 +0800</lastBuildDate><atom:link href="https://www.guzhengsvt.cn/zh-tw/tags/%E8%B3%87%E6%96%99%E7%B5%90%E6%A7%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>資料結構實機實驗報告8——關鍵路徑</title><link>https://www.guzhengsvt.cn/zh-tw/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%8A8%E5%85%B3%E9%94%AE%E8%B7%AF%E5%BE%84/</link><pubDate>Tue, 12 Dec 2023 15:00:26 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/zh-tw/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%8A8%E5%85%B3%E9%94%AE%E8%B7%AF%E5%BE%84/</guid><description>
<![CDATA[<h1>資料結構實機實驗報告8——關鍵路徑</h1><p>作者：孤筝（lvbowen040427@163.com）</p>
        
          <h2 id="a-問題分析">
<a class="header-anchor" href="#a-%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
a. 問題分析
</h2><p>在關鍵路徑方法中，我們需要找到專案中的關鍵路徑，即影響專案總持續時間的關鍵活動序列。為了解決這個問題，我們首先構建了一個表示專案活動的資料結構 <code>Activity</code>，並設計了一個 <code>Project</code> 類來處理專案的計算和輸出。</p>
<p>關鍵路徑的計算主要依賴於兩個關鍵步驟：</p>
<ol>
<li>計算最早開始時間（ES）：從首事件開始，通過拓撲排序和動態規劃，計算每個活動的最早開始時間。</li>
<li>計算最晚開始時間（LS）：從末事件開始，通過反向遍歷拓撲排序和動態規劃，計算每個活動的最晚開始時間。</li>
</ol>
<p>通過比較最早開始時間和最晚開始時間，我們可以確定關鍵路徑上的活動，這些活動對專案總持續時間具有關鍵影響。</p>
<h2 id="b-演算法設計">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
b. 演算法設計
</h2><h3 id="1-計算最早開始時間">
<a class="header-anchor" href="#1-%e8%a8%88%e7%ae%97%e6%9c%80%e6%97%a9%e9%96%8b%e5%a7%8b%e6%99%82%e9%96%93"></a>
1. 計算最早開始時間
</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="c1">// 計算最早開始時間
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">calculateEarliestStart</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">q</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">const</span> <span class="n">Activity</span><span class="o">&amp;</span> <span class="nl">activity</span> <span class="p">:</span> <span class="n">activities</span><span class="p">)</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="n">activity</span><span class="p">.</span><span class="n">next</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span><span class="c1">//如果某節點鄰接表為空(即為首事件)
</span></span></span><span class="line"><span class="cl">            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">);</span><span class="c1">//入隊
</span></span></span><span class="line"><span class="cl">            <span class="n">earliestStart</span><span class="p">[</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span><span class="c1">//設置最早開始時間為0
</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="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</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">currentId</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span><span class="c1">//取出最優先事件currentId
</span></span></span><span class="line"><span class="cl">        <span class="n">q</span><span class="p">.</span><span class="n">pop</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="kt">int</span> <span class="nl">nextId</span> <span class="p">:</span> <span class="n">activities</span><span class="p">[</span><span class="n">currentId</span><span class="p">].</span><span class="n">next</span><span class="p">)</span> <span class="p">{</span><span class="c1">//遍歷currentId的鄰接表
</span></span></span><span class="line"><span class="cl">            <span class="n">earliestStart</span><span class="p">[</span><span class="n">nextId</span><span class="p">]</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">earliestStart</span><span class="p">[</span><span class="n">nextId</span><span class="p">],</span> <span class="n">earliestStart</span><span class="p">[</span><span class="n">currentId</span><span class="p">]</span> <span class="o">+</span> <span class="n">activities</span><span class="p">[</span><span class="n">currentId</span><span class="p">].</span><span class="n">duration</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// nextId的最早開始時間==max{當前記錄最早開始時間,前置節點currentId最早開始時間+currentId事件時間}
</span></span></span><span class="line"><span class="cl">            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">nextId</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><h3 id="2-計算最晚開始時間">
<a class="header-anchor" href="#2-%e8%a8%88%e7%ae%97%e6%9c%80%e6%99%9a%e9%96%8b%e5%a7%8b%e6%99%82%e9%96%93"></a>
2. 計算最晚開始時間
</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="c1">// 計算最晚開始時間
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">calculateLatestStart</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">latestStart</span> <span class="o">=</span> <span class="n">earliestStart</span><span class="p">;</span><span class="c1">//初始化最晚開始時間為最早開始時間
</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="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">activities</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="o">--</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span><span class="c1">//從最後的事件i開始反向遍歷
</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="nl">nextId</span> <span class="p">:</span> <span class="n">activities</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">next</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">latestStart</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">latestStart</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">latestStart</span><span class="p">[</span><span class="n">nextId</span><span class="p">]</span> <span class="o">-</span> <span class="n">activities</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">duration</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// 當前事件最晚開始時間==min{已記錄最晚開始時間,下一事件nextId最晚開始時間-當前事件i所需時間}
</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><h2 id="c-資料結構設計">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
c. 資料結構設計
</h2><p>我們使用了兩個關鍵的資料結構：</p>
<ol>
<li><code>Activity</code> 結構體：用於表示專案中的活動，包括活動編號、持續時間和後續活動的資訊。</li>
</ol>
<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">Activity</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">id</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">duration</span><span class="p">;</span> <span class="c1">// 持續時間
</span></span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">next</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><ol start="2">
<li><code>Project</code> 類：用於管理專案，包括添加活動、計算最早開始時間、計算最晚開始時間、列印關鍵路徑和時間資訊等方法。</li>
</ol>
<h2 id="d-調試過程">
<a class="header-anchor" href="#d-%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b"></a>
d. 調試過程
</h2><p>在調試過程中，我們主要關注以下方面：</p>
<ol>
<li>資料結構的正確性：確保 <code>Activity</code> 結構體和 <code>Project</code> 類正確地表示了專案和活動的關係。</li>
<li>演算法的正確性：驗證計算最早開始時間和最晚開始時間的演算法是否正確。</li>
<li>輸出結果的準確性：檢查列印的關鍵路徑和時間資訊是否符合預期。</li>
</ol>
<h2 id="e-輸出結果">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
e. 輸出結果
</h2><p>運行程式後，我們得到以下輸出結果：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">Critical Path</span><span class="p">:</span><span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="m">2</span><span class="w"> </span><span class="m">3</span><span class="w"> </span><span class="m">4</span><span class="w"> </span><span class="m">5</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="nt">Activity 0</span><span class="p">:</span><span class="w"> </span><span class="l">ES=0, LS=0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">Activity 1</span><span class="p">:</span><span class="w"> </span><span class="l">ES=2, LS=2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">Activity 2</span><span class="p">:</span><span class="w"> </span><span class="l">ES=6, LS=6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">Activity 3</span><span class="p">:</span><span class="w"> </span><span class="l">ES=9, LS=9</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">Activity 4</span><span class="p">:</span><span class="w"> </span><span class="l">ES=14, LS=14</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">Activity 5</span><span class="p">:</span><span class="w"> </span><span class="l">ES=16, LS=16</span><span class="w">
</span></span></span></code></pre></div><p>從結果中可以看到，關鍵路徑上的活動是 0、1、2、3、4、5，並且每個活動的最早開始時間和最晚開始時間都正確計算。這表明我們的演算法和資料結構設計是有效的。</p>
<h2 id="f-原始碼">
<a class="header-anchor" href="#f-%e5%8e%9f%e5%a7%8b%e7%a2%bc"></a>
f. 原始碼
</h2><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</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;queue&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl">
</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">Activity</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">id</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">duration</span><span class="p">;</span> <span class="c1">// 持續時間
</span></span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">next</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="k">class</span> <span class="nc">Project</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="k">private</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="n">Activity</span><span class="o">&gt;</span> <span class="n">activities</span><span class="p">;</span> <span class="c1">// 儲存專案活動的向量
</span></span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">earliestStart</span><span class="p">;</span>   <span class="c1">// 最早開始時間
</span></span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">latestStart</span><span class="p">;</span>     <span class="c1">// 最晚開始時間
</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="c1">// 添加活動
</span></span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="n">addActivity</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">duration</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">next</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">activities</span><span class="p">.</span><span class="n">push_back</span><span class="p">({</span><span class="n">id</span><span class="p">,</span> <span class="n">duration</span><span class="p">,</span> <span class="n">next</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="c1">// 計算最早開始時間
</span></span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="nf">calculateEarliestStart</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">q</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">const</span> <span class="n">Activity</span><span class="o">&amp;</span> <span class="nl">activity</span> <span class="p">:</span> <span class="n">activities</span><span class="p">)</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="n">activity</span><span class="p">.</span><span class="n">next</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span><span class="c1">//如果某節點鄰接表為空(即為首事件)
</span></span></span><span class="line"><span class="cl">                <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">);</span><span class="c1">//入隊
</span></span></span><span class="line"><span class="cl">                <span class="n">earliestStart</span><span class="p">[</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span><span class="c1">//設置最早開始時間為0
</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="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</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">currentId</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span><span class="c1">//取出最優先事件currentId
</span></span></span><span class="line"><span class="cl">            <span class="n">q</span><span class="p">.</span><span class="n">pop</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="kt">int</span> <span class="nl">nextId</span> <span class="p">:</span> <span class="n">activities</span><span class="p">[</span><span class="n">currentId</span><span class="p">].</span><span class="n">next</span><span class="p">)</span> <span class="p">{</span><span class="c1">//遍歷currentId的鄰接表
</span></span></span><span class="line"><span class="cl">                <span class="n">earliestStart</span><span class="p">[</span><span class="n">nextId</span><span class="p">]</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">earliestStart</span><span class="p">[</span><span class="n">nextId</span><span class="p">],</span> <span class="n">earliestStart</span><span class="p">[</span><span class="n">currentId</span><span class="p">]</span> <span class="o">+</span> <span class="n">activities</span><span class="p">[</span><span class="n">currentId</span><span class="p">].</span><span class="n">duration</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="c1">// nextId的最早開始時間==max{當前記錄最早開始時間,前置節點currentId最早開始時間+currentId事件時間}
</span></span></span><span class="line"><span class="cl">                <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">nextId</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><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">calculateLatestStart</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">latestStart</span> <span class="o">=</span> <span class="n">earliestStart</span><span class="p">;</span><span class="c1">//初始化最晚開始時間為最早開始時間
</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="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">activities</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="o">--</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span><span class="c1">//從最後的事件i開始反向遍歷
</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="nl">nextId</span> <span class="p">:</span> <span class="n">activities</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">next</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">latestStart</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">latestStart</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">latestStart</span><span class="p">[</span><span class="n">nextId</span><span class="p">]</span> <span class="o">-</span> <span class="n">activities</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">duration</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="c1">// 當前事件最晚開始時間==min{已記錄最晚開始時間,下一事件nextId最晚開始時間-當前事件i所需時間}
</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><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">printCriticalPath</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;Critical Path: &#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">const</span> <span class="n">Activity</span><span class="o">&amp;</span> <span class="nl">activity</span> <span class="p">:</span> <span class="n">activities</span><span class="p">)</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="n">earliestStart</span><span class="p">[</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">]</span> <span class="o">==</span> <span class="n">latestStart</span><span class="p">[</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">])</span> <span class="p">{</span><span class="c1">//關鍵路徑上事件最早開始時間==最晚開始時間
</span></span></span><span class="line"><span class="cl">                <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">activity</span><span class="p">.</span><span class="n">id</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="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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="c1">// 列印最早開始時間和最晚開始時間
</span></span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="nf">printTimeInfo</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="k">const</span> <span class="n">Activity</span><span class="o">&amp;</span> <span class="nl">activity</span> <span class="p">:</span> <span class="n">activities</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;Activity &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">activity</span><span class="p">.</span><span class="n">id</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;: ES=&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">earliestStart</span><span class="p">[</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">                 <span class="o">&lt;&lt;</span> <span class="s">&#34;, LS=&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">latestStart</span><span class="p">[</span><span class="n">activity</span><span class="p">.</span><span class="n">id</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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></span><span class="line"><span class="cl">    <span class="c1">// 構造初始化函數
</span></span></span><span class="line"><span class="cl">    <span class="n">Project</span><span class="p">(</span><span class="kt">int</span> <span class="n">numActivities</span><span class="p">)</span> <span class="o">:</span> <span class="n">earliestStart</span><span class="p">(</span><span class="n">numActivities</span><span class="p">),</span> <span class="n">latestStart</span><span class="p">(</span><span class="n">numActivities</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">
</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="n">Project</span> <span class="n">project</span><span class="p">(</span><span class="mi">6</span><span class="p">);</span> <span class="c1">// 假設有6個活動
</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="n">project</span><span class="p">.</span><span class="n">addActivity</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="p">{</span><span class="mi">1</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="n">project</span><span class="p">.</span><span class="n">addActivity</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="p">{</span><span class="mi">2</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="n">project</span><span class="p">.</span><span class="n">addActivity</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="p">{</span><span class="mi">3</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="n">project</span><span class="p">.</span><span class="n">addActivity</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="p">{</span><span class="mi">4</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="n">project</span><span class="p">.</span><span class="n">addActivity</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="p">{</span><span class="mi">5</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="n">project</span><span class="p">.</span><span class="n">addActivity</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</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="n">project</span><span class="p">.</span><span class="n">calculateEarliestStart</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">project</span><span class="p">.</span><span class="n">calculateLatestStart</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="n">project</span><span class="p">.</span><span class="n">printCriticalPath</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">project</span><span class="p">.</span><span class="n">printTimeInfo</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</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>
        
        <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><item><title>資料結構實機實驗報告7——Kruskal演算法與最小生成樹問題，Dijkstra演算法與帶權圖最短路徑問題</title><link>https://www.guzhengsvt.cn/zh-tw/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%8A7kruskal%E7%AE%97%E6%B3%95%E4%B8%8E%E6%9C%80%E5%B0%8F%E7%94%9F%E6%88%90%E6%A0%91%E9%97%AE%E9%A2%98dijkstra%E7%AE%97%E6%B3%95%E4%B8%8E%E5%B8%A6%E6%9D%83%E5%9B%BE%E6%9C%80%E7%9F%AD%E8%B7%AF%E5%BE%84%E9%97%AE%E9%A2%98/</link><pubDate>Tue, 12 Dec 2023 14:58:44 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/zh-tw/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%8A7kruskal%E7%AE%97%E6%B3%95%E4%B8%8E%E6%9C%80%E5%B0%8F%E7%94%9F%E6%88%90%E6%A0%91%E9%97%AE%E9%A2%98dijkstra%E7%AE%97%E6%B3%95%E4%B8%8E%E5%B8%A6%E6%9D%83%E5%9B%BE%E6%9C%80%E7%9F%AD%E8%B7%AF%E5%BE%84%E9%97%AE%E9%A2%98/</guid><description>
<![CDATA[<h1>資料結構實機實驗報告7——Kruskal演算法與最小生成樹問題，Dijkstra演算法與帶權圖最短路徑問題</h1><p>作者：孤筝（lvbowen040427@163.com）</p>
        
          <h2 id="kruskal演算法生成最小生成樹">
<a class="header-anchor" href="#kruskal%e6%bc%94%e7%ae%97%e6%b3%95%e7%94%9f%e6%88%90%e6%9c%80%e5%b0%8f%e7%94%9f%e6%88%90%e6%a8%b9"></a>
Kruskal演算法生成最小生成樹
</h2><h3 id="問題分析">
<a class="header-anchor" href="#%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
問題分析
</h3><p>我們需要使用 Kruskal 演算法找到一個包含10個節點和20條邊的圖的最小生成樹。Kruskal演算法基於貪心思想，通過不斷選擇權重最小的邊，並確保添加這條邊不形成環路，來構建最小生成樹。</p>
<h3 id="b-演算法設計">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
b 演算法設計
</h3><h4 id="kruskal-演算法的關鍵步驟">
<a class="header-anchor" href="#kruskal-%e6%bc%94%e7%ae%97%e6%b3%95%e7%9a%84%e9%97%9c%e9%8d%b5%e6%ad%a5%e9%a9%9f"></a>
Kruskal 演算法的關鍵步驟：
</h4><h5 id="邊的排序">
<a class="header-anchor" href="#%e9%82%8a%e7%9a%84%e6%8e%92%e5%ba%8f"></a>
<strong>邊的排序：</strong>
</h5><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="n">sort</span><span class="p">(</span><span class="n">edges</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">edges</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="p">[](</span><span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">weight</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">weight</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p><code>sort</code> 函數通過指定排序的範圍和比較規則，對容器中的元素進行排序。在這裡，它被用於按照邊的權重升序排序，以便在Kruskal演算法中逐步選擇最小權重的邊。
1. <code>edges.begin()</code> 和 <code>edges.end()</code>: 這兩個參數指定了排序的範圍，即待排序元素的起始和終止位置。在這裡，<code>edges</code> 是一個存儲邊的集合的容器，<code>begin()</code> 返回容器的起始迭代器，<code>end()</code> 返回容器的終止迭代器。
2. <code>[](const Edge&amp; a, const Edge&amp; b) { return a.weight &lt; b.weight; }</code>: 這是一個 lambda 表達式，它定義了排序的比較規則。lambda 表達式是一個匿名函數，用於在排序過程中比較兩個元素的大小。在這裡，比較規則是按照邊的權重 (<code>weight</code>) 升序排列。
3. <code>const Edge&amp; a</code> 和 <code>const Edge&amp; b</code> 是 lambda 表達式的參數，表示兩個待比較的邊。
4. <code>return a.weight &lt; b.weight;</code> 表示如果邊 <code>a</code> 的權重小於邊 <code>b</code> 的權重，則返回 <code>true</code>，否則返回 <code>false</code>。這樣，<code>sort</code> 函數會按照升序的方式對邊進行排序。</p>
<h5 id="並查集初始化">
<a class="header-anchor" href="#%e4%b8%a6%e6%9f%a5%e9%9b%86%e5%88%9d%e5%a7%8b%e5%8c%96"></a>
<strong>並查集初始化：</strong>
</h5><p>初始化並查集，每個節點單獨成為一個集合。</p>
<ul>
<li>並查集（Disjoint Set Union，簡稱並查集）是一種用於處理集合的數據結構，主要支援兩種操作：查找（Find）和合併（Union）。這種數據結構用於解決一些與集合劃分相關的問題，特別是在圖論和網絡連接等領域。</li>
<li><strong>基本操作:</strong>
<ol>
<li><strong>查找 (Find):</strong> 查找元素所屬的集合，通常通過找到根節點來確定一個元素所在的集合。這個過程可以幫助判斷兩個元素是否屬於同一集合。</li>
<li><strong>合併 (Union):</strong> 將兩個集合合併為一個新的集合。這個操作通常會將兩個集合的根節點連接在一起，以確保它們成為同一個集合。</li>
</ol>
</li>
<li><strong>實現細節:</strong>
<ul>
<li>通常，可以使用數組來實現並查集。數組的每個元素代表一個集合中的一個元素，數組中的值表示該元素的父節點（或根節點）。初始時，每個元素都是其自己的根節點。</li>
</ul>
</li>
<li>為了優化並查集的性能，通常會使用路徑壓縮和按秩合併這兩種技術：
<ul>
<li><strong>路徑壓縮 (Path Compression):</strong> 在進行查找操作時，將查找路徑上的所有節點的父節點都直接設為根節點，從而降低樹的高度，提高後續查找的效率。</li>
<li><strong>按秩合併 (Union by Rank):</strong> 在進行合併操作時，將較矮的樹合併到較高的樹上，從而避免樹的過度增長，提高效率。&ldquo;秩&quot;通常指樹的高度或者節點的深度。</li>
</ul>
</li>
</ul>
<h5 id="邊的遍歷">
<a class="header-anchor" href="#%e9%82%8a%e7%9a%84%e9%81%8d%e6%ad%b7"></a>
<strong>邊的遍歷：</strong>
</h5><p>遍歷排序後的邊，逐步選擇邊並加入最小生成樹，確保不形成環路。</p>
<h4 id="具體實現">
<a class="header-anchor" href="#%e5%85%b7%e9%ab%94%e5%af%a6%e7%8f%be"></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="c1">// Kruskal演算法
</span></span></span><span class="line"><span class="cl"><span class="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;</span> <span class="n">kruskal</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;&amp;</span> <span class="n">edges</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numNodes</span><span class="p">)</span> <span class="p">{</span><span class="c1">//傳入邊集、節點數
</span></span></span><span class="line"><span class="cl">    <span class="c1">// 將邊按權重升序排序
</span></span></span><span class="line"><span class="cl">    <span class="n">sort</span><span class="p">(</span><span class="n">edges</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">edges</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="p">[](</span><span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> 
</span></span><span class="line"><span class="cl"><span class="c1">//傳入開始比較邊、終止比較邊、lambda表達式（兩比較元素）
</span></span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">weight</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">weight</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="n">UnionFind</span> <span class="nf">uf</span><span class="p">(</span><span class="n">numNodes</span><span class="p">);</span><span class="c1">//UnionFind(size)
</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="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;</span> <span class="n">result</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">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="nl">edge</span> <span class="p">:</span> <span class="n">edges</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="k">if</span> <span class="p">(</span><span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">edge</span><span class="p">.</span><span class="n">start</span><span class="p">)</span> <span class="o">!=</span> <span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">edge</span><span class="p">.</span><span class="n">end</span><span class="p">))</span> <span class="p">{</span><span class="c1">//這條邊開始節點與終止節點不在同一集合（子樹）
</span></span></span><span class="line"><span class="cl">            <span class="c1">// 不會形成環路，加入最小生成樹
</span></span></span><span class="line"><span class="cl">            <span class="n">result</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">edge</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">uf</span><span class="p">.</span><span class="n">unite</span><span class="p">(</span><span class="n">edge</span><span class="p">.</span><span class="n">start</span><span class="p">,</span> <span class="n">edge</span><span class="p">.</span><span class="n">end</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="k">return</span> <span class="n">result</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-資料結構設計">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
c 資料結構設計
</h3><h4 id="1-edge-結構體">
<a class="header-anchor" href="#1-edge-%e7%b5%90%e6%a7%8b%e9%ab%94"></a>
1. <strong>Edge 結構體：</strong>
</h4><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">Edge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="n">weight</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><ul>
<li><code>Edge</code> 結構體表示圖中的一條邊，包含起點、終點和權重。</li>
</ul>
<h4 id="2-unionfind-類">
<a class="header-anchor" href="#2-unionfind-%e9%a1%9e"></a>
2. <strong>UnionFind 類：</strong>
</h4><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">class</span> <span class="nc">UnionFind</span> <span class="p">{</span>
</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">UnionFind</span><span class="p">(</span><span class="kt">int</span> <span class="n">size</span><span class="p">)</span> <span class="o">:</span> <span class="n">parent</span><span class="p">(</span><span class="n">size</span><span class="p">),</span> <span class="n">rank</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="c1">//parent儲存各節點的根節點，初始為自身；rank記錄各節點作為根節點時樹的深度，初始為0
</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">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">parent</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</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">find</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">)</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="n">x</span> <span class="o">!=</span> <span class="n">parent</span><span class="p">[</span><span class="n">x</span><span class="p">])</span> <span class="p">{</span><span class="c1">//x的根節點不為自身（存在雙親節點）
</span></span></span><span class="line"><span class="cl">            <span class="n">parent</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">parent</span><span class="p">[</span><span class="n">x</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="k">return</span> <span class="n">parent</span><span class="p">[</span><span class="n">x</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="kt">void</span> <span class="nf">unite</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</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">rootX</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="c1">//x節點的根節點
</span></span></span><span class="line"><span class="cl">        <span class="kt">int</span> <span class="n">rootY</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">y</span><span class="p">);</span><span class="c1">//y節點的根節點
</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">rootX</span> <span class="o">!=</span> <span class="n">rootY</span><span class="p">)</span> <span class="p">{</span><span class="c1">//x、y不在同一集合（子樹）
</span></span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">rank</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">rank</span><span class="p">[</span><span class="n">rootY</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="c1">//x所在子樹深度小於y所在子樹深度
</span></span></span><span class="line"><span class="cl">                <span class="n">parent</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">=</span> <span class="n">rootY</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="c1">//將x子樹併入y子樹以保證合併後深度不增大
</span></span></span><span class="line"><span class="cl">            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rank</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">rank</span><span class="p">[</span><span class="n">rootY</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">parent</span><span class="p">[</span><span class="n">rootY</span><span class="p">]</span> <span class="o">=</span> <span class="n">rootX</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 class="c1">//x、y所在子樹深度相同
</span></span></span><span class="line"><span class="cl">                <span class="n">parent</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">=</span> <span class="n">rootY</span><span class="p">;</span><span class="c1">//x子樹併入y子樹
</span></span></span><span class="line"><span class="cl">                <span class="n">rank</span><span class="p">[</span><span class="n">rootY</span><span class="p">]</span><span class="o">++</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 class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">private</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">parent</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">rank</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><ul>
<li><code>UnionFind</code> 類實現了並查集，用於查找節點所在的集合和合併兩個集合。<code>find</code> 函數用於查找根節點，<code>unite</code> 函數用於合併兩個集合。</li>
<li>在建構函數中，<code>rank</code> 陣列的初始值都被設置為0。在這裡，<code>rank</code> 陣列的值不是表示節點的深度，而是近似表示樹的高度。每個節點初始化時都被認為是一棵只包含自己的樹，所以初始高度是0。</li>
<li>在 <code>rank</code> 陣列中，每個元素的值表示樹的近似高度。在進行合併操作時，通過比較兩棵樹的高度，選擇將較矮的樹連接到較高的樹上，以保持樹的平衡。這有助於避免樹的高度過度增長，維護了並查集的高效性。</li>
</ul>
<h3 id="d-調試過程">
<a class="header-anchor" href="#d-%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b"></a>
d 調試過程
</h3><p>在調試過程中，我們可以逐步運行代碼，觀察每個步驟的輸出，特別是排序後的邊、最小生成樹的構建過程，以及並查集的狀態。通過輸出中間結果，可以驗證算法是否按預期工作。</p>
<h3 id="e-輸出結果">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
e 輸出結果
</h3><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="nl">Graph</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"><span class="mi">0</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">:</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="mi">0</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">:</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="mi">1</span> <span class="o">-</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">1</span> <span class="o">-</span> <span class="mi">4</span> <span class="o">:</span> <span class="mi">8</span>
</span></span><span class="line"><span class="cl"><span class="mi">2</span> <span class="o">-</span> <span class="mi">5</span> <span class="o">:</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="mi">2</span> <span class="o">-</span> <span class="mi">6</span> <span class="o">:</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl"><span class="mi">3</span> <span class="o">-</span> <span class="mi">7</span> <span class="o">:</span> <span class="mi">5</span>
</span></span><span class="line"><span class="cl"><span class="mi">3</span> <span class="o">-</span> <span class="mi">8</span> <span class="o">:</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="mi">4</span> <span class="o">-</span> <span class="mi">9</span> <span class="o">:</span> <span class="mi">6</span>
</span></span><span class="line"><span class="cl"><span class="mi">5</span> <span class="o">-</span> <span class="mi">6</span> <span class="o">:</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">6</span> <span class="o">-</span> <span class="mi">8</span> <span class="o">:</span> <span class="mi">6</span>
</span></span><span class="line"><span class="cl"><span class="mi">7</span> <span class="o">-</span> <span class="mi">9</span> <span class="o">:</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="mi">8</span> <span class="o">-</span> <span class="mi">9</span> <span class="o">:</span> <span class="mi">9</span>
</span></span><span class="line"><span class="cl"><span class="mi">1</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">:</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">3</span> <span class="o">-</span> <span class="mi">4</span> <span class="o">:</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="mi">5</span> <span class="o">-</span> <span class="mi">7</span> <span class="o">:</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="mi">6</span> <span class="o">-</span> <span class="mi">9</span> <span class="o">:</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl"><span class="mi">0</span> <span class="o">-</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">6</span>
</span></span><span class="line"><span class="cl"><span class="mi">2</span> <span class="o">-</span> <span class="mi">8</span> <span class="o">:</span> <span class="mi">5</span>
</span></span><span class="line"><span class="cl"><span class="mi">4</span> <span class="o">-</span> <span class="mi">5</span> <span class="o">:</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="n">Edges</span> <span class="n">in</span> <span class="n">the</span> <span class="n">minimum</span> <span class="n">spanning</span> <span class="nl">tree</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"><span class="mi">0</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">:</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="mi">3</span> <span class="o">-</span> <span class="mi">8</span> <span class="o">:</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="mi">1</span> <span class="o">-</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">1</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">:</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">5</span> <span class="o">-</span> <span class="mi">6</span> <span class="o">:</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">2</span> <span class="o">-</span> <span class="mi">5</span> <span class="o">:</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="mi">3</span> <span class="o">-</span> <span class="mi">4</span> <span class="o">:</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="mi">7</span> <span class="o">-</span> <span class="mi">9</span> <span class="o">:</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="mi">5</span> <span class="o">-</span> <span class="mi">7</span> <span class="o">:</span> <span class="mi">4</span>
</span></span></code></pre></div><h3 id="f-原始碼">
<a class="header-anchor" href="#f-%e5%8e%9f%e5%a7%8b%e7%a2%bc"></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</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="c1">//調用sort函數
</span></span></span><span class="line"><span class="cl">
</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">Edge</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="n">weight</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="k">class</span> <span class="nc">UnionFind</span> <span class="p">{</span>
</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">UnionFind</span><span class="p">(</span><span class="kt">int</span> <span class="n">size</span><span class="p">)</span> <span class="o">:</span> <span class="n">parent</span><span class="p">(</span><span class="n">size</span><span class="p">),</span> <span class="n">rank</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="c1">//parent儲存各節點的根節點，初始為自身；rank記錄各節點作為根節點時樹的深度，初始為0
</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">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">parent</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</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">find</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">)</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="n">x</span> <span class="o">!=</span> <span class="n">parent</span><span class="p">[</span><span class="n">x</span><span class="p">])</span> <span class="p">{</span><span class="c1">//x的根節點不為自身（存在雙親節點）
</span></span></span><span class="line"><span class="cl">            <span class="n">parent</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">parent</span><span class="p">[</span><span class="n">x</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="k">return</span> <span class="n">parent</span><span class="p">[</span><span class="n">x</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="kt">void</span> <span class="nf">unite</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</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">rootX</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="c1">//x節點的根節點
</span></span></span><span class="line"><span class="cl">        <span class="kt">int</span> <span class="n">rootY</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">y</span><span class="p">);</span><span class="c1">//y節點的根節點
</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">rootX</span> <span class="o">!=</span> <span class="n">rootY</span><span class="p">)</span> <span class="p">{</span><span class="c1">//x、y不在同一集合（子樹）
</span></span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">rank</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">rank</span><span class="p">[</span><span class="n">rootY</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="c1">//x所在子樹深度小於y所在子樹深度
</span></span></span><span class="line"><span class="cl">                <span class="n">parent</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">=</span> <span class="n">rootY</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="c1">//將x子樹併入y子樹以保證合併後深度不增大
</span></span></span><span class="line"><span class="cl">            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rank</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">rank</span><span class="p">[</span><span class="n">rootY</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">parent</span><span class="p">[</span><span class="n">rootY</span><span class="p">]</span> <span class="o">=</span> <span class="n">rootX</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 class="c1">//x、y所在子樹深度相同
</span></span></span><span class="line"><span class="cl">                <span class="n">parent</span><span class="p">[</span><span class="n">rootX</span><span class="p">]</span> <span class="o">=</span> <span class="n">rootY</span><span class="p">;</span><span class="c1">//x子樹併入y子樹
</span></span></span><span class="line"><span class="cl">                <span class="n">rank</span><span class="p">[</span><span class="n">rootY</span><span class="p">]</span><span class="o">++</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 class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">private</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">parent</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">rank</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="c1">// Kruskal算法
</span></span></span><span class="line"><span class="cl"><span class="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;</span> <span class="n">kruskal</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;&amp;</span> <span class="n">edges</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numNodes</span><span class="p">)</span> <span class="p">{</span><span class="c1">//傳入邊集、節點數
</span></span></span><span class="line"><span class="cl">    <span class="c1">// 將邊按權重升序排序
</span></span></span><span class="line"><span class="cl">    <span class="n">sort</span><span class="p">(</span><span class="n">edges</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">edges</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="p">[](</span><span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> 
</span></span><span class="line"><span class="cl"><span class="c1">//傳入開始比較邊、終止比較邊、lambda表達式（兩比較元素）
</span></span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">weight</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">.</span><span class="n">weight</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="n">UnionFind</span> <span class="nf">uf</span><span class="p">(</span><span class="n">numNodes</span><span class="p">);</span><span class="c1">//UnionFind(size)
</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="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;</span> <span class="n">result</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">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="nl">edge</span> <span class="p">:</span> <span class="n">edges</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="k">if</span> <span class="p">(</span><span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">edge</span><span class="p">.</span><span class="n">start</span><span class="p">)</span> <span class="o">!=</span> <span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">edge</span><span class="p">.</span><span class="n">end</span><span class="p">))</span> <span class="p">{</span><span class="c1">//這條邊開始節點與終止節點不在同一集合（子樹）
</span></span></span><span class="line"><span class="cl">            <span class="c1">// 不會形成環路，加入最小生成樹
</span></span></span><span class="line"><span class="cl">            <span class="n">result</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">edge</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">uf</span><span class="p">.</span><span class="n">unite</span><span class="p">(</span><span class="n">edge</span><span class="p">.</span><span class="n">start</span><span class="p">,</span> <span class="n">edge</span><span class="p">.</span><span class="n">end</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="k">return</span> <span class="n">result</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">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">// 創建一個10節點的圖
</span></span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">numNodes</span> <span class="o">=</span> <span class="mi">10</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="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;</span> <span class="n">edges</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">8</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">1</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">6</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">6</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">6</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">9</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">4</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">6</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">6</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">5</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</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="c1">//輸出該圖
</span></span></span><span class="line"><span class="cl">    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Graph:&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="nl">edge</span> <span class="p">:</span> <span class="n">edges</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="n">edge</span><span class="p">.</span><span class="n">start</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; - &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">edge</span><span class="p">.</span><span class="n">end</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; : &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">edge</span><span class="p">.</span><span class="n">weight</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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="c1">// 運行Kruskal算法
</span></span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="n">Edge</span><span class="o">&gt;</span> <span class="n">minSpanningTree</span> <span class="o">=</span> <span class="n">kruskal</span><span class="p">(</span><span class="n">edges</span><span class="p">,</span> <span class="n">numNodes</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="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Edges in the minimum spanning tree:&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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">const</span> <span class="n">Edge</span><span class="o">&amp;</span> <span class="nl">edge</span> <span class="p">:</span> <span class="n">minSpanningTree</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="n">edge</span><span class="p">.</span><span class="n">start</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; - &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">edge</span><span class="p">.</span><span class="n">end</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; : &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">edge</span><span class="p">.</span><span class="n">weight</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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="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="dijkstra演算法解決帶權圖最短路徑問題">
<a class="header-anchor" href="#dijkstra%e6%bc%94%e7%ae%97%e6%b3%95%e8%a7%a3%e6%b1%ba%e5%b8%b6%e6%ac%8a%e5%9c%96%e6%9c%80%e7%9f%ad%e8%b7%af%e5%be%91%e5%95%8f%e9%a1%8c"></a>
Dijkstra演算法解決帶權圖最短路徑問題
</h2><h3 id="問題分析-1">
<a class="header-anchor" href="#%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90-1"></a>
問題分析
</h3><p>代碼實現了 Dijkstra 演算法，用於解決帶權圖中的單源最短路徑問題。通過給定的鄰接矩陣表示圖，從指定的起始節點出發，計算該起始節點到圖中所有其他節點的最短距離。</p>
<h3 id="b-演算法設計-1">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88-1"></a>
b 演算法設計
</h3><h4 id="1-初始化">
<a class="header-anchor" href="#1-%e5%88%9d%e5%a7%8b%e5%8c%96"></a>
1. 初始化
</h4><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="n">n</span> <span class="o">=</span> <span class="n">graph</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="n">distances</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">INF</span><span class="p">);</span>
</span></span></code></pre></div><ul>
<li><strong>分析：</strong> 取得圖的節點數 <code>n</code>，然後初始化距離陣列 <code>distances</code>，將所有節點的距離初始值設為無窮大（<code>INF</code>）。</li>
</ul>
<h4 id="2-建構優先佇列">
<a class="header-anchor" href="#2-%e5%bb%ba%e6%a7%8b%e5%84%aa%e5%85%88%e4%bd%87%e5%88%97"></a>
2. 建構優先佇列
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span><span class="p">,</span> <span class="n">greater</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;&gt;</span> <span class="n">pq</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">distances</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="mi">0</span><span class="p">,</span> <span class="n">start</span><span class="p">});</span>
</span></span></code></pre></div><ul>
<li><strong>分析：</strong> 建立一個優先佇列 <code>pq</code>，元素為節點和其距離的 <code>pair</code> 對。將起始節點的距離設定為0，並將該節點放入優先佇列。</li>
</ul>
<h4 id="3-循環迭代">
<a class="header-anchor" href="#3-%e5%be%aa%e7%92%b0%e8%bf%ad%e4%bb%a3"></a>
3. 循環迭代
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">pq</span><span class="p">.</span><span class="n">empty</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">u</span> <span class="o">=</span> <span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">().</span><span class="n">second</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pq</span><span class="p">.</span><span class="n">pop</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="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">n</span><span class="p">;</span> <span class="o">++</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">if</span> <span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">u</span><span class="p">][</span><span class="n">v</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">distances</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">distances</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">+</span> <span class="n">graph</span><span class="p">[</span><span class="n">u</span><span class="p">][</span><span class="n">v</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">distances</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">distances</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">+</span> <span class="n">graph</span><span class="p">[</span><span class="n">u</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">pq</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">distances</span><span class="p">[</span><span class="n">v</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 class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><ul>
<li><strong>分析：</strong> 不斷從優先佇列中取出當前距離起點最小的節點 <code>u</code>，然後遍歷節點 <code>u</code> 的鄰居。如果透過節點 <code>u</code> 到達鄰居節點 <code>v</code> 的距離比已知的距離短，更新距離值並將新距離和節點 <code>v</code> 加入佇列。</li>
</ul>
<h4 id="4-重複">
<a class="header-anchor" href="#4-%e9%87%8d%e8%a4%87"></a>
4. 重複
</h4><ul>
<li><strong>分析：</strong> 重複步驟3，直到優先佇列為空。在每一步中，佇列中的節點都是當前距離起點最小的，確保了每次都選擇了當前已知最短路徑的節點進行擴展。</li>
</ul>
<h3 id="c-資料結構設計-1">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88-1"></a>
c 資料結構設計
</h3><h4 id="1-graph圖的鄰接矩陣表示">
<a class="header-anchor" href="#1-graph%e5%9c%96%e7%9a%84%e9%84%b0%e6%8e%a5%e7%9f%a9%e9%99%a3%e8%a1%a8%e7%a4%ba"></a>
1. Graph（圖的鄰接矩陣表示）
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">Graph</span><span class="p">;</span>
</span></span></code></pre></div><ul>
<li><strong>分析：</strong> <code>Graph</code> 是一個二維向量，表示圖的鄰接矩陣。其中 <code>graph[u][v]</code> 表示從節點 <code>u</code> 到節點 <code>v</code> 的邊的權重。0 表示沒有直接連接。</li>
</ul>
<h4 id="2-distances儲存節點到起始節點的最短距離">
<a class="header-anchor" href="#2-distances%e5%84%b2%e5%ad%98%e7%af%80%e9%bb%9e%e5%88%b0%e8%b5%b7%e5%a7%8b%e7%af%80%e9%bb%9e%e7%9a%84%e6%9c%80%e7%9f%ad%e8%b7%9d%e9%9b%a2"></a>
2. distances（儲存節點到起始節點的最短距離）
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">distances</span><span class="p">;</span>
</span></span></code></pre></div><ul>
<li><strong>分析：</strong> <code>distances</code> 是一個一維向量，用於儲存每個節點到起始節點的最短距離。初始值為無窮大，後續會在 Dijkstra 演算法的執行過程中被更新。</li>
</ul>
<h4 id="3-pq優先佇列">
<a class="header-anchor" href="#3-pq%e5%84%aa%e5%85%88%e4%bd%87%e5%88%97"></a>
3. pq（優先佇列）
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span><span class="p">,</span> <span class="n">greater</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;&gt;</span> <span class="n">pq</span><span class="p">;</span>
</span></span></code></pre></div><ul>
<li><strong>分析：</strong> <code>pq</code> 是一個優先佇列，用於按照節點的距離從小到大排序。每個佇列元素是一個 <code>pair&lt;int, int&gt;</code>，表示節點和其距離。透過 <code>greater&lt;pair&lt;int, int&gt;&gt;</code> 指定比較規則，確保隊首元素是最小的。</li>
</ul>
<h3 id="d-調試過程-1">
<a class="header-anchor" href="#d-%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b-1"></a>
d 調試過程
</h3><ul>
<li>在 <code>dijkstra</code> 函數中，使用 <code>cout</code> 輸出中間結果，確保每一步計算都符合預期。</li>
<li>考慮邊界情況，如圖中有沒有邊、負權邊等，以確保算法的魯棒性。</li>
<li>通過多個測試用例驗證算法的正確性和效率。</li>
</ul>
<h3 id="e-輸出結果-1">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%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="n">Distance</span> <span class="n">from</span> <span class="n">node</span> <span class="mi">0</span> <span class="n">to</span> <span class="mi">0</span><span class="o">:</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"><span class="n">Distance</span> <span class="n">from</span> <span class="n">node</span> <span class="mi">0</span> <span class="n">to</span> <span class="mi">1</span><span class="o">:</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="n">Distance</span> <span class="n">from</span> <span class="n">node</span> <span class="mi">0</span> <span class="n">to</span> <span class="mi">2</span><span class="o">:</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="n">Distance</span> <span class="n">from</span> <span class="n">node</span> <span class="mi">0</span> <span class="n">to</span> <span class="mi">3</span><span class="o">:</span> <span class="mi">9</span>
</span></span><span class="line"><span class="cl"><span class="n">Distance</span> <span class="n">from</span> <span class="n">node</span> <span class="mi">0</span> <span class="n">to</span> <span class="mi">4</span><span class="o">:</span> <span class="mi">6</span>
</span></span></code></pre></div><h3 id="f-原始碼-1">
<a class="header-anchor" href="#f-%e5%8e%9f%e5%a7%8b%e7%a2%bc-1"></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</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;queue&gt;</span><span class="c1">//引入優先佇列
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;climits&gt;</span><span class="c1">//引入int型最大值
</span></span></span><span class="line"><span class="cl">
</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="cp">#define INF INT_MAX
</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">typedef</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">Graph</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="c1">//二維向量表示兩節點間邊的權重，graph[u][v]
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Dijkstra演算法實現
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">dijkstra</span><span class="p">(</span><span class="k">const</span> <span class="n">Graph</span><span class="o">&amp;</span> <span class="n">graph</span><span class="p">,</span> <span class="kt">int</span> <span class="n">start</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">distances</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="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="n">graph</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="c1">//n為節點數
</span></span></span><span class="line"><span class="cl">    <span class="n">distances</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">INF</span><span class="p">);</span>  <span class="c1">// 初始化距離陣列，初始值為無窮大
</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="n">priority_queue</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span><span class="p">,</span> <span class="n">greater</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;&gt;</span> <span class="n">pq</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="c1">//pair為其他節點，和該節點到起始節點的距離，構成的對{distance,v}
</span></span></span><span class="line"><span class="cl"><span class="c1">//優先佇列的元素類型為pair，底層容器類型為vector
</span></span></span><span class="line"><span class="cl"><span class="c1">//定義比較器greater，比較規則為pair，佇列頂端將是距離最短的節點pair
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">distances</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>  <span class="c1">// 起始節點到自身的距離為0
</span></span></span><span class="line"><span class="cl">    <span class="n">pq</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="mi">0</span><span class="p">,</span> <span class="n">start</span><span class="p">});</span>   <span class="c1">// 將起始節點加入佇列，距離為0
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">pq</span><span class="p">.</span><span class="n">empty</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">u</span> <span class="o">=</span> <span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">().</span><span class="n">second</span><span class="p">;</span>  <span class="c1">// 取出當前距離起點最小的節點，定為出發點u
</span></span></span><span class="line"><span class="cl">        <span class="n">pq</span><span class="p">.</span><span class="n">pop</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="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">n</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="k">if</span> <span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">u</span><span class="p">][</span><span class="n">v</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">distances</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">distances</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">+</span> <span class="n">graph</span><span class="p">[</span><span class="n">u</span><span class="p">][</span><span class="n">v</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="c1">// 如果通過當前節點u到節點v的距離比已知的距離短，更新距離值
</span></span></span><span class="line"><span class="cl">                <span class="n">distances</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">distances</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">+</span> <span class="n">graph</span><span class="p">[</span><span class="n">u</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">pq</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">distances</span><span class="p">[</span><span class="n">v</span><span class="p">],</span> <span class="n">v</span><span class="p">});</span>  <span class="c1">// 將新距離和節點v加入佇列
</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><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">Graph</span> <span class="n">graph</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</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="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</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="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">startNode</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">distances</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">dijkstra</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">startNode</span><span class="p">,</span> <span class="n">distances</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">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">distances</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</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;Distance from node &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">startNode</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; to &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">i</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="k">if</span> <span class="p">(</span><span class="n">distances</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">INF</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;INF&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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">cout</span> <span class="o">&lt;&lt;</span> <span class="n">distances</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="n">endl</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></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>
        
        <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><item><title>資料結構實機實驗報告6——前序、後序將二元樹線索化，圖的鄰接矩陣和鄰接表的儲存</title><link>https://www.guzhengsvt.cn/zh-tw/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/zh-tw/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%e5%ba%8f%e5%be%8c%e7%ba%8c%e5%b0%87%e4%ba%8c%e5%85%83%e6%a8%b9%e7%b7%9a%e7%b4%a2%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-%e6%bc%94%e7%ae%97%e6%b3%95%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-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
c. 資料結構設計
</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="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-%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b"></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-%e8%bc%b8%e5%87%ba%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-%e5%8e%9f%e5%a7%8b%e7%a2%bc"></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="#%e5%9c%96%e7%9a%84%e9%84%b0%e6%8e%a5%e7%9f%a9%e9%99%a3%e5%92%8c%e9%84%b0%e6%8e%a5%e8%a1%a8%e7%9a%84%e5%84%b2%e5%ad%98"></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++中實現圖的鄰接矩陣和鄰接表的存儲。這涉及到兩種不同的資料結構：陣列（用於鄰接矩陣）和鏈表（用於鄰接表）。</p>
<h3 id="b-演算法設計-1">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88-1"></a>
b. 演算法設計
</h3><h4 id="鄰接矩陣">
<a class="header-anchor" href="#%e9%84%b0%e6%8e%a5%e7%9f%a9%e9%99%a3"></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%84%b0%e6%8e%a5%e8%a1%a8"></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-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88-1"></a>
c. 資料結構設計
</h3><h4 id="鄰接矩陣-1">
<a class="header-anchor" href="#%e9%84%b0%e6%8e%a5%e7%9f%a9%e9%99%a3-1"></a>
鄰接矩陣
</h4><p>我們使用一個二維陣列<code>int adj[MAX][MAX]</code>來儲存鄰接矩陣。<code>MAX</code>是圖中節點的最大數量。</p>
<h4 id="鄰接表-1">
<a class="header-anchor" href="#%e9%84%b0%e6%8e%a5%e8%a1%a8-1"></a>
鄰接表
</h4><p>我們使用一個鏈結串列陣列<code>list&lt;int&gt; *adj</code>來儲存鄰接表。<code>V</code>是圖中節點的數量。</p>
<h3 id="d-除錯過程">
<a class="header-anchor" href="#d-%e9%99%a4%e9%8c%af%e9%81%8e%e7%a8%8b"></a>
d. 除錯過程
</h3><p>在實作和除錯程式碼的過程中，我們首先確保了輸入的邊是有效的。如果輸入的邊無效（例如，如果它引用了一個不存在的節點），我們會提示使用者並讓他們重新輸入。</p>
<p>在新增邊到鄰接矩陣或鄰接表時，我們使用了錯誤檢查來確保我們不會嘗試存取陣列或鏈結串列的越界索引。</p>
<h3 id="e-輸出結果-1">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%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-%e5%8e%9f%e5%a7%8b%e7%a2%bc-1"></a>
f. 原始碼
</h3><h4 id="鄰接矩陣儲存">
<a class="header-anchor" href="#%e9%84%b0%e6%8e%a5%e7%9f%a9%e9%99%a3%e5%84%b2%e5%ad%98"></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%84%b0%e6%8e%a5%e8%a1%a8%e5%84%b2%e5%ad%98"></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><item><title>資料結構實機實驗報告5——哈夫曼樹的編碼和解碼，排序二元樹的建構和節點刪除</title><link>https://www.guzhengsvt.cn/zh-tw/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%8A5%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91%E7%9A%84%E7%BC%96%E7%A0%81%E5%92%8C%E8%AF%91%E7%A0%81%E6%8E%92%E5%BA%8F%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9E%84%E5%BB%BA%E5%92%8C%E8%8A%82%E7%82%B9%E5%88%A0%E9%99%A4/</link><pubDate>Tue, 12 Dec 2023 14:54:04 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/zh-tw/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%8A5%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91%E7%9A%84%E7%BC%96%E7%A0%81%E5%92%8C%E8%AF%91%E7%A0%81%E6%8E%92%E5%BA%8F%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9E%84%E5%BB%BA%E5%92%8C%E8%8A%82%E7%82%B9%E5%88%A0%E9%99%A4/</guid><description>
<![CDATA[<h1>資料結構實機實驗報告5——哈夫曼樹的編碼和解碼，排序二元樹的建構和節點刪除</h1><p>作者：孤筝（lvbowen040427@163.com）</p>
        
          <h2 id="實現哈夫曼樹的編碼和解碼">
<a class="header-anchor" href="#%e5%af%a6%e7%8f%be%e5%93%88%e5%a4%ab%e6%9b%bc%e6%a8%b9%e7%9a%84%e7%b7%a8%e7%a2%bc%e5%92%8c%e8%a7%a3%e7%a2%bc"></a>
實現哈夫曼樹的編碼和解碼
</h2><h4 id="a-問題分析">
<a class="header-anchor" href="#a-%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
a. 問題分析
</h4><h5 id="目標">
<a class="header-anchor" href="#%e7%9b%ae%e6%a8%99"></a>
目標：
</h5><p>實現排序二叉樹的構建和節點刪除。</p>
<h5 id="問題">
<a class="header-anchor" href="#%e5%95%8f%e9%a1%8c"></a>
問題：
</h5><ol>
<li>構建排序二叉樹的過程是否正確？</li>
<li>是否正確實現了節點的插入和刪除？</li>
<li>是否能夠處理重複值的節點？</li>
<li>是否能夠正確處理樹的平衡性？</li>
</ol>
<h4 id="b-算法設計">
<a class="header-anchor" href="#b-%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
b. 算法設計
</h4><h5 id="1-構建排序二叉樹">
<a class="header-anchor" href="#1-%e6%a7%8b%e5%bb%ba%e6%8e%92%e5%ba%8f%e4%ba%8c%e5%8f%89%e6%a8%b9"></a>
1. 構建排序二叉樹：
</h5><ul>
<li>根據輸入的數據，依次插入節點到排序二叉樹中。</li>
</ul>
<p><strong>輸入：</strong> 一組數據值。
<strong>輸出：</strong> 排序二叉樹的根節點 <code>root</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="n">TreeNode</span><span class="o">*</span> <span class="nf">buildBST</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">values</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span> <span class="o">=</span> <span class="k">nullptr</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="nl">val</span> <span class="p">:</span> <span class="n">values</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span> <span class="o">=</span> <span class="n">insertNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">val</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">return</span> <span class="n">root</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h5 id="2-插入節點">
<a class="header-anchor" href="#2-%e6%8f%92%e5%85%a5%e7%af%80%e9%bb%9e"></a>
2. 插入節點：
</h5><ul>
<li>遞歸地找到合適的位置插入新節點。</li>
</ul>
<p><strong>輸入：</strong> 當前子樹的根節點 <code>node</code>，要插入的值 <code>val</code>。
<strong>輸出：</strong> 插入後的子樹根節點。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">insertNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">node</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">val</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">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">insertNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">insertNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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">return</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h5 id="3-刪除節點">
<a class="header-anchor" href="#3-%e5%88%aa%e9%99%a4%e7%af%80%e9%bb%9e"></a>
3. 刪除節點：
</h5><ul>
<li>找到要刪除的節點，並根據其子節點的情況進行刪除操作。</li>
</ul>
<p><strong>輸入：</strong> 當前子樹的根節點 <code>node</code>，要刪除的值 <code>val</code>。
<strong>輸出：</strong> 刪除後的子樹根節點。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">deleteNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">node</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">nullptr</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">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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="k">if</span> <span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">node</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="k">delete</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">node</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="k">delete</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</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">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">findMin</span><span class="p">(</span><span class="n">node</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">node</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">=</span> <span class="n">temp</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">temp</span><span class="o">-&gt;</span><span class="n">val</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">return</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h5 id="4-查找最小節點">
<a class="header-anchor" href="#4-%e6%9f%a5%e6%89%be%e6%9c%80%e5%b0%8f%e7%af%80%e9%bb%9e"></a>
4. 查找最小節點：
</h5><ul>
<li>在右子樹中找到最小的節點（用於刪除節點時替換）。</li>
</ul>
<p><strong>輸入：</strong> 當前子樹的根節點 <code>node</code>。
<strong>輸出：</strong> 最小節點的指針。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">findMin</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</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">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span> <span class="o">=</span> <span class="n">node</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="k">return</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="c-數據結構設計">
<a class="header-anchor" href="#c-%e6%95%b8%e6%93%9a%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
c. 數據結構設計
</h4><ul>
<li><strong>TreeNode 結構體：</strong>
<ul>
<li>存儲節點值 <code>val</code>，以及左右子節點指針 <code>left</code> 和 <code>right</code>。</li>
</ul>
</li>
<li><strong>std::vector：</strong>
<ul>
<li>用於存儲輸入的數據值。</li>
</ul>
</li>
<li><strong>遞歸函數：</strong>
<ul>
<li>用於實現節點的插入和刪除操作。</li>
</ul>
</li>
</ul>
<h4 id="d-調試過程">
<a class="header-anchor" href="#d-%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b"></a>
d. 調試過程
</h4><ol>
<li>
<p><strong>構建排序二叉樹：</strong></p>
<ul>
<li>檢查節點是否按照排序二叉樹的規則正確插入。</li>
<li>檢查重複值的處理是否正確。</li>
</ul>
</li>
<li>
<p><strong>刪除節點：</strong></p>
<ul>
<li>測試刪除葉子節點、只有一個子節點的節點和兩個子節點的節點。</li>
<li>檢查刪除後樹的結構是否仍然符合排序二叉樹的規則。</li>
</ul>
</li>
<li>
<p><strong>平衡性檢查：</strong></p>
<ul>
<li>雖然排序二叉樹不保證平衡，但檢查極端情況下（如完全升序或降序輸入）樹的深度是否過大。</li>
</ul>
</li>
</ol>
<h4 id="e-輸出結果">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
e. 輸出結果
</h4><p>運行程序並使用測試用例（例如輸入 <code>[5,3,6,2,4,7]</code> 並刪除節點 <code>3</code>）檢查輸出結果。確保輸出包括構建後的樹結構和刪除節點後的樹結構，並驗證其正確性。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-plaintext" data-lang="plaintext"><span class="line"><span class="cl">Original BST:
</span></span><span class="line"><span class="cl">    5
</span></span><span class="line"><span class="cl">   / \
</span></span><span class="line"><span class="cl">  3   6
</span></span><span class="line"><span class="cl"> / \   \
</span></span><span class="line"><span class="cl">2   4   7
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">After deleting node 3:
</span></span><span class="line"><span class="cl">    5
</span></span><span class="line"><span class="cl">   / \
</span></span><span class="line"><span class="cl">  4   6
</span></span><span class="line"><span class="cl"> /     \
</span></span><span class="line"><span class="cl">2       7
</span></span></code></pre></div><h4 id="f-源代碼">
<a class="header-anchor" href="#f-%e6%ba%90%e4%bb%a3%e7%a2%bc"></a>
f. 源代碼
</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</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;queue&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl">
</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">TreeNode</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">val</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span> <span class="o">*</span><span class="n">left</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span> <span class="o">*</span><span class="n">right</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">)</span> <span class="o">:</span> <span class="n">val</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="n">left</span><span class="p">(</span><span class="k">nullptr</span><span class="p">),</span> <span class="n">right</span><span class="p">(</span><span class="k">nullptr</span><span class="p">)</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="c1">// 插入節點到排序二叉樹
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">insertNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">node</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">val</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">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">insertNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">insertNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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">return</span> <span class="n">node</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="c1">// 構建排序二叉樹
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">buildBST</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">values</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span> <span class="o">=</span> <span class="k">nullptr</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="nl">val</span> <span class="p">:</span> <span class="n">values</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span> <span class="o">=</span> <span class="n">insertNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">val</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">return</span> <span class="n">root</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="c1">// 查找最小節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">findMin</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</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">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span> <span class="o">=</span> <span class="n">node</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="k">return</span> <span class="n">node</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="c1">// 刪除節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">deleteNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">node</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">nullptr</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">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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="k">if</span> <span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">node</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="k">delete</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">node</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="k">delete</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</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">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">findMin</span><span class="p">(</span><span class="n">node</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">node</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">=</span> <span class="n">temp</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">temp</span><span class="o">-&gt;</span><span class="n">val</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">return</span> <span class="n">node</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="c1">// 打印二叉樹（層序遍歷）
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">printBST</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</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">root</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</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">queue</span><span class="o">&lt;</span><span class="n">TreeNode</span><span class="o">*&gt;</span> <span class="n">q</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">root</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">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="n">q</span><span class="p">.</span><span class="n">pop</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">node</span><span class="o">-&gt;</span><span class="n">val</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="k">if</span> <span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">node</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="k">if</span> <span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">node</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="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">endl</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">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="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">values</span> <span class="o">=</span> <span class="p">{</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">7</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span> <span class="o">=</span> <span class="n">buildBST</span><span class="p">(</span><span class="n">values</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;Original BST: &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">printBST</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">root</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="mi">3</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;After deleting node 3: &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">printBST</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</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><h4 id="總結">
<a class="header-anchor" href="#%e7%b8%bd%e7%b5%90"></a>
總結
</h4><p>通過測試，確保程序正確實現了排序二叉樹的構建和節點刪除功能。特別注意刪除節點時樹的結構是否仍然符合排序二叉樹的規則，並檢查重複值的處理是否正確。雖然排序二叉樹不保證平衡，但在實際應用中可以考慮進一步優化（如 AVL 樹或紅黑樹）以保持平衡性。</p>
<h3 id="問題分析">
<a class="header-anchor" href="#%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
問題分析
</h3><p>本實驗的目標是實現基於排序二元樹的節點插入、中序遍歷、刪除整個樹以及刪除單獨某個節點的功能。具體要求包括使用<code>struct</code>實現節點，實現插入節點和刪除節點的功能。</p>
<h3 id="b-演算法設計">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
b 演算法設計
</h3><h4 id="插入節點演算法設計">
<a class="header-anchor" href="#%e6%8f%92%e5%85%a5%e7%af%80%e9%bb%9e%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
插入節點演算法設計
</h4><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="n">TreeNode</span><span class="o">*</span> <span class="nf">insert</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">root</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">val</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="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&lt;=</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">insert</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">insert</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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="k">return</span> <span class="n">root</span><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="#%e6%a7%8b%e5%bb%ba%e6%8e%92%e5%ba%8f%e4%ba%8c%e5%85%83%e6%a8%b9%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
構建排序二元樹演算法設計
</h4><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="n">TreeNode</span><span class="o">*</span> <span class="nf">buildTree</span><span class="p">(</span><span class="kt">int</span> <span class="n">input</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">size</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span> <span class="o">=</span> <span class="k">nullptr</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="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span> <span class="o">=</span> <span class="n">insert</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">input</span><span class="p">[</span><span class="n">i</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="k">return</span> <span class="n">root</span><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="#%e4%b8%ad%e5%ba%8f%e9%81%8d%e6%ad%b7%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
中序遍歷演算法設計
</h4><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="nf">inorderTraversal</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</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">node</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">inorderTraversal</span><span class="p">(</span><span class="n">node</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="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">node</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="n">inorderTraversal</span><span class="p">(</span><span class="n">node</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="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="#%e5%88%aa%e9%99%a4%e6%95%b4%e5%80%8b%e6%a8%b9%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
刪除整個樹演算法設計
</h4><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="nf">deleteTree</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</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">node</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">deleteTree</span><span class="p">(</span><span class="n">node</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="n">deleteTree</span><span class="p">(</span><span class="n">node</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="k">delete</span> <span class="n">node</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="#%e5%88%aa%e9%99%a4%e5%96%ae%e7%8d%a8%e6%9f%90%e5%80%8b%e7%af%80%e9%bb%9e%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
刪除單獨某個節點演算法設計
</h4><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="n">TreeNode</span><span class="o">*</span> <span class="nf">deleteNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">root</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">root</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="c1">// 找到匹配節點
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&lt;</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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="c1">// 節點有一個或無子節點
</span></span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">root</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="k">delete</span> <span class="n">root</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">root</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="k">delete</span> <span class="n">root</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</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="c1">// 節點有兩個子節點，找到右子樹的最小節點
</span></span></span><span class="line"><span class="cl">        <span class="n">TreeNode</span><span class="o">*</span> <span class="n">minRight</span> <span class="o">=</span> <span class="n">root</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="k">while</span> <span class="p">(</span><span class="n">minRight</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">minRight</span> <span class="o">=</span> <span class="n">minRight</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></span><span class="line"><span class="cl">        <span class="c1">// 複製最小節點的值到當前節點
</span></span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">=</span> <span class="n">minRight</span><span class="o">-&gt;</span><span class="n">data</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="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">minRight</span><span class="o">-&gt;</span><span class="n">data</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="k">return</span> <span class="n">root</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="c1">// 刪除單獨某個節點的介面函數
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">deleteSingleNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">nodeToDelete</span> <span class="o">=</span> <span class="n">findNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">val</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">nodeToDelete</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">val</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">return</span> <span class="n">root</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="c-資料結構設計">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
c 資料結構設計
</h4><h5 id="節點結構">
<a class="header-anchor" href="#%e7%af%80%e9%bb%9e%e7%b5%90%e6%a7%8b"></a>
節點結構
</h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">TreeNode</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></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">left</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">right</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="p">(</span><span class="kt">int</span> <span class="n">val</span><span class="p">)</span> <span class="o">:</span> <span class="n">data</span><span class="p">(</span><span class="n">val</span><span class="p">),</span> <span class="n">left</span><span class="p">(</span><span class="k">nullptr</span><span class="p">),</span> <span class="n">right</span><span class="p">(</span><span class="k">nullptr</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><h3 id="d-調試過程-1">
<a class="header-anchor" href="#d-%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b-1"></a>
d 調試過程
</h3><p>在調試過程中，首先確保 <code>deleteSingleNode</code> 函數能夠正確執行。通過刪除單獨某個節點後，使用中序遍歷驗證排序二叉樹的節點值，以確保刪除操作的正確性。最後，通過輸出驗證整個實現的正確性。</p>
<h3 id="e-輸出結果-1">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c-1"></a>
e 輸出結果
</h3><p>針對輸入序列 <code>7, 5, 9, 2, 5, 2, 6, 3, 7, 0</code>，實驗的輸出結果如下：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">排序二元樹: 0 2 2 3 5 5 6 7 7 9 
</span></span><span class="line"><span class="cl">刪除節點 3 後的排序二元樹: 0 2 2 5 5 6 7 7 9 
</span></span><span class="line"><span class="cl">刪除單獨節點 5 後的排序二元樹: 0 2 2 6 7 7 9 
</span></span></code></pre></div><p>這個輸出結果表明刪除單獨某個節點的功能已經添加，並且在刪除節點 5 後，中序遍歷輸出排序二元樹的節點值，驗證刪除操作的正確性。</p>
<h3 id="f-原始碼">
<a class="header-anchor" href="#f-%e5%8e%9f%e5%a7%8b%e7%a2%bc"></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</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl">
</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">TreeNode</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></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">left</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">right</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="p">(</span><span class="kt">int</span> <span class="n">val</span><span class="p">)</span> <span class="o">:</span> <span class="n">data</span><span class="p">(</span><span class="n">val</span><span class="p">),</span> <span class="n">left</span><span class="p">(</span><span class="k">nullptr</span><span class="p">),</span> <span class="n">right</span><span class="p">(</span><span class="k">nullptr</span><span class="p">)</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="c1">// 插入節點到排序二元樹
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">insert</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">root</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">val</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="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&lt;=</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">insert</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">insert</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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="k">return</span> <span class="n">root</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="c1">// 中序遍歷
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">inorderTraversal</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</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">node</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">inorderTraversal</span><span class="p">(</span><span class="n">node</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="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">node</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="n">inorderTraversal</span><span class="p">(</span><span class="n">node</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="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="c1">// 刪除整個樹
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">deleteTree</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">node</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">node</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">deleteTree</span><span class="p">(</span><span class="n">node</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="n">deleteTree</span><span class="p">(</span><span class="n">node</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="k">delete</span> <span class="n">node</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></span><span class="line"><span class="cl"><span class="c1">// 查找節點值為val的節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">findNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">root</span> <span class="o">==</span> <span class="k">nullptr</span> <span class="o">||</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">==</span> <span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">root</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="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&lt;</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">findNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</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="k">return</span> <span class="n">findNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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></span><span class="line"><span class="cl"><span class="c1">// 刪除單獨某個節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">deleteNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</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">root</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">root</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="c1">// 找到匹配節點
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&lt;</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="o">&gt;</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">val</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="c1">// 節點有一個或無子節點
</span></span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">root</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="k">delete</span> <span class="n">root</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">TreeNode</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">root</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="k">delete</span> <span class="n">root</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">temp</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="c1">// 節點有兩個子節點，找到右子樹的最小節點
</span></span></span><span class="line"><span class="cl">        <span class="n">TreeNode</span><span class="o">*</span> <span class="n">minRight</span> <span class="o">=</span> <span class="n">root</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="k">while</span> <span class="p">(</span><span class="n">minRight</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">minRight</span> <span class="o">=</span> <span class="n">minRight</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></span><span class="line"><span class="cl">        <span class="c1">// 複製最小節點的值到當前節點
</span></span></span><span class="line"><span class="cl">        <span class="n">root</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">=</span> <span class="n">minRight</span><span class="o">-&gt;</span><span class="n">data</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="n">root</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">,</span> <span class="n">minRight</span><span class="o">-&gt;</span><span class="n">data</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="k">return</span> <span class="n">root</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="c1">// 刪除單獨某個節點的介面函數
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">deleteSingleNode</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span><span class="p">,</span> <span class="kt">int</span> <span class="n">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">nodeToDelete</span> <span class="o">=</span> <span class="n">findNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">val</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">nodeToDelete</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">val</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">return</span> <span class="n">root</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">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="kt">int</span> <span class="n">input</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</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">TreeNode</span><span class="o">*</span> <span class="n">root</span> <span class="o">=</span> <span class="k">nullptr</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">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">root</span> <span class="o">=</span> <span class="n">insert</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">input</span><span class="p">[</span><span class="n">i</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="c1">// 顯示排序二元樹
</span></span></span><span class="line"><span class="cl">    <span class="n">cout</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="n">inorderTraversal</span><span class="p">(</span><span class="n">root</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">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 刪除節點 3 後的排序二元樹
</span></span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">nodeToDelete</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">root</span> <span class="o">=</span> <span class="n">deleteNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">nodeToDelete</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;刪除節點 &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">nodeToDelete</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="n">inorderTraversal</span><span class="p">(</span><span class="n">root</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">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 刪除單獨節點 5 後的排序二元樹
</span></span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">singleNodeToDelete</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">root</span> <span class="o">=</span> <span class="n">deleteSingleNode</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">singleNodeToDelete</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;刪除單獨節點 &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">singleNodeToDelete</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="n">inorderTraversal</span><span class="p">(</span><span class="n">root</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">endl</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="n">deleteTree</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</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>
        
        <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><item><title>資料結構實機實驗報告4——二元樹的建構（完全二元樹BFS結果）、儲存（順序儲存與鏈式儲存）、遍歷（BFS與DFS）</title><link>https://www.guzhengsvt.cn/zh-tw/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%8A4%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9E%84%E5%BB%BA%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91bfs%E7%BB%93%E6%9E%9C%E5%AD%98%E5%82%A8%E9%A1%BA%E5%BA%8F%E5%AD%98%E5%82%A8%E4%B8%8E%E9%93%BE%E5%BC%8F%E5%AD%98%E5%82%A8%E9%81%8D%E5%8E%86bfs%E4%B8%8Edfs/</link><pubDate>Tue, 12 Dec 2023 14:43:54 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/zh-tw/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%8A4%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9E%84%E5%BB%BA%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91bfs%E7%BB%93%E6%9E%9C%E5%AD%98%E5%82%A8%E9%A1%BA%E5%BA%8F%E5%AD%98%E5%82%A8%E4%B8%8E%E9%93%BE%E5%BC%8F%E5%AD%98%E5%82%A8%E9%81%8D%E5%8E%86bfs%E4%B8%8Edfs/</guid><description>
<![CDATA[<h1>資料結構實機實驗報告4——二元樹的建構（完全二元樹BFS結果）、儲存（順序儲存與鏈式儲存）、遍歷（BFS與DFS）</h1><p>作者：孤筝（lvbowen040427@163.com）</p>
        
          <h2 id="1-根據輸入建立二元樹順序儲存和鏈結儲存">
<a class="header-anchor" href="#1-%e6%a0%b9%e6%93%9a%e8%bc%b8%e5%85%a5%e5%bb%ba%e7%ab%8b%e4%ba%8c%e5%85%83%e6%a8%b9%e9%a0%86%e5%ba%8f%e5%84%b2%e5%ad%98%e5%92%8c%e9%8f%88%e7%b5%90%e5%84%b2%e5%ad%98"></a>
1. 根據輸入建立二元樹，順序儲存和鏈結儲存
</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>在這個問題中，需要根據輸入的字元序列建立一個二元樹，要求實現兩種儲存方式：順序儲存和鏈式儲存。輸入的字元序列中，字元 &lsquo;@&rsquo; 表示空節點。</p>
<h3 id="b-演算法設計">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
b. 演算法設計：
</h3><h4 id="順序儲存方式">
<a class="header-anchor" href="#%e9%a0%86%e5%ba%8f%e5%84%b2%e5%ad%98%e6%96%b9%e5%bc%8f"></a>
順序儲存方式：
</h4><ol>
<li>初始化一個陣列來表示順序儲存的二元樹。</li>
<li>依序遍歷輸入字元序列，將字元按照順序儲存到陣列中。</li>
<li>可以使用陣列的索引來表示節點的位置，假設父節點的索引為 <code>i</code>，則左子節點的索引為 <code>2*i + 1</code>，右子節點的索引為 <code>2*i + 2</code>。</li>
<li>將 &lsquo;@&rsquo; 字元表示的空節點跳過，只儲存實際的資料。</li>
</ol>
<h4 id="鏈結儲存方式">
<a class="header-anchor" href="#%e9%8f%88%e7%b5%90%e5%84%b2%e5%ad%98%e6%96%b9%e5%bc%8f"></a>
鏈結儲存方式：
</h4><ol>
<li>建立一個結構體 <code>TreeNode</code> 來表示二元樹的節點，包含資料、左子樹指標和右子樹指標。</li>
<li>使用佇列資料結構輔助建構二元樹。初始化一個根節點，將其入隊。</li>
<li>遍歷輸入字元序列，每次從佇列中取出一個節點，為其建立左子節點和右子節點，然後將它們入隊。</li>
</ol>
<h3 id="c-資料結構設計">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
c. 資料結構設計：
</h3><h4 id="順序存儲方式">
<a class="header-anchor" href="#%e9%a0%86%e5%ba%8f%e5%ad%98%e5%84%b2%e6%96%b9%e5%bc%8f"></a>
順序存儲方式：
</h4><ul>
<li><code>struct TreeNode</code> 用於表示二元樹的節點。</li>
<li>陣列用於順序存儲二元樹節點。</li>
</ul>
<h4 id="鏈式存儲方式">
<a class="header-anchor" href="#%e9%8f%88%e5%bc%8f%e5%ad%98%e5%84%b2%e6%96%b9%e5%bc%8f"></a>
鏈式存儲方式：
</h4><ul>
<li><code>struct TreeNode</code> 用於表示二元樹的節點，包含資料、左子樹指標和右子樹指標。</li>
<li>佇列資料結構用於輔助構建二元樹。</li>
</ul>
<h3 id="d-除錯過程">
<a class="header-anchor" href="#d-%e9%99%a4%e9%8c%af%e9%81%8e%e7%a8%8b"></a>
d. 除錯過程：
</h3><ul>
<li>執行程式，按照輸入範例輸入字元以建構二元樹。</li>
<li>確保輸入的字元順序正確，空節點用 &lsquo;@&rsquo; 表示。</li>
<li>鏈式儲存時用&rsquo;#&lsquo;表示輸入完畢</li>
<li>驗證建立的二元樹的順序儲存和鏈式儲存是否正確。</li>
</ul>
<h3 id="e-輸出結果">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
e. 輸出結果：
</h3><ul>
<li>輸出結果包括順序儲存的二元樹節點資料和鏈式儲存的二元樹的遍歷結果。</li>
</ul>
<h2 id="2-深度遍歷演算法的實現">
<a class="header-anchor" href="#2-%e6%b7%b1%e5%ba%a6%e9%81%8d%e6%ad%b7%e6%bc%94%e7%ae%97%e6%b3%95%e7%9a%84%e5%af%a6%e7%8f%be"></a>
2. 深度遍歷演算法的實現
</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>在這個問題中，需要實現深度遍歷演算法，包括前序遍歷、中序遍歷和後序遍歷。對於順序儲存的二元樹，需要實現相應的遍歷演算法。</p>
<h3 id="b-演算法設計-1">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88-1"></a>
b. 演算法設計：
</h3><h4 id="前序遍歷">
<a class="header-anchor" href="#%e5%89%8d%e5%ba%8f%e9%81%8d%e6%ad%b7"></a>
前序遍歷：
</h4><ul>
<li>訪問根節點，然後遞迴遍歷左子樹和右子樹。</li>
</ul>
<h4 id="中序遍歷">
<a class="header-anchor" href="#%e4%b8%ad%e5%ba%8f%e9%81%8d%e6%ad%b7"></a>
中序遍歷：
</h4><ul>
<li>先遞迴遍歷左子樹，然後訪問根節點，最後遞迴遍歷右子樹。</li>
</ul>
<h4 id="後序遍歷">
<a class="header-anchor" href="#%e5%be%8c%e5%ba%8f%e9%81%8d%e6%ad%b7"></a>
後序遍歷：
</h4><ul>
<li>先遞迴遍歷左子樹和右子樹，然後訪問根節點。</li>
</ul>
<h3 id="c-資料結構設計-1">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88-1"></a>
c. 資料結構設計：
</h3><ul>
<li>遞迴演算法。</li>
</ul>
<h2 id="3-廣度遍歷演算法的實現">
<a class="header-anchor" href="#3-%e5%bb%a3%e5%ba%a6%e9%81%8d%e6%ad%b7%e6%bc%94%e7%ae%97%e6%b3%95%e7%9a%84%e5%af%a6%e7%8f%be"></a>
3. 廣度遍歷演算法的實現
</h2><h3 id="a-問題分析-2">
<a class="header-anchor" href="#a-%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90-2"></a>
a. 問題分析：
</h3><p>在這個問題中，需要實現廣度遍歷演算法（層次遍歷）。對於鏈式存儲的二元樹，需要實現相應的遍歷演算法。</p>
<h3 id="b-演算法設計-2">
<a class="header-anchor" href="#b-%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88-2"></a>
b. 演算法設計：
</h3><ul>
<li>使用佇列資料結構，從根節點開始，將節點逐層加入佇列，並逐個存取佇列中的節點。</li>
</ul>
<h3 id="c-資料結構設計-2">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88-2"></a>
c. 資料結構設計：
</h3><ul>
<li>佇列資料結構。</li>
</ul>
<p>非常抱歉，我理解你的要求，下面將使用具體的樣例 <code>abc@@@d@ef@</code> 和 <code>abc@@@d@ef@#</code> 來完善調試過程和輸出結果，並結合你提供的程式碼進行說明。</p>
<h2 id="樣例">
<a class="header-anchor" href="#%e6%a8%a3%e4%be%8b"></a>
樣例
</h2><p><code>abc@@@d@ef@</code>，<code>abc@@@d@ef@#</code></p>
<h3 id="調試過程">
<a class="header-anchor" href="#%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b"></a>
調試過程：
</h3><ol>
<li>使用順序存儲方式：
<ul>
<li>依次讀入字元 &lsquo;a&rsquo;， &lsquo;b&rsquo;， &lsquo;c&rsquo;， &lsquo;@&rsquo;， &lsquo;@&rsquo;， &lsquo;@&rsquo;， &rsquo;d&rsquo;， &lsquo;@&rsquo;， &rsquo;e&rsquo;， &lsquo;f&rsquo;。</li>
<li>構建順序存儲的二元樹，陣列元素如下： <code>['a', 'b', 'c', '@', '@', '@', 'd', '@', 'e', 'f']</code>。</li>
</ul>
</li>
<li>使用鏈式存儲方式：
<ul>
<li>創建根節點 &lsquo;a&rsquo;，將其入隊。</li>
<li>讀入字元 &lsquo;b&rsquo;，創建 &lsquo;a&rsquo; 的左子節點 &lsquo;b&rsquo;，將其入隊。</li>
<li>讀入字元 &lsquo;c&rsquo;，創建 &lsquo;a&rsquo; 的右子節點 &lsquo;c&rsquo;，將其入隊。</li>
<li>讀入字元 &lsquo;@&rsquo;，表示左子節點為空。</li>
<li>讀入字元 &lsquo;@&rsquo;，表示右子節點為空。</li>
<li>讀入字元 &rsquo;d&rsquo;，創建 &lsquo;b&rsquo; 的左子節點 &rsquo;d&rsquo;，將其入隊。</li>
<li>讀入字元 &lsquo;@&rsquo;，表示右子節點為空。</li>
<li>讀入字元 &rsquo;e&rsquo;，創建 &lsquo;c&rsquo; 的左子節點 &rsquo;e&rsquo;，將其入隊。</li>
<li>讀入字元 &lsquo;f&rsquo;，創建 &lsquo;c&rsquo; 的右子節點 &lsquo;f&rsquo;，將其入隊。</li>
</ul>
</li>
</ol>
<h3 id="輸出結果">
<a class="header-anchor" href="#%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
輸出結果：
</h3><ol>
<li>順序存儲方式：
<ul>
<li>先序遍歷結果： <code>a b d c e f</code></li>
<li>中序遍歷結果： <code>d b a e c f</code></li>
<li>後序遍歷結果： <code>d b e f c a</code></li>
</ul>
</li>
<li>鏈式存儲方式：
<ul>
<li>前序遍歷結果： <code>a b d c e f</code></li>
<li>中序遍歷結果： <code>b d a e c f</code></li>
<li>後序遍歷結果： <code>d b e f c a</code></li>
<li>廣度優先搜索（層次遍歷）結果： <code>a b c d e f</code></li>
</ul>
</li>
</ol>
<h2 id="原始碼">
<a class="header-anchor" href="#%e5%8e%9f%e5%a7%8b%e7%a2%bc"></a>
原始碼
</h2><h3 id="順序儲存">
<a class="header-anchor" href="#%e9%a0%86%e5%ba%8f%e5%84%b2%e5%ad%98"></a>
順序儲存
</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;bits/stdc++.h&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 class="cp">#define MAX_NODES 1000  </span><span class="c1">// 最大節點數量
</span></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">TreeNode</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">data</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="c1">// 創建一個新的二元樹節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">createNode</span><span class="p">(</span><span class="kt">char</span> <span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">newNode</span> <span class="o">=</span> <span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">TreeNode</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">newNode</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">newNode</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="c1">// 順序儲存的字符二元樹結構
</span></span></span><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">SequentialTree</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">nodes</span><span class="p">[</span><span class="n">MAX_NODES</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">size</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="c1">// 初始化順序儲存的字符二元樹
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">initSequentialTree</span><span class="p">(</span><span class="n">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</span> <span class="o">=</span> <span class="mi">0</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">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">MAX_NODES</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">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">nullptr</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="c1">// 插入一個節點到順序儲存的字符二元樹
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">insertNode</span><span class="p">(</span><span class="n">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">,</span> <span class="kt">char</span> <span class="n">data</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">tree</span><span class="o">-&gt;</span><span class="n">size</span> <span class="o">&lt;</span> <span class="n">MAX_NODES</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">TreeNode</span><span class="o">*</span> <span class="n">newNode</span> <span class="o">=</span> <span class="n">createNode</span><span class="p">(</span><span class="n">data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</span><span class="p">]</span> <span class="o">=</span> <span class="n">newNode</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</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">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><span class="line"><span class="cl"><span class="c1">// 獲取根節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">getRoot</span><span class="p">(</span><span class="n">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="mi">0</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="c1">// 獲取左子節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">getLeftChild</span><span class="p">(</span><span class="n">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">,</span> <span class="kt">int</span> <span class="n">parentIndex</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">leftChildIndex</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">parentIndex</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">if</span> <span class="p">(</span><span class="n">leftChildIndex</span> <span class="o">&lt;</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</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="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">leftChildIndex</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">return</span> <span class="k">nullptr</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="c1">// 獲取右子節點
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">getRightChild</span><span class="p">(</span><span class="n">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">,</span> <span class="kt">int</span> <span class="n">parentIndex</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">rightChildIndex</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">parentIndex</span> <span class="o">+</span> <span class="mi">2</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">rightChildIndex</span> <span class="o">&lt;</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">rightChildIndex</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">return</span> <span class="k">nullptr</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="c1">// 前序遍歷
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">preorderTraversal</span><span class="p">(</span><span class="k">struct</span> <span class="nc">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">,</span> <span class="kt">int</span> <span class="n">index</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">index</span> <span class="o">&gt;=</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</span> <span class="o">||</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">==</span> <span class="sc">&#39;@&#39;</span><span class="p">)</span> <span class="p">{</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">printf</span><span class="p">(</span><span class="s">&#34;%c &#34;</span><span class="p">,</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</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">preorderTraversal</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// 遍歷左子樹
</span></span></span><span class="line"><span class="cl">    <span class="n">preorderTraversal</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">2</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="c1">// 中序遍歷
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">inorderTraversal</span><span class="p">(</span><span class="k">struct</span> <span class="nc">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">,</span> <span class="kt">int</span> <span class="n">index</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">index</span> <span class="o">&gt;=</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</span> <span class="o">||</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">==</span> <span class="sc">&#39;@&#39;</span><span class="p">)</span> <span class="p">{</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">inorderTraversal</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// 遍歷左子樹
</span></span></span><span class="line"><span class="cl">    <span class="n">printf</span><span class="p">(</span><span class="s">&#34;%c &#34;</span><span class="p">,</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</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">inorderTraversal</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">2</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="c1">// 後序遍歷
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">postorderTraversal</span><span class="p">(</span><span class="k">struct</span> <span class="nc">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="p">,</span> <span class="kt">int</span> <span class="n">index</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">index</span> <span class="o">&gt;=</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</span> <span class="o">||</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">==</span> <span class="sc">&#39;@&#39;</span><span class="p">)</span> <span class="p">{</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">postorderTraversal</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// 遍歷左子樹
</span></span></span><span class="line"><span class="cl">    <span class="n">postorderTraversal</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">2</span><span class="p">);</span> <span class="c1">// 遍歷右子樹
</span></span></span><span class="line"><span class="cl">    <span class="n">printf</span><span class="p">(</span><span class="s">&#34;%c &#34;</span><span class="p">,</span> <span class="n">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</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="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="n">SequentialTree</span><span class="o">*</span> <span class="n">tree</span><span class="o">=</span><span class="p">(</span><span class="n">SequentialTree</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">SequentialTree</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">initSequentialTree</span><span class="p">(</span><span class="n">tree</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">data</span><span class="o">=</span><span class="sc">&#39;a&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="mi">1</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">data</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">data</span><span class="o">==</span><span class="sc">&#39;#&#39;</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="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">insertNode</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span><span class="n">data</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="s">&#34;先序遍歷結果:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">preorderTraversal</span><span class="p">(</span><span class="n">tree</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">cout</span><span class="o">&lt;&lt;</span><span class="n">endl</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;中序遍歷結果:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">inorderTraversal</span><span class="p">(</span><span class="n">tree</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">cout</span><span class="o">&lt;&lt;</span><span class="n">endl</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;後序遍歷結果:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">postorderTraversal</span><span class="p">(</span><span class="n">tree</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">cout</span><span class="o">&lt;&lt;</span><span class="n">endl</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;層次遍歷結果:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</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">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">tree</span><span class="o">-&gt;</span><span class="n">size</span><span class="p">;</span><span class="n">i</span><span class="o">++</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">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">!=</span><span class="sc">&#39;@&#39;</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">tree</span><span class="o">-&gt;</span><span class="n">nodes</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">&lt;&lt;</span><span class="sc">&#39; &#39;</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">endl</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="鏈式儲存">
<a class="header-anchor" href="#%e9%8f%88%e5%bc%8f%e5%84%b2%e5%ad%98"></a>
鏈式儲存
</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;bits/stdc++.h&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 class="c1">// 二元樹節點結構
</span></span></span><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">TreeNode</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">data</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">left</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">right</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="p">(</span><span class="kt">char</span> <span class="n">val</span><span class="p">)</span> <span class="o">:</span> <span class="n">data</span><span class="p">(</span><span class="n">val</span><span class="p">),</span> <span class="n">left</span><span class="p">(</span><span class="k">nullptr</span><span class="p">),</span> <span class="n">right</span><span class="p">(</span><span class="k">nullptr</span><span class="p">)</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="c1">// 建立鏈式儲存的二元樹
</span></span></span><span class="line"><span class="cl"><span class="n">TreeNode</span><span class="o">*</span> <span class="nf">createBinaryTree</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">input</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">input</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">nullptr</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">queue</span><span class="o">&lt;</span><span class="n">TreeNode</span><span class="o">*&gt;</span> <span class="n">nodeQueue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">input</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">nodeQueue</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">root</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">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">input</span><span class="p">.</span><span class="n">length</span><span class="p">();</span> <span class="n">i</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">TreeNode</span><span class="o">*</span> <span class="n">current</span> <span class="o">=</span> <span class="n">nodeQueue</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="n">nodeQueue</span><span class="p">.</span><span class="n">pop</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">input</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">&#39;@&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">current</span><span class="o">-&gt;</span><span class="n">left</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">input</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">            <span class="n">nodeQueue</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">current</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="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">&lt;</span> <span class="n">input</span><span class="p">.</span><span class="n">length</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">input</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="o">!=</span> <span class="sc">&#39;@&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">current</span><span class="o">-&gt;</span><span class="n">right</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">input</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">            <span class="n">nodeQueue</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">current</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="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">return</span> <span class="n">root</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="c1">// 前序遍歷
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">preorderTraversal</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</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">root</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="n">root</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="n">preorderTraversal</span><span class="p">(</span><span class="n">root</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="n">preorderTraversal</span><span class="p">(</span><span class="n">root</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="p">}</span>
</span></span><span class="line"><span class="cl"><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="kt">void</span> <span class="nf">inorderTraversal</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</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">root</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">inorderTraversal</span><span class="p">(</span><span class="n">root</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="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">root</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="n">inorderTraversal</span><span class="p">(</span><span class="n">root</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="p">}</span>
</span></span><span class="line"><span class="cl"><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="kt">void</span> <span class="nf">postorderTraversal</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</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">root</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">postorderTraversal</span><span class="p">(</span><span class="n">root</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="n">postorderTraversal</span><span class="p">(</span><span class="n">root</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">root</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="p">}</span>
</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">breadthFirstTraversal</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</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="o">!</span><span class="n">root</span><span class="p">)</span> <span class="p">{</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">queue</span><span class="o">&lt;</span><span class="n">TreeNode</span><span class="o">*&gt;</span> <span class="n">nodeQueue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">nodeQueue</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">root</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">nodeQueue</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">TreeNode</span><span class="o">*</span> <span class="n">current</span> <span class="o">=</span> <span class="n">nodeQueue</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="n">nodeQueue</span><span class="p">.</span><span class="n">pop</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">current</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="k">if</span> <span class="p">(</span><span class="n">current</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">nodeQueue</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">current</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="k">if</span> <span class="p">(</span><span class="n">current</span><span class="o">-&gt;</span><span class="n">right</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">nodeQueue</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">current</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="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="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="n">string</span> <span class="n">input</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">input</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">TreeNode</span><span class="o">*</span> <span class="n">root</span> <span class="o">=</span> <span class="n">createBinaryTree</span><span class="p">(</span><span class="n">input</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;前序遍歷結果: &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">preorderTraversal</span><span class="p">(</span><span class="n">root</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">endl</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;中序遍歷結果: &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">inorderTraversal</span><span class="p">(</span><span class="n">root</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">endl</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;後序遍歷結果: &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">postorderTraversal</span><span class="p">(</span><span class="n">root</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">endl</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;廣度優先搜尋（層次遍歷）結果: &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">breadthFirstTraversal</span><span class="p">(</span><span class="n">root</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">endl</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>
        
        <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><item><title>資料結構實機實驗報告3——KMP演算法用於字串搜尋</title><link>https://www.guzhengsvt.cn/zh-tw/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%8A3kmp%E7%AE%97%E6%B3%95%E7%94%A8%E4%BA%8E%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%90%9C%E7%B4%A2/</link><pubDate>Tue, 12 Dec 2023 14:42:01 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/zh-tw/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%8A3kmp%E7%AE%97%E6%B3%95%E7%94%A8%E4%BA%8E%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%90%9C%E7%B4%A2/</guid><description>
<![CDATA[<h1>資料結構實機實驗報告3——KMP演算法用於字串搜尋</h1><p>作者：孤筝（lvbowen040427@163.com）</p>
        
          <h2 id="實驗目的">
<a class="header-anchor" href="#%e5%af%a6%e9%a9%97%e7%9b%ae%e7%9a%84"></a>
<strong>實驗目的：</strong>
</h2><p>本實驗旨在分析和測試KMP算法的實現，並研究其在字串搜尋中的應用。</p>
<h2 id="實驗內容">
<a class="header-anchor" href="#%e5%af%a6%e9%a9%97%e5%85%a7%e5%ae%b9"></a>
<strong>實驗內容：</strong>
</h2><h3 id="a-問題分析">
<a class="header-anchor" href="#a-%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
<strong>a 問題分析：</strong>
</h3><ul>
<li>如何構建最長前綴後綴匹配表（LPS陣列）以提高搜尋效率？</li>
<li>如何在文本字串中執行匹配，利用LPS陣列來避免不必要的字元比較？</li>
<li>如何設計算法以實現模式字串的搜尋？</li>
</ul>
<h3 id="b-算法設計">
<a class="header-anchor" href="#b-%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
<strong>b 算法設計：</strong>
</h3><p>KMP算法的設計包括以下關鍵步驟：</p>
<ul>
<li>構建LPS陣列：使用<code>computeLPSArray</code>函數來計算模式字串的LPS陣列，該陣列指示了模式字串中每個位置的前綴和後綴的最長匹配長度。</li>
<li>在文本中執行匹配：使用<code>KMPSearch</code>函數，該函數在文本字串中執行模式字串的匹配。它使用LPS陣列來智能地回溯，以提高搜尋效率。</li>
</ul>
<h3 id="c-資料結構設計">
<a class="header-anchor" href="#c-%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
<strong>c 資料結構設計：</strong>
</h3><p>在這次實驗中，我使用了以下資料結構：</p>
<ul>
<li>字串：用於表示文本字串和模式字串。</li>
<li>向量（vector）：用於儲存LPS陣列。</li>
<li>整數變數：用於表示匹配過程中的索引。</li>
</ul>
<h3 id="d-調試過程">
<a class="header-anchor" href="#d-%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b"></a>
<strong>d 調試過程：</strong>
</h3><p>在編寫和測試程式碼時，我遇到了一些可能的問題，如邏輯錯誤或邊界情況。這些問題需要仔細調試，以確保算法的正確性和性能。通過逐步調試和打印輸出結果，我確認程式碼能夠正確地找到模式字串在文本中的匹配位置。</p>
<h3 id="e-輸出結果">
<a class="header-anchor" href="#e-%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
<strong>e 輸出結果：</strong>
</h3><p>以下是一些範例輸出結果：</p>
<ul>
<li>當文本字串為&quot;ABABDABACDABABCABAB&quot;，模式字串為&quot;ABABCABAB&quot;時，KMP算法找到了模式字串在文本中的匹配位置：</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">在索引 10 處找到匹配串
</span></span></code></pre></div><ul>
<li>當文本字串和模式字串由使用者輸入時，KMP算法會在使用者提供的文本中查找使用者提供的模式，並輸出匹配位置。</li>
</ul>
<h3 id="f-原始碼">
<a class="header-anchor" href="#f-%e5%8e%9f%e5%a7%8b%e7%a2%bc"></a>
f 原始碼：
</h3><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cp">#include&lt;bits/stdc++.h&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">// 計算匹配字串的最長前綴後綴匹配表（LPS陣列）
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">computeLPSArray</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">lps</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">length</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>  <span class="c1">// 前一個最長前綴後綴匹配的長度
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">lps</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>  <span class="c1">// lps[0] 總是為 0
</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">i</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">while</span> <span class="p">(</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">pattern</span><span class="p">.</span><span class="n">length</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">pattern</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">pattern</span><span class="p">[</span><span class="n">length</span><span class="p">])</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">length</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">lps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">length</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="k">if</span> <span class="p">(</span><span class="n">length</span> <span class="o">!=</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">length</span> <span class="o">=</span> <span class="n">lps</span><span class="p">[</span><span class="n">length</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 class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">lps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</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></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><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 使用KMP算法在文本中搜尋匹配字串
</span></span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">KMPSearch</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">text</span><span class="p">,</span> <span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">pattern</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">m</span> <span class="o">=</span> <span class="n">pattern</span><span class="p">.</span><span class="n">length</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="o">=</span> <span class="n">text</span><span class="p">.</span><span class="n">length</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">lps</span><span class="p">(</span><span class="n">m</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">computeLPSArray</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">lps</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">i</span> <span class="o">=</span> <span class="mi">0</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">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>  <span class="c1">// 用於匹配串[]
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</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">pattern</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">==</span> <span class="n">text</span><span class="p">[</span><span class="n">i</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="n">j</span><span class="o">++</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="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="n">m</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">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;在索引 &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">i</span> <span class="o">-</span> <span class="n">j</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; 處找到匹配串&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">j</span> <span class="o">=</span> <span class="n">lps</span><span class="p">[</span><span class="n">j</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 class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span> <span class="o">&amp;&amp;</span> <span class="n">pattern</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="n">text</span><span class="p">[</span><span class="n">i</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">j</span> <span class="o">!=</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">j</span> <span class="o">=</span> <span class="n">lps</span><span class="p">[</span><span class="n">j</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 class="k">else</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></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><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// int main() {
</span></span></span><span class="line"><span class="cl"><span class="c1">//     string text = &#34;ABABDABACDABABCABAB&#34;;
</span></span></span><span class="line"><span class="cl"><span class="c1">//     string pattern = &#34;ABABCABAB&#34;;
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">//     KMPSearch(text, pattern);
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">//     return 0;
</span></span></span><span class="line"><span class="cl"><span class="c1">// }
</span></span></span><span class="line"><span class="cl">
</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="n">string</span> <span class="n">text</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">string</span> <span class="n">pattern</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">text</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">pattern</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">KMPSearch</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">pattern</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</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>
        
        <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><item><title>資料結構實機實驗報告2——稀疏矩陣乘法</title><link>https://www.guzhengsvt.cn/zh-tw/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%8A2%E7%A8%80%E7%96%8F%E7%9F%A9%E9%98%B5%E4%B9%98%E6%B3%95/</link><pubDate>Tue, 12 Dec 2023 14:38:24 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/zh-tw/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%8A2%E7%A8%80%E7%96%8F%E7%9F%A9%E9%98%B5%E4%B9%98%E6%B3%95/</guid><description>
<![CDATA[<h1>資料結構實機實驗報告2——稀疏矩陣乘法</h1><p>作者：孤筝（lvbowen040427@163.com）</p>
        
          <h2 id="問題分析">
<a class="header-anchor" href="#%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
問題分析
</h2><p>本實驗的主要目標是開發一個稀疏矩陣乘法演算法，該演算法能夠將兩個稀疏矩陣 A 和 B 相乘，然後輸出結果矩陣 C。在這個演算法中，稀疏矩陣使用三元組表示，並且使用者可以多次輸入不同的矩陣數據，計算它們的乘積。</p>
<h2 id="演算法設計">
<a class="header-anchor" href="#%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
演算法設計
</h2><p>稀疏矩陣乘法演算法的設計如下：</p>
<ul>
<li>使用 <code>struct</code> 結構體來表示矩陣，其中包括矩陣的行數、列數、稀疏矩陣元素的個數，以及一個陣列用於儲存節點的資訊。</li>
<li>輸入函數 <code>input</code> 用於獲取矩陣的三元組表示，檢查輸入的合法性，然後儲存在記憶體中的結構體中。</li>
<li>輸出函數 <code>output</code> 將稀疏矩陣以標準矩陣的形式打印出來，便於使用者查看。</li>
<li>矩陣乘法函數 <code>multiplier</code> 接受兩個輸入矩陣 A 和 B，計算它們的乘積，並將結果儲存在矩陣 C 中。</li>
</ul>
<h2 id="資料結構設計">
<a class="header-anchor" href="#%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
資料結構設計
</h2><ul>
<li><code>matrix</code> 結構體包含了矩陣的行數 <code>m</code>、列數 <code>n</code>、稀疏矩陣元素的個數 <code>L</code>，以及 <code>Ma</code> 陣列用於儲存節點資訊。</li>
<li><code>node</code> 結構體表示稀疏矩陣的每個非零元素，包括行索引 <code>i</code>、列索引 <code>j</code> 以及元素的值 <code>data</code>。</li>
</ul>
<h2 id="調試過程">
<a class="header-anchor" href="#%e8%aa%bf%e8%a9%a6%e9%81%8e%e7%a8%8b"></a>
調試過程
</h2><ul>
<li>程式碼中有一些錯誤處理機制，例如檢查輸入是否合法，檢查記憶體分配是否成功，以及檢查矩陣相乘是否合法。</li>
<li>在輸入稀疏矩陣數據時，使用者會得到錯誤訊息並要求重新輸入，以確保輸入的數據符合矩陣的大小。</li>
<li>稀疏矩陣乘法演算法中，會檢查矩陣的列和行是否匹配，以確保它們可以相乘。</li>
</ul>
<h2 id="輸出結果">
<a class="header-anchor" href="#%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
輸出結果
</h2><p><img src="https://cdn.jsdelivr.net/gh/GuZhengSVT/Hugo-media/2023/12/1074652966.png" alt="Pasted image 20231020161652.png">
Matlab驗證結果：
<img src="https://cdn.jsdelivr.net/gh/GuZhengSVT/Hugo-media/2023/12/4226980695.png" alt="Pasted image 20231020161908.png">
<img src="https://cdn.jsdelivr.net/gh/GuZhengSVT/Hugo-media/2023/12/2855363853.png" alt="Pasted image 20231020161929.png"></p>
<p>使用者可以輸入兩個矩陣 A 和 B，然後程式會計算它們的乘積並輸出結果矩陣 C。使用者可以選擇繼續進行稀疏矩陣乘法計算，也可以選擇退出程式。程式會一直運行，直到使用者選擇退出。</p>
<h2 id="總結">
<a class="header-anchor" href="#%e7%b8%bd%e7%b5%90"></a>
總結
</h2><p>總體而言，該實驗成功實現了稀疏矩陣的乘法操作，提供了友好的使用者介面和錯誤處理機制，以確保輸入的矩陣數據是有效的。然後，它正確計算了兩個稀疏矩陣的乘積並將結果以標準矩陣的形式輸出。</p>
<h2 id="原始碼">
<a class="header-anchor" href="#%e5%8e%9f%e5%a7%8b%e7%a2%bc"></a>
原始碼
</h2><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cp">#include&lt;bits/stdc++.h&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 class="cp">#define MAX 1000
</span></span></span><span class="line"><span class="cl">
</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">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">j</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></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">matrix</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">m</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 class="kt">int</span> <span class="n">L</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">node</span><span class="o">*</span> <span class="n">Ma</span><span class="p">[</span><span class="n">MAX</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">int</span> <span class="nf">input</span><span class="p">(</span><span class="n">matrix</span><span class="o">*</span> <span class="n">A</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">m</span><span class="p">,</span><span class="n">n</span><span class="p">,</span><span class="n">data</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">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">L</span><span class="p">;</span><span class="n">i</span><span class="o">++</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">m</span><span class="o">&gt;&gt;</span><span class="n">n</span><span class="o">&gt;&gt;</span><span class="n">data</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">m</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">||</span><span class="n">m</span><span class="o">&gt;=</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">m</span><span class="o">||</span><span class="n">n</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">||</span><span class="n">n</span><span class="o">&gt;=</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">n</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;輸入錯誤,行/列超出矩陣大小!&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</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">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="p">(</span><span class="n">node</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">node</span><span class="p">));</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">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</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;申請空間失敗!&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="mi">2</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">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">i</span><span class="o">=</span><span class="n">m</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">j</span><span class="o">=</span><span class="n">n</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">=</span><span class="n">data</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="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><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">output</span><span class="p">(</span><span class="n">matrix</span><span class="o">*</span> <span class="n">A</span><span class="p">,</span><span class="n">string</span> <span class="n">name</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;矩陣&#34;</span><span class="o">&lt;&lt;</span><span class="n">name</span><span class="o">&lt;&lt;</span><span class="s">&#34;為:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">nums</span><span class="p">[</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">m</span><span class="p">][</span><span class="n">A</span><span class="o">-&gt;</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="n">memset</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="k">sizeof</span><span class="p">(</span><span class="n">nums</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">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">L</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">        <span class="n">nums</span><span class="p">[</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">i</span><span class="p">][</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</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">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">m</span><span class="p">;</span><span class="n">i</span><span class="o">++</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">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">n</span><span class="p">;</span><span class="n">j</span><span class="o">++</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">nums</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">&lt;&lt;</span><span class="sc">&#39;\t&#39;</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">endl</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></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">multiplier</span><span class="p">(</span><span class="n">matrix</span><span class="o">*</span> <span class="n">A</span><span class="p">,</span><span class="n">matrix</span><span class="o">*</span> <span class="n">B</span><span class="p">,</span><span class="n">matrix</span><span class="o">*</span> <span class="n">C</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">    <span class="n">C</span><span class="o">-&gt;</span><span class="n">m</span><span class="o">=</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">m</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">C</span><span class="o">-&gt;</span><span class="n">n</span><span class="o">=</span><span class="n">B</span><span class="o">-&gt;</span><span class="n">n</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">C</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">z</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">bool</span> <span class="n">sert</span><span class="o">=</span><span class="nb">false</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">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">L</span><span class="p">;</span><span class="n">i</span><span class="o">++</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">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">B</span><span class="o">-&gt;</span><span class="n">L</span><span class="p">;</span><span class="n">j</span><span class="o">++</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">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">j</span><span class="o">==</span><span class="n">B</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">i</span><span class="p">){</span><span class="c1">//A的列號==B的行號
</span></span></span><span class="line"><span class="cl">                <span class="n">x</span><span class="o">=</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">y</span><span class="o">=</span><span class="n">B</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">j</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">z</span><span class="o">=</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">*</span><span class="n">B</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">sert</span><span class="o">=</span><span class="nb">false</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">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">k</span><span class="o">&lt;</span><span class="n">C</span><span class="o">-&gt;</span><span class="n">L</span><span class="p">;</span><span class="n">k</span><span class="o">++</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">x</span><span class="o">==</span><span class="n">C</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">i</span><span class="o">&amp;&amp;</span><span class="n">y</span><span class="o">==</span><span class="n">C</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">j</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">                        <span class="n">C</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">+=</span><span class="n">z</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="n">sert</span><span class="o">=</span><span class="nb">true</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="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="o">!</span><span class="n">sert</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">                    <span class="n">C</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">C</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">C</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="p">(</span><span class="n">node</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">node</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">                    <span class="n">C</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">C</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">i</span><span class="o">=</span><span class="n">x</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">C</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">C</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">j</span><span class="o">=</span><span class="n">y</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">C</span><span class="o">-&gt;</span><span class="n">Ma</span><span class="p">[</span><span class="n">C</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">=</span><span class="n">z</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><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></span><span class="line"><span class="cl"><span class="nl">start</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">matrix</span><span class="o">*</span> <span class="n">A</span><span class="o">=</span><span class="p">(</span><span class="n">matrix</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">matrix</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">matrix</span><span class="o">*</span> <span class="n">B</span><span class="o">=</span><span class="p">(</span><span class="n">matrix</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">matrix</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">matrix</span><span class="o">*</span> <span class="n">C</span><span class="o">=</span><span class="p">(</span><span class="n">matrix</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">matrix</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;請輸入A矩陣三元組長度,矩陣行數,矩陣列數:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</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">A</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">&gt;&gt;</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">m</span><span class="o">&gt;&gt;</span><span class="n">A</span><span class="o">-&gt;</span><span class="n">n</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;請輸入A矩陣:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</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">input</span><span class="p">(</span><span class="n">A</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;出現錯誤,請重新輸入!&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">start</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">output</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="s">&#34;A&#34;</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;請輸入B矩陣三元組長度,矩陣行數,矩陣列數:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</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">B</span><span class="o">-&gt;</span><span class="n">L</span><span class="o">&gt;&gt;</span><span class="n">B</span><span class="o">-&gt;</span><span class="n">m</span><span class="o">&gt;&gt;</span><span class="n">B</span><span class="o">-&gt;</span><span class="n">n</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;請輸入B矩陣:&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</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">input</span><span class="p">(</span><span class="n">B</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;出現錯誤,請重新輸入!&#34;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">start</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">output</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="s">&#34;B&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">multiplier</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">B</span><span class="p">,</span><span class="n">C</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">output</span><span class="p">(</span><span class="n">C</span><span class="p">,</span><span class="s">&#34;C&#34;</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;是否繼續進行稀疏矩陣乘法計算(y/n):&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">choice</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nl">choise</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">choice</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">choice</span><span class="o">==</span><span class="sc">&#39;y&#39;</span><span class="o">||</span><span class="n">choice</span><span class="o">==</span><span class="sc">&#39;Y&#39;</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">start</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">choice</span><span class="o">==</span><span class="sc">&#39;n&#39;</span><span class="o">||</span><span class="n">choice</span><span class="o">==</span><span class="sc">&#39;N&#39;</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 class="k">else</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;輸入錯誤,請重新輸入:&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">choise</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">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>
        
        <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><item><title>資料結構上機實驗報告1——Fibonacci序列、劃分子集問題</title><link>https://www.guzhengsvt.cn/zh-tw/post/code/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8A%E6%9C%BA%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A1fibonacci%E5%BA%8F%E5%88%97%E5%88%92%E5%88%86%E5%AD%90%E9%9B%86%E9%97%AE%E9%A2%98/</link><pubDate>Tue, 12 Dec 2023 14:31:17 +0800</pubDate><author>lvbowen040427@163.com (孤筝)</author><guid>https://www.guzhengsvt.cn/zh-tw/post/code/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8A%E6%9C%BA%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A1fibonacci%E5%BA%8F%E5%88%97%E5%88%92%E5%88%86%E5%AD%90%E9%9B%86%E9%97%AE%E9%A2%98/</guid><description>
<![CDATA[<h1>資料結構上機實驗報告1——Fibonacci序列、劃分子集問題</h1><p>作者：孤筝（lvbowen040427@163.com）</p>
        
          <h2 id="費波那契數列">
<a class="header-anchor" href="#%e8%b2%bb%e6%b3%a2%e9%82%a3%e5%a5%91%e6%95%b8%e5%88%97"></a>
<strong>費波那契數列</strong>
</h2><h3 id="問題分析">
<a class="header-anchor" href="#%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90"></a>
<strong>問題分析</strong>
</h3><p>要正確實現程序的遞迴調用和返回，必須解決參數的傳遞和返回地址問題。具體地說，進行調用時，每遞迴一次都要給所有參變量重新分配儲存空間，並要把前一次調用的實參和本次調用後的返回地址保留。</p>
<h3 id="演算法設計">
<a class="header-anchor" href="#%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88"></a>
<strong>演算法設計</strong>
</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">int</span> <span class="nf">Fib</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">fib</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">n</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="n">fib</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">n</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span> <span class="n">fib</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">else</span> <span class="n">fib</span><span class="o">=</span><span class="n">Fib</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">Fib</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">fib</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="資料結構設計">
<a class="header-anchor" href="#%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88"></a>
<strong>資料結構設計</strong>
</h3><p>用堆疊去分配和管理儲存空間，系統在每次執行呼叫過程的語句時需要開闢一個「工作記錄」，用以保存呼叫前過程中所有參變數的值及呼叫後的返回位址，將此工作記錄存於堆疊中，以便在返回時能在堆疊頂端找到正確的資訊。</p>
<h3 id="除錯過程">
<a class="header-anchor" href="#%e9%99%a4%e9%8c%af%e9%81%8e%e7%a8%8b"></a>
<strong>除錯過程</strong>
</h3><p>在每次呼叫函數的時候，將傳入的參數進行輸出，可以更直觀地看到堆疊的呼叫過程。
以最開始Fib（2）的遞迴呼叫為例，程式先將Fib（5）、Fib（4）…Fib（1）儲存到堆疊中，當n==1時，將值返回上一個位址中，同理也將n==0時的值返回，這樣Fib（2）的值便有了，再返回到Fib（2）的上一個層級Fib（3）中。</p>
<h3 id="輸出結果">
<a class="header-anchor" href="#%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c"></a>
<strong>輸出結果</strong>
</h3><p><img src="https://cdn.jsdelivr.net/gh/GuZhengSVT/Hugo-media/2023/12/3648031837.png" alt="Pasted image 20231020121850.png"></p>
<h3 id="原始碼">
<a class="header-anchor" href="#%e5%8e%9f%e5%a7%8b%e7%a2%bc"></a>
原始碼
</h3><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cp">#include&lt;bits/stdc++.h&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="kt">int</span> <span class="nf">Fibonacci</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">fib</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">n</span><span class="o">==</span><span class="mi">0</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">        <span class="n">fib</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span><span class="k">else</span> <span class="k">if</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 class="n">fib</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 class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">n</span><span class="o">==</span><span class="mi">2</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">        <span class="n">fib</span><span class="o">=</span><span class="mi">2</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">fib</span><span class="o">=</span><span class="n">Fibonacci</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">Fibonacci</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</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">return</span> <span class="n">fib</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">int</span> <span class="nf">main</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="o">=</span><span class="mi">0</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;請輸入n:&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nl">start</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">cout</span><span class="o">&lt;&lt;</span><span class="s">&#34;第n個Fibonacci數為&#34;</span><span class="o">&lt;&lt;</span><span class="n">Fibonacci</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">endl</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;是否繼續計算(y/n):&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">choice</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nl">choice</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">choice</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">choice</span><span class="o">==</span><span class="sc">&#39;y&#39;</span><span class="o">||</span><span class="n">choice</span><span class="o">==</span><span class="sc">&#39;Y&#39;</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">start</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">choice</span><span class="o">==</span><span class="sc">&#39;n&#39;</span><span class="o">||</span><span class="n">choice</span><span class="o">==</span><span class="sc">&#39;N&#39;</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 class="k">else</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;輸入錯誤,請重新輸入:&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">choice</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">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="#%e5%8a%83%e5%88%86%e5%ad%90%e9%9b%86%e5%95%8f%e9%a1%8c"></a>
<strong>劃分子集問題</strong>
</h2><h3 id="問題分析-1">
<a class="header-anchor" href="#%e5%95%8f%e9%a1%8c%e5%88%86%e6%9e%90-1"></a>
<strong>問題分析</strong>
</h3><p>問題要求我們將一個集合中劃分成互不相交的子集，使任何子集上的元素無任何衝突，且劃分的子集數較少。此類問題常用在日程安排上。</p>
<h3 id="演算法設計-1">
<a class="header-anchor" href="#%e6%bc%94%e7%ae%97%e6%b3%95%e8%a8%ad%e8%a8%88-1"></a>
<strong>演算法設計</strong>
</h3><p>衝突關係首先透過一個二維陣列表示出來，有衝突關係則賦值1，無衝突則賦值0。透過循環篩選法對其劃分，即從第一個元素開始，先將元素1單獨拿出，逐個判斷其他元素是否和拿出的所有元素有衝突關係，無衝突則拿出元素，並劃為一組。這樣循環一周，所有互相無衝突關係的已被劃為一組，循環此操作，即可完成劃分要求。</p>
<h3 id="資料結構設計-1">
<a class="header-anchor" href="#%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b%e8%a8%ad%e8%a8%88-1"></a>
<strong>資料結構設計</strong>
</h3><p>透過一個循環佇列來儲存資料，每次循環一週，不斷迭代資料，不需要開闢新的儲存空間。</p>
<h3 id="除錯過程-1">
<a class="header-anchor" href="#%e9%99%a4%e9%8c%af%e9%81%8e%e7%a8%8b-1"></a>
<strong>除錯過程</strong>
</h3><h3 id="輸出結果-1">
<a class="header-anchor" href="#%e8%bc%b8%e5%87%ba%e7%b5%90%e6%9e%9c-1"></a>
<strong>輸出結果</strong>
</h3><p><img src="https://cdn.jsdelivr.net/gh/GuZhengSVT/Hugo-media/2023/12/3486074357.png" alt="Pasted image 20231020123220.png"></p>
<h3 id="原始碼-1">
<a class="header-anchor" href="#%e5%8e%9f%e5%a7%8b%e7%a2%bc-1"></a>
原始碼
</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;bits/stdc++.h&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 class="kt">int</span> <span class="n">newr</span><span class="p">[</span><span class="mi">9</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">DivideIntoGroup</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">,</span><span class="kt">int</span> <span class="n">R</span><span class="p">[][</span><span class="mi">9</span><span class="p">],</span><span class="kt">int</span> <span class="n">cp</span><span class="p">[],</span><span class="kt">int</span> <span class="n">result</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="kt">int</span> <span class="n">front</span><span class="p">,</span><span class="n">rear</span><span class="p">,</span><span class="n">group</span><span class="p">,</span><span class="n">pre</span><span class="p">,</span><span class="n">I</span><span class="p">,</span><span class="n">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">front</span><span class="o">=</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 class="n">rear</span><span class="o">=</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 class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span><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></span><span class="line"><span class="cl">        <span class="n">newr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">cp</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">i</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">group</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pre</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">front</span><span class="o">=</span><span class="p">(</span><span class="n">front</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">n</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">I</span><span class="o">=</span><span class="n">cp</span><span class="p">[</span><span class="n">front</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">I</span><span class="o">&lt;</span><span class="n">pre</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">group</span><span class="o">=</span><span class="n">group</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">result</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="o">=</span><span class="n">group</span><span class="p">;</span>
</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">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span><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></span><span class="line"><span class="cl">                <span class="n">newr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">R</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="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="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</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">newr</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="o">!=</span><span class="mi">0</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">rear</span><span class="o">=</span><span class="p">(</span><span class="n">rear</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">n</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">cp</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="o">=</span><span class="n">I</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">else</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">result</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="o">=</span><span class="n">group</span><span class="p">;</span>
</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">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span><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></span><span class="line"><span class="cl">                    <span class="n">newr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">+=</span><span class="n">R</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="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><span class="line"><span class="cl">        <span class="n">pre</span><span class="o">=</span><span class="n">I</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span><span class="k">while</span><span class="p">(</span><span class="n">rear</span><span class="o">!=</span><span class="n">front</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="kt">int</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">result</span><span class="p">[</span><span class="mi">9</span><span class="p">],</span><span class="n">cp</span><span class="p">[</span><span class="mi">9</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">R</span><span class="p">[</span><span class="mi">9</span><span class="p">][</span><span class="mi">9</span><span class="p">]</span><span class="o">=</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 class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</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="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</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="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</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="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</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="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</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="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</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="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">DivideIntoGroup</span><span class="p">(</span><span class="mi">9</span><span class="p">,</span><span class="n">R</span><span class="p">,</span><span class="n">cp</span><span class="p">,</span><span class="n">result</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">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="mi">9</span><span class="p">;</span><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></span><span class="line"><span class="cl">        <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">i</span><span class="o">+</span><span class="mi">1</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">cout</span><span class="o">&lt;&lt;</span><span class="n">endl</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">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="mi">9</span><span class="p">;</span><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></span><span class="line"><span class="cl">        <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">]</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="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>
        
        <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>