13465 lines
1.3 MiB
13465 lines
1.3 MiB
<?xml version="1.0" encoding="utf-8"?>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
|
||
<channel>
|
||
<title>飞鸿踏雪</title>
|
||
<link>http://www.inksoul.top/</link>
|
||
<description>飞鸿踏雪是一个个人小站,记录分享个人的学习历程</description>
|
||
<generator>Hugo 0.113.0 https://gohugo.io/</generator>
|
||
|
||
<language>zh-CN</language>
|
||
|
||
|
||
<managingEditor>qingci30@163.com (InkSoul)</managingEditor>
|
||
|
||
|
||
<webMaster>qingci30@163.com (InkSoul)</webMaster>
|
||
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<lastBuildDate>Sun, 18 Jun 2023 23:27:18 +0800</lastBuildDate>
|
||
|
||
<atom:link rel="self" type="application/rss+xml" href="http://www.inksoul.top/rss.xml" />
|
||
|
||
|
||
<item>
|
||
<title>《操作系统》操作系统发展历程</title>
|
||
<link>http://www.inksoul.top/408/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%8F%91%E5%B1%95%E5%8E%86%E7%A8%8B/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/408/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%8F%91%E5%B1%95%E5%8E%86%E7%A8%8B/</guid>
|
||
<pubDate>Thu, 29 Dec 2022 20:53:40 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="手工操作阶段">手工操作阶段</h3>
|
||
<p>用户在计算机上的所有计算流程都要人工干预</p>
|
||
<p>缺点:</p>
|
||
<ol>
|
||
<li>用户独占全机,虽然不会出现因资源已被用户占用而等待的现象,但资源利用率极低</li>
|
||
<li>CPU等待手工操作,CPU利用不充分</li>
|
||
</ol>
|
||
<h3 id="批处理阶段">批处理阶段</h3>
|
||
<h4 id="单道批处理系统">单道批处理系统</h4>
|
||
<p>主要在解决人机矛盾及CPU和I/O设备不匹配的问题</p>
|
||
<p>特征:</p>
|
||
<ol>
|
||
<li>自动性,顺利的情况下,同一磁带上的同一批作业能够自动逐个运行</li>
|
||
<li>顺序性,磁带上的各道作业顺序地进入内存</li>
|
||
<li>单道性,内存中仅有一道程序运行</li>
|
||
</ol>
|
||
<h4 id="多道批处理系统">多道批处理系统</h4>
|
||
<p>多道程序设计的特点是多道、宏观上并行,微观上串行</p>
|
||
<ol>
|
||
<li>多道。计算机内存中同时存放多道相互独立的程序</li>
|
||
<li>宏观上并行。同时进入系统的多道程序都出于运行过程中,即先后开始各自运行但都未运行完毕</li>
|
||
<li>微观上串行。内存中的多道程序轮流占有CPU,交替执行</li>
|
||
</ol>
|
||
<p>优点:</p>
|
||
<p>资源利用率高,多道程序共享计算机资源,从而使各种资源得到充分利用;系统吞吐量打,CPU和其他资源保持“忙碌”状态</p>
|
||
<p>缺点:</p>
|
||
<p>用户响应时间较长;不提供人机交互能力,用户既不能了解自己的程序的运行情况,又不能控制计算机</p>
|
||
<h3 id="分时操作系统">分时操作系统</h3>
|
||
<p>分时操作系统是指多个用户通过终端同时共享一台主机,用户可以同时与主机进行交互操作而互不干扰</p>
|
||
<p>特征:</p>
|
||
<ol>
|
||
<li>同时性</li>
|
||
<li>交互性,用户能够方便进行人机对话</li>
|
||
<li>独立性,多个用户可以彼此独立地进行操作</li>
|
||
<li>及时性,用户请求能在很短的时间内响应</li>
|
||
</ol>
|
||
<h3 id="实时操作系统">实时操作系统</h3>
|
||
<p>根据响应时间限制分为两种:</p>
|
||
<ol>
|
||
<li>硬实时系统:某个动作必须绝对地在规定的时刻发生</li>
|
||
<li>软实时系统:能够接受偶尔违反时间规定的情况且不会引起任何永久性的损害</li>
|
||
</ol>
|
||
<p>特点:</p>
|
||
<ol>
|
||
<li>及时性</li>
|
||
<li>可靠性</li>
|
||
</ol>
|
||
<h3 id="网络操作系统和分布式计算机系统">网络操作系统和分布式计算机系统</h3>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/408/">408\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>《数学一》公式大全</title>
|
||
<link>http://www.inksoul.top/mathematics/%E5%85%AC%E5%BC%8F%E5%A4%A7%E5%85%A8/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/mathematics/%E5%85%AC%E5%BC%8F%E5%A4%A7%E5%85%A8/</guid>
|
||
<pubDate>Sat, 24 Dec 2022 13:05:40 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h1 id="高等数学">高等数学</h1>
|
||
<h2 id="函数极限连续">函数,极限,连续</h2>
|
||
<h3 id="函数">函数</h3>
|
||
<h4 id="函数的定义">函数的定义</h4>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/mathematics/">mathematics\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>《数据结构》线性表</title>
|
||
<link>http://www.inksoul.top/408/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%BA%BF%E6%80%A7%E8%A1%A8/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/408/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%BA%BF%E6%80%A7%E8%A1%A8/</guid>
|
||
<pubDate>Wed, 16 Nov 2022 21:53:40 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h2 id="线性表的定义和操作">线性表的定义和操作</h2>
|
||
<h3 id="定义">定义</h3>
|
||
<p>线性表是具有相同数据类型的$n (n \leq 0 )$ 个元素的有限序列,其中$n$为表长,当 $n = 0$时线性表为一个空表</p>
|
||
<p>若用$L$来命名线性表,则其一般表示为 $L=(a_1,a_2,\cdots,a_i,a_(i+1),\cdots,a_n)$ 式中,$ a_1 $是唯一的“第一个”数据元素,即表头元素;$a_n$是唯一的“最后一个”数据元素,即表尾元素</p>
|
||
<p>线性表的逻辑特性:每个元素有且仅有一个直接前驱。除去最后一个元素外,每个元素有且仅有一个直接后继,这种逻辑特性即为线性表的名称由来</p>
|
||
<p>线性表的特点:</p>
|
||
<ul>
|
||
<li>表中元素个数有限</li>
|
||
<li>表中元素具有逻辑上的顺序性,表中元素有其先后次序</li>
|
||
<li>表中元素都是数据元素,每个元素都是单个元素</li>
|
||
<li>表中元素的数据类型都相同,意味着每个元素占有的存储空间相同</li>
|
||
<li>表中元素具有抽象性,仅讨论元素间的逻辑关系,而忽视元素的实际内容</li>
|
||
</ul>
|
||
<h3 id="基本操作">基本操作</h3>
|
||
<ul>
|
||
<li>InitList(&amp;L):初始化表。构造一个空的线性表</li>
|
||
<li>Length(L):求表长。返回线性表L的长度,即L中数据元素的个数</li>
|
||
<li>LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素</li>
|
||
<li>GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值</li>
|
||
<li>ListInsert(&amp;L,i,&amp;e):插入操作。在表L中第i个位置插入指定元素e</li>
|
||
<li>ListDelete(&amp;L,i,&amp;e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值</li>
|
||
<li>PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值</li>
|
||
<li>Empty(L):判空操作。若L为空表,则返回true</li>
|
||
<li>DestroyList:销毁操作。销毁线性表,并释放线性表L所占用的内存空间</li>
|
||
</ul>
|
||
<h2 id="线性表的顺序表示顺序表">线性表的顺序表示(顺序表)</h2>
|
||
<h3 id="定义-1">定义</h3>
|
||
<p>顺序表,即线性表的顺序存储。是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。</p>
|
||
<p>第一个元素存储在线性表的起始位置,第i个元素的存储位置后面紧接着存储的是$i + 1$个元素,称$i$为元素$a_i$在线性表中的位序,因此可见,顺序表的特点是表中元素的逻辑顺序与其物理顺序相同</p>
|
||
<p>假设线性表L存储的起始位置为LOC(A),sizeof(ElemType)为每个数据元素所占用存储空间的大小,可得该表对应的顺序存储如下</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th style="text-align:center">数组下标</th>
|
||
<th style="text-align:center">顺序表</th>
|
||
<th style="text-align:center">内存地址</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td style="text-align:center">0</td>
|
||
<td style="text-align:center">$a_1$</td>
|
||
<td style="text-align:center">LOC(A)</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">1</td>
|
||
<td style="text-align:center">$a_2$</td>
|
||
<td style="text-align:center">LOC(A) + sizeof(ElemType)</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">i-1</td>
|
||
<td style="text-align:center">$a_i$</td>
|
||
<td style="text-align:center">LOC(A) + (i-1)$\times$sizeof(ElemType)</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">n-1</td>
|
||
<td style="text-align:center">$a_n$</td>
|
||
<td style="text-align:center">LOC(A) + (n-1)$\times$sizeof(ElemType)</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">MaxSize - 1</td>
|
||
<td style="text-align:center">$\cdots$</td>
|
||
<td style="text-align:center">LOC(A) + (MaxSize - 1)$\times$sizeof(ElemType)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>每个数据元素的存储位置和线性表的起始位置相差一个和该数据元素的位序成正比的常数,因此,线性表中的任一数据元素都可以随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构</p>
|
||
<ul>
|
||
<li>Attention : 线性表中元素的位序从1开始,而数组中元素下标是从0开始的</li>
|
||
</ul>
|
||
<p>假定线性表的元素类型为ElemType,则线性表的顺序存储类型可描述为:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-C++" data-lang="C++"><span class="line"><span class="cl"><span class="cp">#define MaxSize 50 </span><span class="c1">//定义线性表最大长度
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">typedef</span> <span class="k">struct</span><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ElemType</span> <span class="n">data</span><span class="p">[</span><span class="n">MaxSize</span><span class="p">];</span> <span class="c1">//顺序表的元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">int</span> <span class="n">length</span><span class="p">;</span> <span class="c1">//顺序表的当前长度
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="n">SqList</span><span class="p">;</span> <span class="c1">//顺序表的类型定义
|
||
</span></span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>一组数组可以是静态分配的,也可以是动态分配的</p>
|
||
<ol>
|
||
<li>静态分配时,由于数组的大小和空间已经固定,一旦空间占满,再加入新的数据就会产生溢出,进而导致程序崩溃</li>
|
||
<li>动态分配时,存储数组的空间是在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满就另外开辟一块更大的存储空间用以替换原来的存储空间,从而扩充存储数组空间的目的,不需要为线性表一次性划分所有空间</li>
|
||
</ol>
|
||
<p>动态分配的顺序存储类型定义:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cp">#define InitSize 100 </span><span class="c1">//表长度的初始定义
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">typedef</span> <span class="k">struct</span><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ElemType</span> <span class="o">*</span><span class="n">data</span><span class="p">;</span> <span class="c1">//指示动态分配数组的指针
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">int</span> <span class="n">MaxSize</span><span class="p">,</span><span class="n">length</span><span class="p">;</span> <span class="c1">//数组的最大容量和当前个数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="n">SeqList</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C的初始动态分配语句为:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">L</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">(</span><span class="n">ElemType</span><span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">ElemType</span><span class="p">)</span><span class="o">*</span><span class="n">InitSize</span><span class="p">);</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++的初始动态分配语句为:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-C++" data-lang="C++"><span class="line"><span class="cl"><span class="n">L</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ElemType</span><span class="p">[</span><span class="n">InitSize</span><span class="p">];</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ul>
|
||
<li>Attention : 动态分配并非链式存储,同样属于顺序存储结构,物理结构无变化,依然为随机存储方式,只是分配的空间大小可以在运行时动态决定</li>
|
||
<li>顺序表主要特点是随机访问,即通过首地址和元素序号可以在时间$O(1)$内找到指定元素</li>
|
||
<li>顺序表存储密度相对更高,结点只存储数据元素</li>
|
||
<li>顺序表逻辑上相邻的元素物理上也相邻,所以在插入和删除时需要移动大量元素</li>
|
||
</ul>
|
||
<h3 id="顺序表基本操作的实现">顺序表基本操作的实现</h3>
|
||
<h4 id="插入">插入</h4>
|
||
<p>在顺序表L的第$i(1&lt;=i&lt;=L.length+1)$个位置插入新元素e。若i的输入不合法,则返回false,表示插入失败;否则,将第i个元素及其以后的所有元素依次往后移动一个位置,腾出一个位置插入新元素e,顺序表长度+1,插入成功,返回true</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">ListInsert</span><span class="p">(</span><span class="n">SqList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">e</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="mi">1</span><span class="o">||</span><span class="n">i</span><span class="o">&gt;</span><span class="n">L</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="k">return</span> <span class="nb">false</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">L</span><span class="p">.</span><span class="n">length</span><span class="o">&gt;=</span><span class="n">MaxSize</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</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">j</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="p">;</span><span class="n">j</span><span class="o">&gt;=</span><span class="n">i</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">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</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="n">L</span><span class="p">.</span><span class="n">data</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">e</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">++</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ul>
|
||
<li>最好情况:在表尾插入(即$i=n+1$),元素后移语句不执行,时间复杂度为$O(1)$</li>
|
||
<li>最坏情况:在表头插入(即$i=1$),元素后移语句将执行n次,时间复杂度为$O(n)$</li>
|
||
<li>平均情况:假设$p_i(p_i=1/(n+1))$是在第$i$个位置上插入一个结点的概率,则在长度为$n$的线性表中插入一个结点时,所需移动结点的平均次数为</li>
|
||
</ul>
|
||
<p>$$
|
||
\sum_{i=1}^{n+1} p_i(n-i+1) = \sum_{i=1}^{n+1} \frac{1}{n+1}(n-i+1)=\frac{1}{n+1}\sum_{i=1}^{n+1}(n-i+1)=\frac{1}{n+1}\frac{n(n+1)}{2}=\frac{n}{2}
|
||
$$</p>
|
||
<p>由此可得,线性表插入算法的平均时间复杂度为$O(n)$</p>
|
||
<h4 id="删除">删除</h4>
|
||
<p>删除顺序表L中第$i$个$(1&lt;=i&lt;=L.length)$个位置的元素,用引用变量e返回。若i的输入不合法,则返回false;否则,将被删元素赋给引用变量e,并将第$i+1$个元素及其后的所有元素依次往前移动一个位置,返回true。</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span><span class="lnt">7
|
||
</span><span class="lnt">8
|
||
</span><span class="lnt">9
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">ListDelete</span><span class="p">(</span><span class="n">SqList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="n">Elemtype</span> <span class="o">&amp;</span><span class="n">e</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="mi">1</span><span class="o">||</span><span class="n">i</span><span class="o">&gt;</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="p">)</span> <span class="c1">//判断i的范围是否有效
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">e</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</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="c1">//将被删除的元素赋值给e
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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="n">i</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span><span class="c1">//将第i个位置后的元素后移
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">--</span><span class="p">;</span> <span class="c1">//线性表长度减一
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ul>
|
||
<li>最好情况:删除表尾元素(即$i=n$),无须移动元素,时间复杂度为$O(1)$</li>
|
||
<li>最坏情况:删除表头元素(即$i=1$),需移动除表头元素外的所有元素,时间复杂度为$O(n)$</li>
|
||
<li>平均情况:假设$p_i(p_i = 1/n)$是删除第i个位置上结点的概率,则在长度为n的线性表中删除一个结点时,所需移动结点的平均次数为</li>
|
||
</ul>
|
||
<p>$$
|
||
\sum_{i=1}^{n} p_i(n-i)=\sum_{i=1}^{n} \frac{1}{n}(n-i) = \frac{1}{n}\sum_{i=1}^{n}(n-i) = \frac{1}{n}\frac{n(n-1)}{2} = \frac{n-1}{2}
|
||
$$</p>
|
||
<p>可见线性表删除算法的平均时间复杂度为$O(n)$且顺序表中插入和删除操作的时间主要耗费在移动元素上,而移动元素的个数取决于插入和删除元素的位置。</p>
|
||
<h4 id="按值查找顺序查找">按值查找(顺序查找)</h4>
|
||
<p>在顺序表L中查找第一个元素值等于e的元素,并返回其位序</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span><span class="lnt">7
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">LocateElem</span><span class="p">(</span><span class="n">SqList</span> <span class="n">L</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">e</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="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">L</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="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">==</span><span class="n">e</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="c1">//下标为i的元素值等于e,返回其位序i+1
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">//退出循环,说明查找失败
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ul>
|
||
<li>最好情况:查找的元素就在表头,仅需比较一次,时间复杂度为$O(1)$</li>
|
||
<li>最坏情况:查找的元素在表尾或不存在时,需要比较n次,时间复杂度为$O(n)$</li>
|
||
<li>平均情况:假设$p_i(p_i=1/n)$是查找的元素在第$i(l&lt;=i&lt;=L.length)$个位置上的概率,则在长度为n的线性表中查找值为e的元素所需比较的平均次数为</li>
|
||
</ul>
|
||
<p>$$
|
||
\sum_{i=1}^{n}p_i \times i = \sum_{i=1}^{n} \frac{1}{n} \times i = \frac{1}{n} \frac{n(n+1)}{2} = \frac{n+1}{2}
|
||
$$</p>
|
||
<p>因此线性表按值查找算法的平均时间复杂度为$O(n)$</p>
|
||
<h3 id="一些练习">一些练习</h3>
|
||
<ol>
|
||
<li>从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行</li>
|
||
</ol>
|
||
<p>算法思想:搜索整个顺序表,查找最小值元素并记住其位置,搜索结束后用最后一个元素填补空出的原最小值元素的位置</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">Del_Min</span><span class="p">(</span><span class="n">sqList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="n">ElemType</span> <span class="o">&amp;</span><span class="n">value</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//删除顺序表L中最小值元素结点,并通过引用型参数value返回其值
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">//若删除成功,则返回true,否则返回false
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">.</span><span class="n">length</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">return</span> <span class="nb">false</span><span class="p">;</span><span class="c1">//表空,中止操作
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">value</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</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">pos</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="c1"></span> <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">L</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="p">)</span> <span class="c1">//循环,寻找具有最小值的元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&lt;</span><span class="n">value</span><span class="p">){</span> <span class="c1">//让value记忆当前具有最小值的元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">value</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</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">pos</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="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">L</span><span class="p">.</span><span class="n">length</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="c1"></span> <span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">--</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="2">
|
||
<li>设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为$O(1)$</li>
|
||
</ol>
|
||
<p>算法思想:扫描顺序表L的前半部分元素,对于元素L.data<a href="0%3C=i%3CL.length/2">i</a>,将其与后半部分的对应元素L.data[L.length-i-1]进行交换</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span><span class="lnt">7
|
||
</span><span class="lnt">8
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">Reverse</span><span class="p">(</span><span class="n">Sqlist</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Elemtype</span> <span class="n">temp</span><span class="p">;</span> <span class="c1">//辅助变量
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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">L</span><span class="p">.</span><span class="n">length</span><span class="o">/</span><span class="mi">2</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">temp</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</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">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">L</span><span class="p">.</span><span class="n">length</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="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">-</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">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="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="3">
|
||
<li>对长度为n的顺序表L,编写一个时间复杂度为$O(n)$、空间复杂度为$O(1)$的算法,该算法删除线性表中所有值为x的数据元素</li>
|
||
</ol>
|
||
<p>解法一:用k记录顺序表L中不等于x的元素个数(即需要保存的元素个数),边扫描L边统计k,并将不等于x的元素向前移动k个位置,最后修改L的长度</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span><span class="lnt">7
|
||
</span><span class="lnt">8
|
||
</span><span class="lnt">9
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">del_x_1</span><span class="p">(</span><span class="n">Sqlist</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="n">Elemtype</span> <span class="n">x</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1">//记录值不等于x的元素个数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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">L</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="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</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">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</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">k</span><span class="o">++</span><span class="p">;</span> <span class="c1">//不等于x的元素增一
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">=</span><span class="n">k</span><span class="p">;</span> <span class="c1">//顺序表L的长度等于k
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>解法二:用k记录顺序表L中等于x的元素个数,边扫描L边统计k,并将不等于x的元素前移k个位置,最后修改L的长度</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">del_x_2</span><span class="p">(</span><span class="n">Sqlist</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="n">Elemtype</span> <span class="n">x</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <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">i</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">while</span><span class="p">(</span><span class="n">i</span><span class="o">&lt;</span><span class="n">L</span><span class="p">.</span><span class="n">length</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">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</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">k</span><span class="o">++</span><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="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="n">k</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="c1">//当前元素前移k个位置
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">L</span><span class="p">.</span><span class="n">length</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">-</span><span class="n">k</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="4">
|
||
<li>从有序顺序表中删除其值在给定值s与t之间(包含s和t,要求s&lt;t)的所有元素,若s或t不合理或顺序表为空,则显示出错信息退出运行</li>
|
||
</ol>
|
||
<p>算法思想:因为是有序表,所以删除的部分必定是一个整体,先寻找值大于等于s的一个元素(第一个删除的元素),然后寻找值大于t的第一个元素(最后一个删除的元素的下一个元素),要将这段元素删除,只需将后面的元素前移</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">del_s_t2</span><span class="p">(</span><span class="n">SqList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">s</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">t</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">j</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">s</span><span class="o">&gt;=</span><span class="n">t</span><span class="o">||</span><span class="n">L</span><span class="p">.</span><span class="n">length</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">return</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="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">L</span><span class="p">.</span><span class="n">length</span><span class="o">&amp;&amp;</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&lt;</span><span class="n">s</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">i</span><span class="o">&gt;=</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</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="n">j</span><span class="o">=</span><span class="n">i</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">&amp;&amp;</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">&lt;=</span><span class="n">t</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">for</span><span class="p">(</span><span class="n">j</span><span class="o">&lt;</span><span class="n">L</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="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">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">=</span><span class="n">i</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="5">
|
||
<li>从顺序表中删除其值在给定值s与t之间(包含s和t,s&lt;t)的所有元素,若s或t不合理或顺序表为空,则显示出错信息并退出运行</li>
|
||
</ol>
|
||
<p>算法思想:从前向后扫描顺序表L,用k记录下元素值在s到t之间元素的个数(初始时k=0)。对于当前扫描的元素,若起值不在s到t之间,则前移k个位置,否则执行k++。由于这样每个不在s到t之间的元素仅移动一次,因此算法的效率高</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">Del_s_t</span><span class="p">(</span><span class="n">SqList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">s</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">t</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">k</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">if</span><span class="p">(</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">==</span><span class="mi">0</span><span class="o">||</span><span class="n">s</span><span class="o">&gt;=</span><span class="n">t</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="c1">//线性表为空或s,t不合法
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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">L</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="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&gt;=</span><span class="n">s</span><span class="o">&amp;&amp;</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&lt;=</span><span class="n">t</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">k</span><span class="o">++</span><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="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="n">k</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="c1">//当前元素前移k个位置
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="o">-=</span><span class="n">k</span><span class="p">;</span> <span class="c1">//长度减小
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="6">
|
||
<li>从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同</li>
|
||
</ol>
|
||
<p>算法思想:有序顺序表,因此值相同的元素一定在连续的位置上,用类似于直接插入排序的思想,初始时将第一个元素视为非重复的有序表,之后依次判断后面的元素是否与前面非重复有序表的最后一个元素相同,若相同,则继续向后判断,若不同,则插入前面的非重复有序表的最后,知道判断到表为为止</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">Delete_Same</span><span class="p">(</span><span class="n">SeqList</span><span class="o">&amp;</span> <span class="n">L</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">L</span><span class="p">.</span><span class="n">length</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">return</span> <span class="nb">false</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">j</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">j</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">L</span><span class="p">.</span><span class="n">length</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="c1">//i存储第一个不相同的元素,j为工作指针
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">!=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">])</span> <span class="c1">//查找下一个与上个元素值不同的元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="o">++</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">L</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">];</span><span class="c1">//查找到后,将元素前移
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">L</span><span class="p">.</span><span class="n">length</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="k">return</span> <span class="nb">true</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></td></tr></table>
|
||
</div>
|
||
</div><ol start="7">
|
||
<li>将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表</li>
|
||
</ol>
|
||
<p>算法思想:首先,按顺序不断取下两个顺序表表头较小的结点存入新的顺序表中,然后,看哪个表还有剩余,将剩下的部分加到新的顺序表后面</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">Merge</span><span class="p">(</span><span class="n">SqList</span> <span class="n">A</span><span class="p">,</span><span class="n">SeqList</span> <span class="n">B</span><span class="p">,</span><span class="n">SeqList</span> <span class="o">&amp;</span><span class="n">C</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="p">.</span><span class="n">length</span><span class="o">+</span><span class="n">B</span><span class="p">.</span><span class="n">length</span><span class="o">&gt;</span><span class="n">C</span><span class="p">.</span><span class="n">maxSize</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">false</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="o">=</span><span class="mi">0</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="n">k</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">while</span><span class="p">(</span><span class="n">i</span><span class="o">&lt;</span><span class="n">A</span><span class="p">.</span><span class="n">length</span><span class="o">&amp;&amp;</span><span class="n">B</span><span class="p">.</span><span class="n">length</span><span class="p">){</span> <span class="c1">//循环,两两比较,小者存入结果表
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&lt;=</span><span class="n">B</span><span class="p">.</span><span class="n">data</span><span class="p">[</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="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="p">.</span><span class="n">data</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">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">C</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="o">=</span><span class="n">B</span><span class="p">.</span><span class="n">data</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="p">}</span>
|
||
</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">A</span><span class="p">.</span><span class="n">length</span><span class="p">)</span> <span class="c1">//还剩一个没有比较完的顺序表
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">C</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="p">.</span><span class="n">data</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">while</span><span class="p">(</span><span class="n">j</span><span class="o">&lt;</span><span class="n">B</span><span class="p">.</span><span class="n">length</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">C</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="o">=</span><span class="n">B</span><span class="p">.</span><span class="n">data</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">C</span><span class="p">.</span><span class="n">length</span><span class="o">=</span><span class="n">k</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="8">
|
||
<li>已知在一位数组A[m+n]中一次存放两个线性表$(a_1,a_2,a_3,\cdots,a_m)$和$(b_1,b_2,b_3,\cdots,b_n)$。试编写一个函数,将数组中两个顺序表的位置互换,即将$(a_1,a_2,a_3,\cdots,\a_m$放在$(b_1,b_2,b_3,\cdots,b_n)$后面</li>
|
||
</ol>
|
||
<p>算法思想:先将数组A[m+n]中的全部元素$(a_1,a_2,a_3,\cdots,a_m,b_1,b_2,b_3,\cdots,b_n)$原地逆置为$(b_n,b_{n-1},b_{n-2},\cdots,b_1,a_m,a_{m-1},a_{m-2},\cdots,a_1)$,再对前n个元素和后m个元素分别使用逆置算法,即可得到$(b_1,b_2,b_3,\cdots,b_n,a_1,a_2,a_3,\cdots,a_m)$,从而实现顺序表的位置互换</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="kt">int</span> <span class="n">DataType</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">Reverse</span><span class="p">(</span><span class="n">DataType</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">left</span><span class="p">,</span><span class="kt">int</span> <span class="n">right</span><span class="p">,</span><span class="kt">int</span> <span class="n">arraySize</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">left</span><span class="o">&gt;=</span><span class="n">right</span><span class="o">||</span><span class="n">right</span><span class="o">&gt;=</span><span class="n">arraySize</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="kt">int</span> <span class="n">mid</span><span class="o">=</span><span class="p">(</span><span class="n">left</span><span class="o">+</span><span class="n">right</span><span class="p">)</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">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">mid</span><span class="o">-</span><span class="n">left</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">Datatype</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">left</span><span class="o">+</span><span class="n">i</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">A</span><span class="p">[</span><span class="n">left</span><span class="o">+</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="p">[</span><span class="n">right</span><span class="o">-</span><span class="n">i</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">A</span><span class="p">[</span><span class="n">right</span><span class="o">-</span><span class="n">i</span><span class="p">]</span><span class="o">=</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="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">Exchange</span><span class="p">(</span><span class="n">DataType</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">m</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">arraySize</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Reverse</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">m</span><span class="o">+</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">arraySize</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Reverse</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="mi">0</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">arraySize</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Reverse</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">n</span><span class="p">,</span><span class="n">m</span><span class="o">+</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">arraySize</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="9">
|
||
<li>线性表$(a_1,a_2,a_3,\cdots,a_n)$中的元素递增有序且安顺序存储于计算机内,要求设计一个算法,完成用最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置相交换,若找不到,则将其插入表中并使表中元素仍递增有序</li>
|
||
</ol>
|
||
<p>算法思想:顺序存储的线性表递增有序,可以顺序查找,也可以折半查找,题目要求&quot;用最少的时间在表中查找数值为x的元素&quot;,这里应使用折半查找法</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">SearchExchangeInsert</span><span class="p">(</span><span class="n">EkemType</span> <span class="n">A</span><span class="p">[],</span><span class="n">ElemType</span> <span class="n">x</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">low</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span><span class="n">high</span><span class="o">=</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">mid</span><span class="p">;</span> <span class="c1">//low和high指向顺序表的上界和下界的下标
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">while</span><span class="p">(</span><span class="n">low</span><span class="o">&lt;=</span><span class="n">high</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">mid</span> <span class="o">=</span> <span class="p">(</span><span class="n">low</span><span class="o">+</span><span class="n">high</span><span class="p">)</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="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">mid</span><span class="p">]</span><span class="o">==</span><span class="n">x</span><span class="p">)</span> <span class="c1">//找到x,退出while循环
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">break</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">A</span><span class="p">[</span><span class="n">mid</span><span class="p">]</span><span class="o">&lt;</span><span class="n">x</span><span class="p">)</span> <span class="c1">//到中点mid的右半部去查找
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">low</span><span class="o">=</span><span class="n">mid</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="c1">//到中点mid的左半部去查
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">high</span><span class="o">=</span><span class="n">mid</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">A</span><span class="p">[</span><span class="n">mid</span><span class="p">]</span><span class="o">==</span><span class="n">x</span><span class="o">&amp;&amp;</span><span class="n">mid</span><span class="o">!=</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">){.</span> <span class="c1">//若最后一个元素与x相等,则不存在与其后继交换的操作
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">t</span><span class="o">=</span><span class="n">A</span><span class="p">[</span><span class="n">mid</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">A</span><span class="p">[</span><span class="n">mid</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="p">[</span><span class="n">mid</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">A</span><span class="p">[</span><span class="n">mid</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">t</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">low</span><span class="o">&gt;</span><span class="n">high</span><span class="p">){</span> <span class="c1">//查找失败,插入数据元素x
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="n">n</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="n">high</span><span class="p">;</span><span class="n">i</span><span class="o">--</span><span class="p">)</span> <span class="c1">//后移元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">A</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">A</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">A</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">x</span><span class="p">;</span> <span class="c1">//插入x
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="10">
|
||
<li>设将$n(n&gt;1)$个整数存放到一维数组R中,设计一个在时间和空间两方面都尽可能高效的算法,将R中保存的序列循环左移$p(0&lt;p&lt;n)$个位置,即将R中的数据由$(X_0,X_1,X_2,\cdots,X_{n-1})$变换为$(X_p,X_{p+1},\cdots,X_{n-1},X_0,X_1,\cdots,X_{p-1})$。要求:</li>
|
||
</ol>
|
||
<p>1)给出算法设计思想</p>
|
||
<p>算法的基本设计思想:可将这个问题视为吧数组ab转换成数组ba(a代表数组的前p个元素,b代表数组中余下的n-p个元素),先将a逆置得到$a^{-1}b$,再将b逆置得到$a^{-1}b^{-1}$,最后将整个$a^{-1}b^{-1}$逆置得到$(a^{-1}b^{-1})^{-1}=ba$。设Reverse函数执行将数组元素逆置的操作,对abcdefgh向左循环移动3个位置的过程如下:</p>
|
||
<pre><code>Reverse(0,p-1);得到cbadefgh
|
||
|
||
Reverse(p,p-1);得到cbahgfed;
|
||
|
||
Reverse(0,p-1);得到defghabc;
|
||
</code></pre>
|
||
<p>2)采用C或C++或java语言描述算法,关键之处给出注释</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">Reverse</span><span class="p">(</span><span class="kt">int</span> <span class="n">R</span><span class="p">[],</span><span class="kt">int</span> <span class="n">from</span><span class="p">,</span><span class="kt">int</span> <span class="n">to</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">temp</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="p">(</span><span class="n">to</span><span class="o">-</span><span class="n">from</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</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">temp</span><span class="o">=</span><span class="n">R</span><span class="p">[</span><span class="n">from</span><span class="o">+</span><span class="n">i</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">R</span><span class="p">[</span><span class="n">from</span><span class="o">+</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">to</span><span class="o">-</span><span class="n">i</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">R</span><span class="p">[</span><span class="n">to</span><span class="o">-</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">temp</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="c1">//Reverse
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">Converse</span><span class="p">(</span><span class="kt">int</span> <span class="n">R</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">p</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Reverse</span><span class="p">(</span><span class="n">R</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">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="n">Reverse</span><span class="p">(</span><span class="n">R</span><span class="p">,</span><span class="n">p</span><span class="p">,</span><span class="n">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="n">Reverse</span><span class="p">(</span><span class="n">R</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">p</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="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>3)说明算法时间空间复杂度</p>
|
||
<p>上述三个Reverse函数的时间复杂度分别为$O(p/2)、O((n-p)/2)$和$O(n/2)$故所设计的算法的时间复杂度为$O(n)$,空间复杂度为$O(1)$</p>
|
||
<ol start="11">
|
||
<li>一个长度为$L(L \leq 1)$的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如序列$S_1$=(11,13,15,17,19),则$S_1$的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如$S_2$=(2,4,6,8,20),则$S_1和S_2$的中位数是11.现在有两个等长升序序列A和B,试设计一个在时间和空间都尽可能高效的算法找出两个序列A和B的中位数。要求:</li>
|
||
</ol>
|
||
<p>1)给出算法设计思想</p>
|
||
<p>算法的基本设计思想:</p>
|
||
<p>分别求两个升序序列A,B的中位数,设为a和b,求序列A,B的中位数过程如下:</p>
|
||
<ol>
|
||
<li>若a=b,则a或b即为所求中位数,算法结束</li>
|
||
<li>若a&lt;b,则舍弃序列A中较小的一半,同时舍弃序列B中较大的一半,要求两次舍弃的长度相等</li>
|
||
<li>若a&gt;b,则舍弃序列A中较大的一半,同时舍弃序列B中较小的一半,要求两次舍弃的长度相等。</li>
|
||
</ol>
|
||
<p>在保留的两个升序序列中,重复过程1,2,3,直到两个序列中均只含有一个元素时为止,较小者即为所求的中位数</p>
|
||
<p>2)采用C或C++或java语言描述算法,关键之处给出注释</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">M_Search</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">B</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">s1</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span><span class="n">d1</span><span class="o">=</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">m1</span><span class="p">,</span><span class="n">s2</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span><span class="n">d2</span><span class="o">=</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">m2</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//分别表示序列A和B的首位数,末位数和中位数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">while</span><span class="p">(</span><span class="n">s1</span><span class="o">!=</span><span class="n">d1</span><span class="o">||</span><span class="n">s2</span><span class="o">!=</span><span class="n">d2</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">m1</span><span class="o">=</span><span class="p">(</span><span class="n">s1</span><span class="o">+</span><span class="n">d1</span><span class="p">)</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">m2</span><span class="o">=</span><span class="p">(</span><span class="n">s2</span><span class="o">+</span><span class="n">d2</span><span class="p">)</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">A</span><span class="p">[</span><span class="n">m1</span><span class="p">]</span><span class="o">==</span><span class="n">B</span><span class="p">[</span><span class="n">m2</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">m1</span><span class="p">];</span> <span class="c1">//满足过程1
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">m1</span><span class="p">]</span><span class="o">&lt;</span><span class="n">B</span><span class="p">[</span><span class="n">m2</span><span class="p">]){</span> <span class="c1">//满足过程2
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">((</span><span class="n">s1</span><span class="o">+</span><span class="n">d1</span><span class="p">)</span><span class="o">%</span><span class="mi">2</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="c1"></span> <span class="n">s1</span><span class="o">=</span><span class="n">m1</span><span class="p">;</span> <span class="c1">//舍弃A中间点以前的部分且保留中间点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">d2</span><span class="o">=</span><span class="n">m2</span><span class="p">;</span> <span class="c1">//舍弃B中间点以后的部分且保留中间点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">{</span> <span class="c1">//元素个数为偶数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">s1</span><span class="o">=</span><span class="n">m1</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="c1">//舍弃A中间点及中间点以前部分
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">d2</span><span class="o">=</span><span class="n">m2</span><span class="p">;</span> <span class="c1">//舍弃B中间点以后部分且保留中间点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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 class="p">{.</span> <span class="c1">//满足过程3
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">((</span><span class="n">s2</span><span class="o">+</span><span class="n">d2</span><span class="p">)</span><span class="o">%</span><span class="mi">2</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="c1"></span> <span class="n">d1</span><span class="o">=</span><span class="n">m1</span><span class="p">;</span> <span class="c1">//舍弃A中间点以后的部分且保留中间点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">s2</span><span class="o">=</span><span class="n">m2</span><span class="p">;</span> <span class="c1">//舍弃B中间点以前的部分且保留中间点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">{</span> <span class="c1">//元素个数为偶数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">d1</span><span class="o">=</span><span class="n">m1</span><span class="p">;</span> <span class="c1">//舍弃A中间点以后部分且保留中间点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">s2</span><span class="o">=</span><span class="n">m2</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="c1">//舍弃B中间点及中间点以前部分
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">A</span><span class="p">[</span><span class="n">s1</span><span class="p">]</span><span class="o">&lt;</span><span class="n">B</span><span class="p">[</span><span class="n">s2</span><span class="p">]</span> <span class="o">?</span> <span class="n">A</span><span class="p">[</span><span class="n">s1</span><span class="p">]</span><span class="o">:</span><span class="n">B</span><span class="p">[</span><span class="n">s2</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>3)说明算法时间空间复杂度</p>
|
||
<p>算法的时间复杂度为$O(\log_2 n)$,空间复杂度为$O(1)$</p>
|
||
<ol start="12">
|
||
<li>已知一个整数序列$A=(a_0,a_1,\cdots,a_{n-1})$,其中$0 \leq a_i &lt; n(0 \leq i &lt; n)$。若存在$a_{p1}=a_{p2}=\cdots=a_{pm}=x$且$m&gt;n/2(0\leq p_k &lt; n,1 \leq k \leq m)$,则称x为A的主元素,例如A=(0,5,5,3,5,7,5,5),则5为主元素;又如A=(0,5,5,3,5,1,5,7),则A中没有主元素。假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素,若存在主元素,则输出该元素,否则输出-1,要求</li>
|
||
</ol>
|
||
<p>1)给出算法设计思想</p>
|
||
<p>算法的基本设计思想:从前往后扫描数组元素,标记出一个可能成为主元素的元素num,然后重新计数,确认num是否是主元素</p>
|
||
<ol>
|
||
<li>选取候选的主元素,依次扫描所给数组中的每个整数,将第一个遇到的整数Num保存到c中,记录num的出现次数为1;若遇到的下一个整数仍然等于num,则计数加一,否则计数减一;当计数减到0时,将遇到的下一个整数保存到c中,计数重新记为一,开始新一轮计数,即从当前位置开始重复上述过程,直到扫描完全部数组元素</li>
|
||
<li>判断c中元素是否是真正的主元素。再次扫描该数组,统计c中元素出现的次数,若等于n/2,则为主元素;否则,序列中不存在主元素</li>
|
||
</ol>
|
||
<p>2)采用C或C++或java语言描述算法,关键之处给出注释</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">Majority</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</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">i</span><span class="p">,</span><span class="n">c</span><span class="p">,</span><span class="n">count</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="c1">//c用来保存候选主元素,count计数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">c</span><span class="o">=</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="c1">//设置A[0]为候选主元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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">n</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="c1">//查找候选主元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</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">count</span><span class="o">++</span><span class="p">;</span> <span class="c1">//对A中的候选主元素计数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="n">count</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span> <span class="c1">//处理不是候选主元素的情况
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">count</span><span class="o">--</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">{</span> <span class="c1">//更换候选主元素,重新计数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">c</span><span class="o">=</span><span class="n">A</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">count</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">count</span><span class="o">&gt;</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="n">i</span><span class="o">=</span><span class="n">count</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 class="c1">//统计候选主元素的实际出现次数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</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">count</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">count</span><span class="o">&gt;</span><span class="n">n</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="c1"></span> <span class="k">return</span> <span class="n">c</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span> <span class="c1">//不存在主元素
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</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="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>3)说明算法时间空间复杂度</p>
|
||
<p>时间复杂度为$O(n)$,空间复杂度为$O(1)$</p>
|
||
<ol start="13">
|
||
<li>给定一个含$n(n \geq 1)$个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数,例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4,要求:</li>
|
||
</ol>
|
||
<p>1)给出算法设计思想</p>
|
||
<p>思路:采用空间换时间的方法,分配一个用于标记的数组B[n],用于记录A中是否出现了1~n中的正整数,B[0]对应正整数1,B[n-1]对应正整数n,初始化B中全部为0,由于A中含有n个整数,因此可能的返回值是1~n+1,当A中n个数恰好为1~n时返回n+1。当数组A中出现了小于等于0或大于n的值时,会导致1~n中出现空余位置,返回结果必然在1~n中,因此对于A中出现了小于等于0或大于n的值,可以不采取任何操作</p>
|
||
<p>算法流程:从A[0]开始遍历A,若0&lt;A[i]&lt;=n,则令B[A[i]-1]=1;否则不做操作。对A遍历结束后,开始遍历数组B,若能查找到第一个满足B[i]==0的下标i,返回i+1即为结果,此时说明A中未出现的最小正整数在1~n之间。若B[i]全部不为0,返回i+1(跳出循环时i=n,i+1等于n+1),此时说明A中未出现的最小正整数是n+1</p>
|
||
<p>2)采用C或C++或java语言描述算法,关键之处给出注释</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">findMissMin</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</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">i</span><span class="p">,</span><span class="o">*</span><span class="n">B</span><span class="p">;</span> <span class="c1">//标记数组
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">B</span><span class="o">=</span><span class="p">(</span><span class="kt">int</span><span class="o">*</span> <span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="o">*</span><span class="n">n</span><span class="p">);</span> <span class="c1">//分配空间
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nf">memset</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="nf">siezof</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="o">*</span><span class="n">n</span><span class="p">);</span> <span class="c1">//赋初值为0
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&gt;</span><span class="mi">0</span><span class="o">&amp;&amp;</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&lt;=</span><span class="n">n</span><span class="p">)</span> <span class="c1">//若A[i]的值介于1~n,则标记数组B
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">B</span><span class="p">[</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-</span><span class="mi">1</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="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 class="c1">//扫描数组B,找到目标值
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">B</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="k">break</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">i</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="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>3)说明算法时间空间复杂度</p>
|
||
<p>时间复杂度:A,B各遍历一次,两次循环内操作步骤为$O(1)$量级,因此时间复杂度为$O(n)$</p>
|
||
<ol start="14">
|
||
<li>定义三元组(a,b,c)(a、b、c均为正数)的距离D=|a-b| + |b-c|+|c-a|。给定3个非空整数集合$S_1、S_2、S_3$,按升序分别存储在3个数组中。请设计一个尽可能高效的算法,计算并输出所有可能的三元组$(a,b,c)(a \in S_1,b \in S_2,c \in S_3)$中的最小距离。例如$S_1={-1,0,9},S_2={-25,-10,10,11},S_3={2,9,17,30,41},则最小距离为2,相应的三元组为(9,10,9)。要求:</li>
|
||
</ol>
|
||
<p>1)给出算法设计思想</p>
|
||
<ul>
|
||
<li>思路:由$D=|a-b|+|b-c|+|c-a| \geq 0$可得:</li>
|
||
</ul>
|
||
<ul>
|
||
<li>a=b=c时,距离最小</li>
|
||
<li>假设$a \leq b \leq c$可得$L_1=|a-b| L_2=|b-c| L_3=|c-a| D=|a-b|+|b-c|+|c-a|=L_1+L_2+L_3=2L_3$</li>
|
||
</ul>
|
||
<p>由此可得a和c的距离决定D的大小,问题简化为为每次固定的c找一个a,使得$L_3=|c-a|最小$</p>
|
||
<ul>
|
||
<li>算法的设计思想:</li>
|
||
</ul>
|
||
<ol>
|
||
<li>使用$D_{min}$记录所有已处理的三元组的最小距离,初值为一个足够大的整数。</li>
|
||
<li>集合$S_1,S_2,S_3$分别保存在数组A,B,C中。数组的下标变量i=j=k=0,当$i&lt;|S_1|,j&lt;|S_2|,k&lt;|S_3|$时,循环执行下面的步骤</li>
|
||
</ol>
|
||
<ul>
|
||
<li>计算A[i],B[j],C[k]的距离D</li>
|
||
<li>若$D&lt;D_{min} $,则$D_{min} = D$</li>
|
||
<li>将A[i],B[j],C[k]中的最小值的下标+1(最小值为a,最大值为c,此处c不变更新a,试图寻找更小的距离D)</li>
|
||
<li>输出$D_{min}$,结束</li>
|
||
</ul>
|
||
<p>2)采用C或C++或java语言描述算法,关键之处给出注释</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#define INT_MAX 0x7fffffff
|
||
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="kt">int</span> <span class="nf">abs_</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</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">&lt;</span><span class="mi">0</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">-</span><span class="n">a</span><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="k">return</span> <span class="n">a</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">bool</span> <span class="nf">xls_min</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span><span class="kt">int</span> <span class="n">b</span><span class="p">,</span><span class="kt">int</span> <span class="n">c</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">&lt;=</span><span class="n">b</span><span class="o">&amp;&amp;</span><span class="n">a</span><span class="o">&lt;=</span><span class="n">c</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">false</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">findMinofTrip</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</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">B</span><span class="p">[],</span><span class="kt">int</span> <span class="n">m</span><span class="p">,</span><span class="kt">int</span> <span class="n">C</span><span class="p">[],</span><span class="kt">int</span> <span class="n">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="o">=</span><span class="mi">0</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="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span><span class="n">D_min</span><span class="o">=</span><span class="n">INT_MAX</span><span class="p">,</span><span class="n">D</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">i</span><span class="o">&lt;</span><span class="n">n</span><span class="o">&amp;&amp;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">m</span><span class="o">&amp;&amp;</span><span class="n">k</span><span class="o">&lt;</span><span class="n">p</span><span class="o">&amp;&amp;</span><span class="n">D_min</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">D</span><span class="o">=</span><span class="nf">abs_</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-</span><span class="n">B</span><span class="p">[</span><span class="n">j</span><span class="p">])</span><span class="o">+</span><span class="nf">abs_</span><span class="p">(</span><span class="n">B</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">-</span><span class="n">C</span><span class="p">[</span><span class="n">k</span><span class="p">])</span><span class="o">+</span><span class="nf">abs_</span><span class="p">(</span><span class="n">C</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">-</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="c1">//计算D
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">D</span><span class="o">&lt;</span><span class="n">D_min</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">D_min</span> <span class="o">=</span> <span class="n">D</span><span class="p">;</span> <span class="c1">//更新D
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="nf">xls_min</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="n">B</span><span class="p">[</span><span class="n">j</span><span class="p">],</span><span class="n">C</span><span class="p">[</span><span class="n">k</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 class="c1">//更新a
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nf">xls_min</span><span class="p">(</span><span class="n">B</span><span class="p">[</span><span class="n">j</span><span class="p">],</span><span class="n">C</span><span class="p">[</span><span class="n">k</span><span class="p">],</span><span class="n">A</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">j</span><span class="o">++</span><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="n">k</span><span class="o">++</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 class="k">return</span> <span class="n">D_min</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>3)说明算法时间空间复杂度</p>
|
||
<p>设$n=(|S_1|+|S_2|+|S_3|)$,可得时间复杂度为$O(n)$空间复杂度为$O(1)$</p>
|
||
<h2 id="线性表的链式表示">线性表的链式表示</h2>
|
||
<h3 id="单链表定义">单链表定义</h3>
|
||
<p>线性表的链式存储称为单链表,通过一组任意的存储单元来存储线性表中的数据元素,对于每个链表结点,除存放元素自身元素以外,还需要存放一个指向其后继的指针</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th style="text-align:center">data</th>
|
||
<th style="text-align:center">next</th>
|
||
</tr>
|
||
</thead>
|
||
</table>
|
||
<p>如上,data为数据域,存放数据元素,next为指针域,存放后继结点的地址</p>
|
||
<p>对结点类型的定义如下:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">LNode</span><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ElemType</span> <span class="n">data</span><span class="p">;</span> <span class="c1">// 数据域
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">struct</span> <span class="n">LNode</span> <span class="o">*</span><span class="n">next</span><span class="p">;</span> <span class="c1">//指针域
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="n">LNode</span><span class="p">,</span><span class="o">*</span><span class="n">LinkList</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>单链表可解决顺序表需要大量连续存储单元的问题,但其本身附加指针域,会导致浪费存储空间,且单链表的元素离散分布在存储空间中(非随机存取结构),查找某个特定结点时,需要从表头开始遍历</p>
|
||
<p>头指针通常用于标识一个单链表,如单链表L,头指针为NULL时表示为一个空表,出于便于操作的目的,也会在单链表的第一个结点之前附加一个结点,称为头结点。头结点的数据域可以不设任何信息,也可以记录表长等信息。头结点的指针指向线性表的第一个元素结点</p>
|
||
<p>头结点和头指针的区别:</p>
|
||
<ul>
|
||
<li>头指针始终指向链表的第一个结点</li>
|
||
<li>头结点是带头结点的链表中的第一个结点,结点内通常不存储信息</li>
|
||
</ul>
|
||
<p>头结点引入的优势:</p>
|
||
<ul>
|
||
<li>由于第一个元素结点的位置被放在头结点的指针域中,因而在链表第一个位置上的操作与其他位置保持一致</li>
|
||
<li>无论链表是否为空,头指针都指向头结点的非空指针(空表中头结点的指针域为空),统一了对空表和非空表的处理</li>
|
||
</ul>
|
||
<h3 id="单链表的基本操作">单链表的基本操作</h3>
|
||
<h4 id="采用头插法建立单链表">采用头插法建立单链表</h4>
|
||
<p>该方法从一个空表开始,生成新结点,并把读取到的数据存放到新结点的数据域中,然后将新结点插入到头结点之后</p>
|
||
<p>算法如下:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">LinkList</span> <span class="nf">List_HeadInsert</span><span class="p">(</span><span class="n">LinkList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">LNode</span> <span class="o">*</span><span class="n">s</span><span class="p">;</span> <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="o">=</span><span class="p">(</span><span class="n">LinkList</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">LNode</span><span class="p">));</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</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">x</span><span class="o">!=</span><span class="mi">9999</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">s</span><span class="o">=</span><span class="p">(</span><span class="n">LNode</span><span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">LNode</span><span class="p">));</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">s</span><span class="o">-&gt;</span><span class="n">data</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">s</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">L</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">s</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</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">L</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>读入数据的顺序与生成的链表中的元素的顺序是相反的,每个结点插入的时间为$O(1)$,设单链表长度为n,则总时间复杂度为$O(n)$</p>
|
||
<h4 id="采用尾插法建立单链表">采用尾插法建立单链表</h4>
|
||
<p>该方法将新结点插入到当前链表的表尾,为此必须增加一个尾指针r,使其始终指向当前链表的尾结点</p>
|
||
<p>算法:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">LinkList</span> <span class="nf">List_TailInsert</span><span class="p">(</span><span class="n">LinkList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">){</span> <span class="c1">//正向建立单链表
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">L</span><span class="o">=</span><span class="p">(</span><span class="n">LinkList</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">LNode</span><span class="p">));</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">LNode</span> <span class="o">*</span><span class="n">s</span><span class="p">,</span><span class="o">*</span><span class="n">r</span><span class="o">=</span><span class="n">L</span><span class="p">;</span> <span class="c1">//r为表尾指针
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</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">x</span><span class="o">!=</span><span class="mi">9999</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">s</span><span class="o">=</span><span class="p">(</span><span class="n">LNode</span> <span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">LNode</span><span class="p">));</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">s</span><span class="o">-&gt;</span><span class="n">data</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">r</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">s</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">r</span><span class="o">=</span><span class="n">s</span><span class="p">;</span> <span class="c1">//r指向新的表尾指针
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">x</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">r</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="nb">NULL</span><span class="p">;</span> <span class="c1">//尾结点指针置空
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="n">L</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>读入数据的顺序与生成的链表中的元素的顺序一致,附设了一个指向表尾结点的指针,故时间复杂度和头插法的相同,都为$O(n)$</p>
|
||
<h4 id="按序号查找结点值">按序号查找结点值</h4>
|
||
<p>在单链表中从第一个结点出发,顺指针next域逐个往下搜索,直到找到第i个结点为止,否则返回最后一个结点指针域NULL</p>
|
||
<p>算法:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">LNode</span> <span class="o">*</span><span class="nf">GetElem</span><span class="p">(</span><span class="n">LinkList</span> <span class="n">L</span><span class="p">,</span><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="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="c1">//计数,初始为1
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">LNode</span> <span class="o">*</span><span class="n">p</span><span class="o">=</span><span class="n">L</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//头结点指针赋给p
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">i</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">return</span> <span class="n">L</span><span class="p">;</span> <span class="c1">//若i等于0,则返回头结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">i</span><span class="o">&lt;</span><span class="mi">1</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span> <span class="c1">//i无效则返回NULL
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">while</span><span class="p">(</span><span class="n">p</span><span class="o">&amp;&amp;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">i</span><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">next</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 class="k">return</span> <span class="n">p</span><span class="p">;</span> <span class="c1">//返回第i个结点的指针,若i大于表长,则返回NULL
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>时间复杂度为$O(n)$</p>
|
||
<h4 id="按值查找表结点">按值查找表结点</h4>
|
||
<p>从单链表的第一个结点开始,由前往后依次比较表中各结点数据域的值,若某结点数据域的值等于给定值e,则返回该结点的指针;若整个单链表中没有这样的结点,则返回NULL</p>
|
||
<p>算法:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">LNode</span> <span class="o">*</span><span class="nf">LocateElem</span><span class="p">(</span><span class="n">LinkList</span> <span class="n">L</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">e</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">LNode</span> <span class="o">*</span><span class="n">p</span><span class="o">=</span><span class="n">L</span><span class="o">-&gt;</span><span class="n">next</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="o">!=</span><span class="nb">NULL</span><span class="o">&amp;&amp;</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">!=</span><span class="n">e</span><span class="p">)</span> <span class="c1">//从第一个结点开始查找data域为e的结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">p</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">p</span><span class="p">;</span> <span class="c1">//找到后返回该结点指针,否则返回NULL
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h4 id="插入结点操作">插入结点操作</h4>
|
||
<p>插入结点操作将值为x的新结点插入到单链表的第i个位置上。先检查插入位置的合法性,然后找到待插入位置的前驱结点,即第i-1个结点,再在其后插入新结点</p>
|
||
<p>算法首先调用按序号查找算法GetElem(L,i-1),查找第i-1个结点。假设返回的第i-1个结点为* p,然后令新结点* s的指针域指向* p的后继结点,再令结点* p的指针域指向新插入的结点* s</p>
|
||
<p>实现插入结点的代码片段:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">p</span><span class="o">=</span><span class="nf">GetElem</span><span class="p">(</span><span class="n">L</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">s</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</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">next</span><span class="o">=</span><span class="n">s</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>上述片段中,指针操作顺序不能颠倒,否则,先执行p-&gt;next=s后,指向其原后继的指针就不存在,再执行s-&gt;next=p-&gt;next时,相当于执行了s-&gt;next=s,显然是错误的</p>
|
||
<p>主要的时间开销在于查找第i-1个元素,时间复杂度为$O(n)$.若在给定的节点后面插入新结点,则时间复杂度为$O(1)$</p>
|
||
<h4 id="对某一结点进行前插操作">对某一结点进行前插操作</h4>
|
||
<p>前插通常为在某结点的前面插入一个新结点,后插则相反,且单链表插入算法中更常用后插操作</p>
|
||
<p>上述算法中,找到插入结点的前驱结点后再执行后插操作即可将前插操作转换为后插操作,前提是从单链表头结点开始顺序查找到其前驱结点,时间复杂度为$O(n)$</p>
|
||
<p>也可设待插入结点为*S, 将 *S插入到到 *P的前面,此时仍然可以将 *S插入到 *P后,将p-&gt;data与s-&gt;data交换,此时的时间复杂度为$O(1)$</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">//将 *S插入到到 *P的前面
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">s</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">p</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="c1"></span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">s</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">temp</span> <span class="o">=</span> <span class="n">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="c1"></span><span class="n">p</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">=</span> <span class="n">s</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">s</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">=</span> <span class="n">temp</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h4 id="删除结点操作">删除结点操作</h4>
|
||
<p>删除结点操作是江单链表的第i个结点删除。需要先检查删除位置的合法性,后查找表中第i-1个结点,即被删结点的前驱结点,再将其删除</p>
|
||
<p>假设*p为找到的被删结点的前驱结点,仅需修改 *p的指针域,即将 *p的指针域next指向 *q的下一结点</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">p</span><span class="o">=</span><span class="nf">GetElem</span><span class="p">(</span><span class="n">L</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="c1">//查找删除位置的前驱结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">q</span><span class="o">=</span><span class="n">p</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="c1"></span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//将*q结点从链中断开
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nf">free</span><span class="p">(</span><span class="n">q</span><span class="p">);</span> <span class="c1">//释放后继结点的存储空间
|
||
</span></span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h4 id="求表长操作">求表长操作</h4>
|
||
<p>即计算单链表中数据结点的个数,需从第一个结点开始顺序依次访问表中的每个结点,设置一个计算器变量,每访问一次结点则加一,直到访问空结点,算法复杂度为$O(n)$</p>
|
||
<p>单链表长度往往不包括头结点,对于不带头结点和带头结点的链表在求表长时操作存在不同。对于前者,当表空时需要单独处理</p>
|
||
<h3 id="双链表">双链表</h3>
|
||
<p>双链表在单链表的结点中增加了一个指向前驱的prior指针,使得其无需像单链表那样只能从头开始依次顺序地向后遍历</p>
|
||
<p>结点类型描述:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">DNode</span><span class="p">{</span> <span class="c1">//定义双链表结点类型
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">ElemType</span> <span class="n">data</span><span class="p">;</span> <span class="c1">// 数据域
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">struct</span> <span class="n">DNode</span> <span class="o">*</span><span class="n">prior</span><span class="p">,</span><span class="o">*</span><span class="n">next</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="p">}</span><span class="n">DNode</span><span class="p">,</span><span class="o">*</span><span class="n">DLinklist</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h4 id="双链表的插入操作">双链表的插入操作</h4>
|
||
<p>在双链表中p所指的结点之后插入结点*s</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">s</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//将结点*s插入到结点*p之后
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-&gt;</span><span class="n">prior</span><span class="o">=</span><span class="n">s</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">-&gt;</span><span class="n">prior</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">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">s</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>上述代码顺序并非唯一,但也不是任意的,第一二步需保证在第四步之前,当值丢失*p的后继结点的指针</p>
|
||
<h4 id="双链表的删除操作">双链表的删除操作</h4>
|
||
<p>删除双链表中结点*p的后继结点 *q</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-&gt;</span><span class="n">prior</span><span class="o">=</span><span class="n">p</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="nf">free</span><span class="p">(</span><span class="n">q</span><span class="p">);</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h3 id="循环链表">循环链表</h3>
|
||
<h4 id="循环单链表">循环单链表</h4>
|
||
<p>循环单链表与单链表的区别在表中最后一个结点的指针不是NULL,而是指向头结点,从而整个链表形成一个环</p>
|
||
<p>循环单链表中,表尾结点*r的next域指向L,故表中没有指针域为NULL的结点,因此,循环单链表的判空条件为头结点的指针是否等于头指针</p>
|
||
<p>循环单链表中插入,删除与单链表一致,不同在于表尾操作时需要让单链表继续保持循环的性质。当然由于循环单链表往往认为是一个环,任何一个位置上的插入和删除操作都是等价,无需判断是否为表尾</p>
|
||
<p>相比于单链表,循环单链表能够从表中任意一个结点开始遍历整个链表,有时对单链表常做的操作是在表头和表尾进行,此时对循环单链表不设头指针,仅设尾指针能够有更高的效率,原因在于,若设的是头指针,对表尾进行操作需要$O(n)$的时间复杂度,若设的是尾指针r,r-&gt;即为头指针,对表头与表尾进行操作都只要$O(1)$的时间复杂度</p>
|
||
<h4 id="循环双链表">循环双链表</h4>
|
||
<p>在循环双链表中,头结点的prior指针还要指向表尾结点</p>
|
||
<p>例如在循环双链表L中,某结点*p为尾结点时,p-&gt;next==L;当循环双链表为空表时,其头结点的prior域和next域都等于L</p>
|
||
<h3 id="静态链表">静态链表</h3>
|
||
<p>静态链表借助数组来描述线性表的链式存储结构,结点也有数据域data和指针域next,与先前的链表中的指针不同在于此处的指针是结点的相对地址(数组下标),又称游标。和顺序表一致,静态链表也需要分配一块连续的内存空间</p>
|
||
<p>结构类型描述:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#define MaxSize 50
|
||
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="k">typedef</span> <span class="k">struct</span> <span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ElemType</span> <span class="n">data</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">next</span><span class="p">;</span><span class="c1">//下一个元素的数组下标
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span> <span class="n">SLinkList</span><span class="p">[</span><span class="n">MaxSize</span><span class="p">];</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>静态链表以next == -1作为结束的标志。总体而言,静态链表不如单链表使用起来方便,但在一些不支持指针的高级语言中,其为一种巧妙的设计方法</p>
|
||
<h2 id="顺序表和链表的比较">顺序表和链表的比较</h2>
|
||
<h3 id="存取读写方式">存取(读写)方式</h3>
|
||
<p>顺序表可以顺序存取,也可以随机存取,链表只能从表头顺序存取元素。例如在第i个位置上执行存或取得操作,顺序表仅需一次访问,而链表则需从表头开始依次访问i次</p>
|
||
<h3 id="逻辑结构与物理结构">逻辑结构与物理结构</h3>
|
||
<p>采用顺序存储是,逻辑上相邻的元素,对应的物理存储位置也相邻。采用链式存储时,逻辑上相邻的元素,物理存储位置不一定相邻,对应的逻辑关系是通过指针链接来表示的</p>
|
||
<h3 id="查找插入和删除操作">查找、插入和删除操作</h3>
|
||
<p>对于按值查找,顺序表无序时,两者的时间复杂度均为$O(n)$;顺序表有序时,可采用折半查找,此时的时间复杂度为$O(\log_2 n)$</p>
|
||
<p>对于按序号查找,顺序表支持随机访问,时间复杂度仅为$O(1)$,而链表的平均时间复杂度为$O(n)$。顺序表的插入、删除操作,平均需要移动半个表长的元素。链表的插入、删除操作,只需修改相关结点的指针域即可。由于链表的每个结点都带有指针域,故而存储密度不够大</p>
|
||
<h3 id="空间分配">空间分配</h3>
|
||
<p>顺序存储在静态存储分配情形下,一旦存储空间装满就不能扩充,若再加入新元素,则会出现内存溢出,因此需要预先分配足够大的存储空间。预先分配过大,可能会导致顺序表后不大量闲置;预先分配过小则易发生溢出</p>
|
||
<p>动态分配情形下,虽然可以扩充存储空间,但需要移动大量元素,导致操作效率降低,若内存中没有更大块的连续存储空间,则会分配失败,链式存储的存储空间则只在需要时申请,只要空间足够就能够申请,操作灵活高效</p>
|
||
<h3 id="存储结构的选取考虑">存储结构的选取考虑</h3>
|
||
<h4 id="基于存储考虑">基于存储考虑</h4>
|
||
<p>难以估计线性表长度或存储规模时,不宜采用顺序表;</p>
|
||
<p>链表不用事先估计存储规模,但链表的存储密度低(低于1)</p>
|
||
<h4 id="基于运算的考虑">基于运算的考虑</h4>
|
||
<p>在顺序表中按序号访问$a_j$的时间复杂度为$O(1)$,而链表中按序号访问的时间复杂度为$O(n)$,因此若经常做的运算是按序号访问数据元素,则显然顺序表优于链表</p>
|
||
<p>顺序表中插入,删除操作时,平均移动表中一半的元素,当数据元素的信息量较大且表较长时,此开销不可忽视;在链表中进行插入、删除操作时,虽然也要找插入位置,但主要进行的是比较操作,可见后者优于前者</p>
|
||
<h4 id="基于环境的考虑">基于环境的考虑</h4>
|
||
<p>顺序表易于实现,任何高级语言中都有数组类型;链表的操作是基于指针的,相对来讲,前者实现较为简单</p>
|
||
<p>两者各有优缺点,通常较稳定的线性表选择顺序存储,而频繁进行插入、删除操作的线性表宜使用链式存储</p>
|
||
<h3 id="一些练习-1">一些练习</h3>
|
||
<ol>
|
||
<li>设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点</li>
|
||
</ol>
|
||
<p>设计f(L,x)的功能是删除以L为收结点指针的单链表中所有值等于x的结点,显然有f(L-&gt;next,x)的功能是删除以L-&gt;next为首结点指针的单链表中所有值等于x的结点。由此,可以推出递归模型如下。</p>
|
||
<p>终止条件: f(L,x) = 不做任何事情; 若L为空表</p>
|
||
<p>递归主体: f(L,x) = 删除*L结点;f(L-&gt;next,x); 若L-&gt;data == x
|
||
f(L,x) = f(L-&gt;next,x); 其他情况</p>
|
||
<p>代码如下:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">Del_X_3</span><span class="p">(</span><span class="n">Linklist</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">,</span><span class="n">ElemType</span> <span class="n">x</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//递归实现在单链表L中删除值为x的结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">LNode</span> <span class="o">*</span><span class="n">p</span><span class="p">;</span> <span class="c1">//p指向待删除结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="o">==</span><span class="nb">NULL</span><span class="p">)</span> <span class="c1">//递归出口
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</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">L</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">==</span><span class="n">x</span><span class="p">){</span> <span class="c1">//若L所指结点的值为x
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">p</span><span class="o">=</span><span class="n">L</span><span class="p">;</span> <span class="c1">//删除*L,并让L指向下一结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">L</span><span class="o">=</span><span class="n">L</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">free</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">Del_X_3</span><span class="p">(</span><span class="n">L</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="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span> <span class="c1">//若L所指结点的值不为x
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nf">Del_X_3</span><span class="p">(</span><span class="n">L</span><span class="o">-&gt;</span><span class="n">next</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="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>算法需要调用一个递归工作栈,深度为O(n),时间复杂度为O(n)。由于L为引用,是直接对原链表进行操作,因而不会发生断链</p>
|
||
<ol start="2">
|
||
<li>试L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值</li>
|
||
</ol>
|
||
<p>算法思想:每当访问一个结点时,先递归输出它后面的结点,再输出该结点自身,这样链表就反向输出了</p>
|
||
<p>代码:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">R_Print</span><span class="p">(</span><span class="n">LinkList</span> <span class="n">L</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//从尾到头输出单链表L中每个结点的值
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">R_Print</span><span class="p">(</span><span class="n">L</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="c1"></span>
|
||
</span></span><span class="line"><span class="cl"> <span class="p">}</span><span class="c1">//if
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">print</span><span class="p">(</span><span class="n">L</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="p">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">R_Ignore_Head</span><span class="p">(</span><span class="n">LinkList</span> <span class="n">L</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">L</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">R_Print</span><span class="p">(</span><span class="n">L</span><span class="o">-&gt;</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 class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="3">
|
||
<li>有一个带头结点的单链表L,试设计一个算法使其元素递增有序</li>
|
||
</ol>
|
||
<p>算法思想:</p>
|
||
<p>采用直接插入排序算法的思想,先构成只含一个数据结点的有序单链表,然后一次扫描单链表中剩下的结点*p(直到p==NULL为止),在有序表中通过比较查找插入 *p的前驱结点 *pre,然后将 *p插入到 *pre之后</p>
|
||
<p>代码如下:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">Sort</span><span class="p">(</span><span class="n">LinkList</span> <span class="o">&amp;</span><span class="n">L</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//本算法实现将单链表L的结点重排,使其递增有序
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">LNode</span> <span class="o">*</span><span class="n">p</span><span class="o">=</span><span class="n">L</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">,</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">LNode</span> <span class="o">*</span><span class="n">r</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//r保持*p后继结点指针,保证不断连
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span> <span class="c1">//构造只含一个数据结点的有序表
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">p</span><span class="o">=</span><span class="n">r</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="o">!=</span><span class="nb">NULL</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">r</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//以保存*p的后继结点指针
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">pre</span><span class="o">=</span><span class="n">L</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">pre</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">!=</span><span class="nb">NULL</span><span class="o">&amp;&amp;</span><span class="n">pre</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-&gt;</span><span class="n">data</span><span class="o">&lt;</span><span class="n">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">pre</span> <span class="o">=</span> <span class="n">pre</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//在有序表中查找插入*p的前驱结点*pre
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">next</span> <span class="o">=</span> <span class="n">pre</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//将*p插入到*pre之后
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">pre</span><span class="o">-&gt;</span><span class="n">next</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">p</span><span class="o">=</span><span class="n">r</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></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></td></tr></table>
|
||
</div>
|
||
</div><p>该算法的时间复杂度为$O(n^2)$,为达到最佳的时间性能,可将链表的数据复制到数组中,再采用时间复杂度为$O(n\log_2 n)$的排序算法进行排序,然后将数组元素依次插入链表中,此时的时间复杂度为$O(n\log_2 n)$,显然这是以空间换时间的策略</p>
|
||
<ol start="4">
|
||
<li>已知一个带有表头结点的单链表,结点结构为</li>
|
||
</ol>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th style="text-align:center">data</th>
|
||
<th style="text-align:center">link</th>
|
||
</tr>
|
||
</thead>
|
||
</table>
|
||
<p>假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为整数)。若查找成功,算法输出该结点的data域的值,并返回1;否则,只返回0,要求:</p>
|
||
<ol>
|
||
<li>描述算法的基本设计思想</li>
|
||
</ol>
|
||
<p>问题关键在于设计一个尽可能高效的算法,通过链表的一次遍历,找到倒数第k个结点的位置</p>
|
||
<p>算法的基本设计思想:</p>
|
||
<p>定义两个指针变量p和q,初始时均指向头结点的下一个结点(链表的第一个结点),p指针沿链表移动,当p指针移动到第k个结点时,q指针开始与p指针同步移动;当p指针移动到最后一个结点时,q指针所指示结点为倒数第k个结点。以上过程对链表仅进行一遍扫描</p>
|
||
<ol start="2">
|
||
<li>
|
||
<p>描述算法的详细实现步骤</p>
|
||
<ol>
|
||
<li>count = 0,p和q指向链表表头结点的下一个结点</li>
|
||
<li>若p为空,转向步骤5</li>
|
||
<li>若count等于k,则q指向下一个结点,否则,count=count+1.</li>
|
||
<li>p指向下一个结点,转向步骤2</li>
|
||
<li>若count等于k,则查找成功,输出该结点的data域的值,返回1,否则,说明k值超过了线性表长度,查找失败,返回0</li>
|
||
<li>算法结束</li>
|
||
</ol>
|
||
</li>
|
||
<li>
|
||
<p>根据设计思想和实现步骤,采用程序设计语言描述算法,关键之处请给出简要注释</p>
|
||
</li>
|
||
</ol>
|
||
<p>算法实现:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="kt">int</span> <span class="n">ElemType</span> <span class="c1">//链表数据的类型定义
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">typedef</span> <span class="k">struct</span> <span class="n">LNode</span><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ElemType</span> <span class="n">data</span><span class="p">;</span> <span class="c1">//结点数据
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">struct</span> <span class="n">LNode</span> <span class="o">*</span><span class="n">link</span><span class="p">;</span><span class="c1">//结点链接指针
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="n">LNode</span><span class="p">,</span><span class="o">*</span><span class="n">LinkList</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="kt">int</span> <span class="nf">Search_k</span><span class="p">(</span><span class="n">LinkList</span> <span class="n">list</span><span class="p">,</span><span class="kt">int</span> <span class="n">k</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//查找链表list倒数第k个结点,并输出该结点data域的值
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">LNode</span> <span class="o">*</span><span class="n">p</span><span class="o">=</span><span class="n">list</span><span class="o">-&gt;</span><span class="n">link</span><span class="p">,</span><span class="o">*</span><span class="n">q</span><span class="o">=</span><span class="n">list</span><span class="o">-&gt;</span><span class="n">link</span><span class="p">;</span><span class="c1">//指针p,q指示第一个结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">int</span> <span class="n">count</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">while</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="c1">// 遍历链表直到最后一个结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">count</span><span class="o">&lt;</span><span class="n">k</span><span class="p">){</span> <span class="c1">//计数,若count&lt;k只移动p
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">count</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="k">else</span><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">q</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">link</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">link</span><span class="p">;</span> <span class="c1">//之后让p,q同步移动
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">count</span><span class="o">&lt;</span><span class="n">k</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 class="c1">//查找失败返回0
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">);</span> <span class="c1">//查找成功,打印并返回1
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="5">
|
||
<li>设计一个算法完成以下功能:判断一个链表是否有环,如果有,找出环的入口点并返回,否则返回NULL</li>
|
||
</ol>
|
||
<p>算法的基本设计思想:</p>
|
||
<p>设置快慢两个指针分别为fast和slow,初始时都指向链表头head。slow每次走一步,即slow=slow-&gt;next;fast每次走两步,即fast=fast-&gt;next-&gt;next。由于fast比slow走得快,如果有环,那么fast一定会先进入,而slow后进入环,当两个指针都进入环后,经过若干操作后两个指针定能在环上相遇,从而判断一个链表是否存在环</p>
|
||
<p>当slow刚进入环时,fast早已进入环。因为fast每次比slow多走一步,且fast与slow 的距离小于环的长度,所以fast与slow相遇时,slow所走的距离不超过环的长度</p>
|
||
<p>设头结点到环的入口点的距离为a,环的入口点沿着环的方向到相遇点的距离为x,环长为r,相遇时fast绕过了n圈,则有2(a+x)=a+n * r+x,即a=n * r-x。显然从头结点到环的入口点的距离等于n被的环长减去环的入口点到相遇点的距离。因此可设置两个指针,一个指向head,一个指向相遇点,两个指针同步移动(一次走一步),相遇点即为环的入口点</p>
|
||
<p>代码实现:</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">LNode</span><span class="o">*</span> <span class="nf">FindLoopStart</span><span class="p">(</span><span class="n">LNode</span> <span class="o">*</span><span class="n">head</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">LNode</span> <span class="o">*</span><span class="n">fast</span><span class="o">=</span><span class="n">head</span><span class="p">,</span><span class="o">*</span><span class="n">slow</span><span class="o">=</span><span class="n">head</span><span class="p">;</span><span class="c1">//设置快慢两个指针
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">while</span><span class="p">(</span><span class="n">slow</span><span class="o">!=</span><span class="nb">NULL</span><span class="o">&amp;&amp;</span><span class="n">fats</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">slow</span><span class="o">=</span><span class="n">slow</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="c1"></span> <span class="n">fast</span><span class="o">=</span><span class="n">fast</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-</span><span class="n">next</span><span class="p">;</span><span class="c1">//每次走两步
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="p">(</span><span class="n">slow</span><span class="o">==</span><span class="n">fast</span><span class="p">){</span> <span class="c1">// 相遇
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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="n">slow</span><span class="o">==</span><span class="nb">NULL</span><span class="o">||</span><span class="n">fast</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">==</span><span class="nb">NULL</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span> <span class="c1">//没有环,返回NULL
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">LNode</span> <span class="o">*</span><span class="n">p1</span><span class="o">=</span><span class="n">head</span><span class="p">,</span><span class="o">*</span><span class="n">p2</span><span class="o">=</span><span class="n">slow</span><span class="p">;</span> <span class="c1">//分别指向开始点,相遇点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">while</span><span class="p">(</span><span class="n">p1</span><span class="o">!=</span><span class="n">p2</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">p1</span><span class="o">=</span><span class="n">p1</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">p2</span><span class="o">=</span><span class="n">p2</span><span class="o">-&gt;</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 class="k">return</span> <span class="n">p1</span><span class="p">;</span> <span class="c1">//返回入口点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><ol start="6">
|
||
<li>设线性表$L=(a_1,a_2,a_3,\cdots,a_{n-2},a_{n-1},a_{n})$采用带头结点的单链表保存,链表中的结点定义如下:</li>
|
||
</ol>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">node</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">data</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">struct</span> <span class="n">node</span><span class="o">*</span><span class="n">next</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="n">NODE</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>请设计一个空间复杂度为$O(1)$且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表$L_1=(a_1,a_n,a_2,a_{n-1},a_3,a_{n-2},\cdots)$。要求:</p>
|
||
<ol>
|
||
<li>描述算法的基本设计思想和详细实现步骤</li>
|
||
</ol>
|
||
<p>观察比较$L$和$L_1$可知,后者由前者摘取一个元素,再摘取倒数第一个元素,依次合并而成</p>
|
||
<p>为了方便链表后半段取元素,需要先将$L$的后半段原地逆置(题目要求空间复杂度为$O(n)$因而不能借助栈来逆置),否则每取最后一个结点都需要遍历一次链表</p>
|
||
<pre><code>1. 先找出链表L的中间结点,为此设置两个指针p和q,指针p每次走一步,指针q每次走两步,当指针q到达链尾时,指针p正好在链表的中间结点
|
||
2. 然后将L的后半段结点原地逆置
|
||
3. 从单链表前后两段中依次各取一个结点,按要求重排
|
||
</code></pre>
|
||
<ol start="2">
|
||
<li>根据设计思想和实现步骤,采用程序设计预言描述算法,关键之处请给出简要注释</li>
|
||
</ol>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">change_list</span><span class="p">(</span><span class="n">NODE</span><span class="o">*</span><span class="n">h</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">p</span><span class="p">,</span><span class="o">*</span><span class="n">q</span><span class="p">,</span><span class="o">*</span><span class="n">r</span><span class="p">,</span><span class="o">*</span><span class="n">s</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">p</span><span class="o">=</span><span class="n">q</span><span class="o">=</span><span class="n">h</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">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span> <span class="c1">//寻找中间结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">p</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//p走一步
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">q</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</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">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">q</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//q走两步
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">q</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//p所指结点为中间结点,q为后半段链表的首结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="nb">NULL</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">q</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span> <span class="c1">//逆置链表后半段
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">r</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</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">next</span><span class="o">=</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="o">=</span><span class="n">r</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="n">s</span><span class="o">=</span><span class="n">h</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//s指向前半段的第一个数据结点,插入点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">q</span><span class="o">=</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//q指向后半段的第一个数据结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="nb">NULL</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">q</span><span class="o">!=</span><span class="nb">NULL</span><span class="p">){</span> <span class="c1">//将链表后半段的结点插入到指定位置
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">r</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//r指向后半段的下一个结点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">s</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//将q所指结点插入到s所指结点之后
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">s</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">=</span><span class="n">q</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">s</span><span class="o">=</span><span class="n">q</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//s指向前半段的额下一个插入点
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">q</span><span class="o">=</span><span class="n">r</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></td></tr></table>
|
||
</div>
|
||
</div><ol start="3">
|
||
<li>计算时间复杂度</li>
|
||
</ol>
|
||
<p>第一步中找中间结点的时间复杂度为$O(n)$,第二步逆置的时间复杂度为$O(n)$,第三部合并链表的时间复杂度为$O(n)$,因此该算法的时间复杂度为$O(n)$</p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/408/">408\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>每日一题</title>
|
||
<link>http://www.inksoul.top/stuff/result/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/stuff/result/</guid>
|
||
<pubDate>Mon, 22 Aug 2022 21:53:27 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><p>该题更新于:2022-09-02 18:45:36</p>
|
||
<p>-----每日一题 Day 39------</p>
|
||
<p>计算机组成原理
|
||
4 某虚拟存储器系统采用页式内存管理,假定内存容量为4个页面,开始时是空的,页面访问地址流:1 8 1 7 8 2 7 2 1 8 3 8 2 1 3 1 7 1 3 7 使用LRU页面替换算法的命中率是______(西北工业大学 2015年)</p>
|
||
<p>A 65%</p>
|
||
<p>B 70%</p>
|
||
<p>C 75%</p>
|
||
<p>D 80%</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-02 18:44:49</p>
|
||
<p>-----每日一题 Day 39------</p>
|
||
<p>操作系统
|
||
3 有三个同时到达的作业J1、J2、J3,运行时间分别是1、2、3,若系统中仅有一台单道运行的处理机,按照______序列执行时平均周转时间最小。(西安电子科技大学 2013年)
|
||
A J1--&gt;J2--&gt;J3</p>
|
||
<p>B J2--&gt;J3--&gt;J1</p>
|
||
<p>C J2--&gt;J1--&gt;J3</p>
|
||
<p>D.J1--&gt;J3--&gt;J2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-02 18:44:03</p>
|
||
<p>-----每日一题 Day 39------</p>
|
||
<p>计算机网络
|
||
2 在因特网中,下列哪个不是IP层所需解决的问题______(中国海洋大学 2011年)</p>
|
||
<p>A 流量控制</p>
|
||
<p>B 路径选择</p>
|
||
<p>C 寻址</p>
|
||
<p>D 分段和重新组装</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-01 16:51:32</p>
|
||
<p>-----每日一题 Day 38------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 假设同一套指令集用不同的方法设计了两种机器M1和M2。机器M1的时钟周期为0.8ns,机器M2的时钟周期为1.2ns。某个程序P在机器M1上运行时的CPI为4,在M2上的CPI为2。对于程序P来说,哪台机器的执行速度更快?快多少? ______(上海交通大学)
|
||
|
||
A.M1 比 M2快,快25%</p>
|
||
<p>B.M2 比 M1 快,快33%</p>
|
||
<p>C.M1 比M2快,快33%</p>
|
||
<p>D.M2 比 M1 快,快25%</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-01 16:50:38</p>
|
||
<p>-----每日一题 Day 38------</p>
|
||
<p>操作系统</p>
|
||
<p>3 解决碎片问题,以及使程序可浮动的最好的办法是采用____技术(辽宁大学 2014年)</p>
|
||
<p>A 静态重定位</p>
|
||
<p>B 动态重定位</p>
|
||
<p>C 内存静态分配</p>
|
||
<p>D 内存动态分配</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-01 16:49:43</p>
|
||
<p>-----每日一题 Day 38------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 关于千兆以太网的说法中不正确的是_____(重庆大学 2010年)</p>
|
||
<p>A 千兆以太网中可以使用光纤或者双绞线</p>
|
||
<p>B 千兆以太网仍然可以使用共享介质技术</p>
|
||
<p>C 千兆以太网只能工作在全双工模式</p>
|
||
<p>D 千兆以太网介质访问控制方法仍然可以使用CSMA/CD技术</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-01 16:48:10</p>
|
||
<p>-----每日一题 Day 38------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一个具有513个节点的二叉树,有___种可能的层高(西安交通大学 2015年)</p>
|
||
<p>A 513</p>
|
||
<p>B 512</p>
|
||
<p>C 504</p>
|
||
<p>D 503</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-31 18:00:48</p>
|
||
<p>-----每日一题 Day 37------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 一个计算机有cache、主存和用于虚拟存储的磁盘。若所访问的字在cache中,则存取它只需20ns。若字在主存而不在cache中,则需要60ns将它装入cache,然后再从cache存取。若字不在主存中,则需要12ns将它由磁盘取来装入主存,再用60ns将它复制到cache,最后从cache存取。cache命中率是0.9,主存命中率是0.6。那么此系统访问一个字的平均存取时间是_____(以ns为单位)(清华大学 2012年)</p>
|
||
<p>A 18</p>
|
||
<p>B 21.68</p>
|
||
<p>C 22.8</p>
|
||
<p>D 26.48</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-31 17:59:55</p>
|
||
<p>-----每日一题 Day 37------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____(南京大学 2012年)</p>
|
||
<p>A 请求分页存储管理系统,若把页面的大小增加一倍,则 缺页中断次数会减少一半。</p>
|
||
<p>B 虚拟存储器的实现是基于程序局部性原理,其实质是借助外存将内存较小的物理地址空间转化为较大的逻辑地址空间。</p>
|
||
<p>C 虚存容量仅受外存容量的限制。</p>
|
||
<p>D 请求分页存储管理中,页面置换算法很多,但只有佳置换算法能完全避免进程的抖动,因而应用广泛;其他如改进型 CLOCK算法虽然也能避免进程的抖动,但其效率一般很低。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-31 17:58:52</p>
|
||
<p>-----每日一题 Day 37------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 当一台计算机发送 E-mail 信息给另外一台计算机时,下列的哪一个过程正确描述了数据打包的 5 个转换步骤______(华中科技大学 2011年)</p>
|
||
<p>A 数据,数据段,数据包,数据帧,比特</p>
|
||
<p>B 比特,数据帧,数据包,数据段,数据</p>
|
||
<p>C 数据包,数据段,数据,比特,数据帧</p>
|
||
<p>D 数据段,数据包,数据帧,比特,数据</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-31 17:57:57</p>
|
||
<p>-----每日一题 Day 37------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一棵有15个节点的完全二叉树和一棵同样有15个节点的普通二叉树,叶子节点的个数最多会差_____个(南开大学 2015年)</p>
|
||
<p>A 3</p>
|
||
<p>B 5</p>
|
||
<p>C 7</p>
|
||
<p>D 9</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-30 18:35:17</p>
|
||
<p>-----每日一题 Day 36------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 假定编译器将赋值语句“x=x+3;”转换为指令“add xaddt,3”, 其中xaddt是x对应的存储单元地址,若执行该指令的计算机采用页式虚拟存储管理方式,并配有相应的TLB,且Cache使用直写方式,完成该指令的功能,需要访问主存的次数最少是_____次(电子科技大学)</p>
|
||
<p>A.2</p>
|
||
<p>B.3</p>
|
||
<p>C.0</p>
|
||
<p>D.1</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-30 18:34:24</p>
|
||
<p>-----每日一题 Day 36------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列关于线程说法错误的是______(辽宁大学 2015年)</p>
|
||
<p>A 耗时的操作使用线程,提高程序响应</p>
|
||
<p>B 耗内存的操作使用线程,提高内存利用率</p>
|
||
<p>C 多CPU的系统使用线程,提高CPU利用率</p>
|
||
<p>D 并行操作使用线程,如c/s架构中服务端程序为每个客户端请求创建一个线程来响应</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-30 18:33:18</p>
|
||
<p>-----每日一题 Day 36------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列说法错误的是_____(杭州电子科技大学 2012年)</p>
|
||
<p>A 信道的码元传输速率是有上限的</p>
|
||
<p>B 频带宽度越宽的信道,其信息传输速率越大</p>
|
||
<p>C 信噪比越大的信道,其信息传输速率越大</p>
|
||
<p>D 在信道频带宽度和信噪比不变的情况下,可以通过调制方式提高码元极限传输速率</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-30 18:32:17</p>
|
||
<p>-----每日一题 Day 36------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设F是由T1、T2和T3三棵树组成的森林,与F对应的二叉树为B,T1、T2和T3的结点数分别为N1、N2和N3,则二叉树B的根结点的左子树的结点数为______(福州大学 2014年)</p>
|
||
<p>A N1-1</p>
|
||
<p>B N2-1</p>
|
||
<p>C N2+N3</p>
|
||
<p>D N1+N3</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-29 18:53:57</p>
|
||
<p>-----每日一题 Day 35------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设存储器容量为512K字,字长32位,模块数=8,用交叉方式进行组织。存储周期T=200ns,数据总线宽度为32位,总线传送周期τ=50ns。则交叉存储器带宽是_____位/s(北京大学 2016年)</p>
|
||
<p>A 46.5×10^(7)</p>
|
||
<p>B 16×10^(7)</p>
|
||
<p>C 5.5×10^(7)</p>
|
||
<p>D 32×10^(7)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-29 18:53:03</p>
|
||
<p>-----每日一题 Day 35------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法不正确的是______(北京交通大学 2014年)</p>
|
||
<p>A 可以采用一次性请求所有资源来预防死锁</p>
|
||
<p>B 可以采用强占其它进程已占资源的方法来预防死锁</p>
|
||
<p>C 可以通过提高进程优先级的方法解除死锁</p>
|
||
<p>D 可以采用资源分配拒绝策略(如银行家算法)避免死锁</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-29 18:52:10</p>
|
||
<p>-----每日一题 Day 35------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 以下哪一个不属于因特网基本的服务功能______(北京航空航天大学 2010年)</p>
|
||
<p>A DNS</p>
|
||
<p>B E-mail</p>
|
||
<p>C WWW</p>
|
||
<p>D FTP</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-29 18:51:04</p>
|
||
<p>-----每日一题 Day 35------</p>
|
||
<p>数据结构</p>
|
||
<p>1 分别以下列序列构造二叉排序树,与用其它三个序列所构造的结果不同的是_____(安徽大学 2015年)</p>
|
||
<p>A (100,80,60,90,120,130,110)</p>
|
||
<p>B (100,120,110,130,80,60,90)</p>
|
||
<p>C (100,80,90,60,120,110,130)</p>
|
||
<p>D (100,60,80,90,120,110,130)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-26 18:07:26</p>
|
||
<p>-----每日一题 Day 34------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 以下关于流水段的功能部件的描述中,错误的是_______(上海大学 2014年)
|
||
|
||
A.所有功能部件都要用组合逻辑实现</p>
|
||
<p>B.同一个功能部件可以在不同的流水段中被使用</p>
|
||
<p>C.寄存器写口只能在指令结束时的“写回”阶段被使用</p>
|
||
<p>D.每个功能部件在每条指令中都只被使用一次</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-26 18:06:37</p>
|
||
<p>-----每日一题 Day 34------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____(南京理工大学 2012年)</p>
|
||
<p>A 作业一旦被作业调度选中,就获得了CPU的控制权。</p>
|
||
<p>B 单CPU多道程序设计是指每一时刻可以有多个进程在执行。</p>
|
||
<p>C 用户进程所执行的程序都是用户编写的程序。</p>
|
||
<p>D 为了避免出现内存中进程全部处于阻塞状态的情况,操作 系统可选择将一些进程转移到磁盘,再调入新进程运行。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-26 18:05:32</p>
|
||
<p>-----每日一题 Day 34------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列地址中_____是私有地址(重庆邮电大学 2010年)</p>
|
||
<p>A 172.32.0.1</p>
|
||
<p>B 172.0.0.1</p>
|
||
<p>C 172.16.0.255</p>
|
||
<p>D 172.15.255.255</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-26 18:01:39</p>
|
||
<p>-----每日一题 Day 34------</p>
|
||
<p>数据结构</p>
|
||
<p>1 能说明快速排序是不稳定的排序方法的一组关键字序列是______(暨南大学 2011年)</p>
|
||
<p>A (10,20, 30, 40,50)</p>
|
||
<p>B (50,40, 30, 20,10)</p>
|
||
<p>C (20, 20,30,10,40)</p>
|
||
<p>D (20, 40, 30, 30, 10)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-25 17:23:18</p>
|
||
<p>-----每日一题 Day 33------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 .关于模4补码,下面叙述正确的是_______。(西安电子科技大学 2013年)</p>
|
||
<p>A.模4补码与模2补码不同,它更容易检查乘除运算中的溢出问题</p>
|
||
<p>B.每个模4补码存储时,只要存1个符号位</p>
|
||
<p>C.存储每个模4补码时,需要存2个符号位</p>
|
||
<p>D.模4补码,在算术与逻辑部件中为1个符号位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-25 17:22:24</p>
|
||
<p>-----每日一题 Day 33------</p>
|
||
<p>操作系统</p>
|
||
<p>3 若干个等待访问磁盘者依次要访问的磁道为 19、43、40、4、79、11、76,当前磁头位于 40 号柱面,若用最短寻道时间优先磁盘调度算法,则磁头移动总距离为______(厦门大学 2015年)</p>
|
||
<p>A 271</p>
|
||
<p>B 117</p>
|
||
<p>C 110</p>
|
||
<p>D 129</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-25 17:21:36</p>
|
||
<p>-----每日一题 Day 33------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列关于 IP 路由器功能的描述中,正确的是 _____(武汉大学 2016年)</p>
|
||
<p>Ⅰ . 运行路由协议,设置路由表</p>
|
||
<p>Ⅱ . 监测到拥塞时,合理丢弃 IP 分组</p>
|
||
<p>Ⅲ . 对收到的 IP 分组头进行差错校验,确保传输的 IP 分组不丢失</p>
|
||
<p>Ⅳ . 根据收到的 IP 分组的目的 IP 地址,将其转发到合适的输出线路上</p>
|
||
<p>A 仅Ⅲ、Ⅳ</p>
|
||
<p>B 仅Ⅰ、Ⅱ、Ⅲ</p>
|
||
<p>C 仅Ⅰ、Ⅱ、Ⅳ</p>
|
||
<p>D Ⅰ、Ⅱ、Ⅲ、Ⅳ</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-25 17:13:33</p>
|
||
<p>-----每日一题 Day 33------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设一组初始记录关键字序列为(345,253,674,924,627),则用基数排序需要进行_____趟的分配和回收才能使得初始关键字序列变成有序序列。(武汉科技大学 2014年)</p>
|
||
<p>A 3</p>
|
||
<p>B 4</p>
|
||
<p>C 5</p>
|
||
<p>D 8</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-24 19:25:14</p>
|
||
<p>-----每日一题 Day 32------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某计算机指令集中包含RR型运算指令(源操作数和目的操作数都是寄存器)、取数指令load,、存数指令store,、条件分支指令branch和直接跳转指令jump。 如果采用单周期数据通路实现该指令系统,各主要功能部件的操作时间为:指令存储器和数据存储器都是2ns; ALU和加法器都是1ns; 寄存器文件的读和写都是0.5ns. 在不考虑多路选择器、控制器、PC、符号扩展单元和传输延迟的情况下,该计算机的时钟周期至少为______(上海交通大学)</p>
|
||
<p>A.5ns</p>
|
||
<p>B.8ns</p>
|
||
<p>C.7ns</p>
|
||
<p>D.6ns</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-24 19:23:23</p>
|
||
<p>-----每日一题 Day 32------</p>
|
||
<p>操作系统</p>
|
||
<p>3 设文件F1 的当前引用计数为1,先建立F1 的符号链接文件F2,再建立F1 的硬链接文件 F3,则此时文件F1、F2 和F3 的引用计数值分别是_____(北京交通大学 2014年)</p>
|
||
<p>A 2,1, 2</p>
|
||
<p>B 2,2,2</p>
|
||
<p>C 3,1,2</p>
|
||
<p>D 3,2,2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-24 19:22:33</p>
|
||
<p>-----每日一题 Day 32------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 RIP 协议适用于基于 IP 的____(重庆邮电大学 2009年)</p>
|
||
<p>A 大型网络</p>
|
||
<p>B 中小型网络</p>
|
||
<p>C 更大规模的网络</p>
|
||
<p>D isp与isp之间</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-24 19:21:27</p>
|
||
<p>-----每日一题 Day 32------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设查找表中有100个元素,如果用二分法查找方法查找数据元素X,则最多需要比较______次就可以断定数据元素X是否在查找表中。(福州大学 2014年)</p>
|
||
<p>A 5</p>
|
||
<p>B 6</p>
|
||
<p>C 7</p>
|
||
<p>D 8</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-23 18:18:40</p>
|
||
<p>-----每日一题 Day 31------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 在以下情况中,不会引起指令流水线阻塞的是______(广东工业大学 2013年)</p>
|
||
<p>A 外部中断</p>
|
||
<p>B 指令数据相关</p>
|
||
<p>C 条件转移</p>
|
||
<p>D 数据旁路</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-23 18:15:17</p>
|
||
<p>-----每日一题 Day 31------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在使用 IP 地址时,如果网络号和主机号全1时,则表示_____(华东师范大学 2011年)</p>
|
||
<p>A 地址可以使用,目的地址不可以使用,只在本网络进行广播</p>
|
||
<p>B 源地址不可以使用,目的地址可以使用,只在本网络进行广播</p>
|
||
<p>C 源地址可以使用,目的地址也可以使用,只在本网络进行广播</p>
|
||
<p>D 源地址和目的地址都不可以使用,各路由器可以对广播进行转发</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-23 18:14:05</p>
|
||
<p>-----每日一题 Day 31------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列关键字序列为堆的是_____(南昌大学 2015年)</p>
|
||
<p>A 100,60,70,50,32,65</p>
|
||
<p>B 60,70,65,50,32,100</p>
|
||
<p>C 65,100,70,32,50,60</p>
|
||
<p>D 70,65,100,32,50,60</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-22 21:55:53</p>
|
||
<p>-----每日一题 Day 30------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 连续两次启动同一存储器所需的最小时间间隔称为_____(合肥工业大学 2014年)</p>
|
||
<p>A 存储周期</p>
|
||
<p>B 存取时间</p>
|
||
<p>C 存储时间</p>
|
||
<p>D 访问周期</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-22 21:54:25</p>
|
||
<p>-----每日一题 Day 30------</p>
|
||
<p>操作系统
|
||
3 假设在单处理器多道程序系统中有5个程序A、B、C、D、E按顺 序几乎同时到达,其运行时间、优先级如下表所示</p>
|
||
<p>程序 运行时间(分钟) 优先级</p>
|
||
<p>A 10 3</p>
|
||
<p>B 6 5</p>
|
||
<p>C 2 2</p>
|
||
<p>D 4 1</p>
|
||
<p>E 8 4</p>
|
||
<p>对于HRRF调度算法,其平均周转时间为(不考虑进程切 换)_________分钟。 (南京大学 2012年)</p>
|
||
<p>A 19.2</p>
|
||
<p>B 14</p>
|
||
<p>C 20</p>
|
||
<p>D 18</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-22 21:52:14</p>
|
||
<p>-----每日一题 Day 30------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在无噪声情况下,若某通信链路的带宽为 6kHz ,若采用 4 个相位,每个相位具有 4 种振幅的 QAM 调制技术,那么该通信链路的最大数据传输速率变为_____(杭州电子科技大学 2011年)</p>
|
||
<p>A 12kbps</p>
|
||
<p>B 24kbps</p>
|
||
<p>C 36kbps</p>
|
||
<p>D 48kbps</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-22 21:51:22</p>
|
||
<p>-----每日一题 Day 30------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下述有关hash冲突时候的解决方法的说法,错误的是_____(中科院计算所 1998年)</p>
|
||
<p>A 通常有两类方法处理冲突:开放定址(Open Addressing)法和拉链(Chaining)法。</p>
|
||
<p>B 开放定址更适合于造表前无法确定表长的情况</p>
|
||
<p>C 在用拉链法构造的散列表中,删除结点的操作易于实现</p>
|
||
<p>D 拉链法的缺点是:指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-19 16:56:19</p>
|
||
<p>-----每日一题 Day 29------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 主存地址为32位,按字节编址,主存和cache之间采用直接映射方式,主存块大小为4个字,每个字32位,采用回写(write back)方式,则能存放4K字数据的Cache的总容量的位数是_____(上海大学 2014年)</p>
|
||
<p>A.148K 位</p>
|
||
<p>B.158K 位</p>
|
||
<p>C.146K 位</p>
|
||
<p>D.147K 位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-19 16:55:25</p>
|
||
<p>-----每日一题 Day 29------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法错误的是_____(复旦大学 2016年)</p>
|
||
<p>A 批处理操作系统不允许用户随时干涉自己程序的运行。</p>
|
||
<p>B 单道批处理操作系统中,整个内存只用来存放一个用户程序,只有多任务操作系统中才会划分一部分空间用来存放管理程序。</p>
|
||
<p>C 用户程序中对操作系统的调用称为系统调用。实际上系统 调用指令本身是由CPU提供的机器指令,但其所调用的功能是操作系统提供的。</p>
|
||
<p>D 多机系统就是由两个或两个以上的计算机组成的计算机系统。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-19 16:54:15</p>
|
||
<p>-----每日一题 Day 29------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 一台刚刚接入互联网的WEB服务器第一次被访问到时,不同协议的发生顺序是下面中的____(杭州电子科技大学 2016年)</p>
|
||
<p>A ARP -&gt; DNS -&gt; HTTP</p>
|
||
<p>B ARP -&gt; HTTP -&gt; DNS</p>
|
||
<p>C DNS -&gt; HTTP -&gt; ARP</p>
|
||
<p>D HTTP -&gt; DNS -&gt; ARP</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-19 16:53:21</p>
|
||
<p>-----每日一题 Day 29------</p>
|
||
<p>数据结构</p>
|
||
<p>1 以下排序方式中占用O(n)辅助存储空间的是_____(安徽大学 2015年)</p>
|
||
<p>A 简单选择排序</p>
|
||
<p>B 快速排序</p>
|
||
<p>C 堆排序</p>
|
||
<p>D 二路归并排序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-18 18:14:21</p>
|
||
<p>-----每日一题 Day 28------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设某流水线计算机有一个指令和数据合一的cache,已知cache的读/写时间为10ns,主存的读/写时间为100ns,取指的命中率为98%,数据的命中率为95%,在执行程序时,约有1/5指令需要存/取一个操作数,假设指令流水线在任何时候都不阻塞。与无cache比较,设置cache后计算机的运算速度可提高____倍(大连理工大学 2013年)</p>
|
||
<p>A 2</p>
|
||
<p>B 4</p>
|
||
<p>C 8</p>
|
||
<p>D 16</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-18 18:13:32</p>
|
||
<p>-----每日一题 Day 28------</p>
|
||
<p>操作系统</p>
|
||
<p>3 通过文件名存取文件时,文件系统内部的操作过程是通过_____(南京理工大学 2014年)</p>
|
||
<p>A 文件在目录中查找文件数据存取位置。</p>
|
||
<p>B 文件名直接找到文件的数据,进行存取操作。</p>
|
||
<p>C 文件名在目录中查找对应的inode节点,通过inode节点存取文件数据。</p>
|
||
<p>D 文件名在目录中查找对应的超级块,在超级块查找对应inode节点,通过inode节点存取文件数据</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-18 18:12:33</p>
|
||
<p>-----每日一题 Day 28------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列观点正确的是_____(东南大学 2012年)</p>
|
||
<p>A 组建计算机网络的目的是实现局域网的互联</p>
|
||
<p>B 联入网络的所有计算机都必须使用同样的操作系统</p>
|
||
<p>C 网络必须采用一个具有全局资源调度能力的分布操作系统</p>
|
||
<p>D 互联的计算机是分布在不同地理位置的多台独立的自治计算机系统</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-18 18:11:39</p>
|
||
<p>-----每日一题 Day 28------</p>
|
||
<p>数据结构</p>
|
||
<p>1 有一个单向链表,头指针和尾指针分别为p,q,以下____操作的复杂度会受队列长度的影响(福州大学 2014年)</p>
|
||
<p>A 删除头部元素</p>
|
||
<p>B 删除尾部元素</p>
|
||
<p>C 头部元素之前插入一个元素</p>
|
||
<p>D 尾部元素之后插入一个元素</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-17 17:41:16</p>
|
||
<p>-----每日一题 Day 27------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 对于IEEE754单精度浮点数加减运算,只要对阶时得到的两个阶码之差的绝对值大于等于______,就无须继续进行后续处理,此时运算结果直接取阶大的那个数.(电子科技大学)</p>
|
||
<p>A.22</p>
|
||
<p>B.23</p>
|
||
<p>C.24</p>
|
||
<p>D.25</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-17 17:40:21</p>
|
||
<p>-----每日一题 Day 27------</p>
|
||
<p>操作系统</p>
|
||
<p>3 在单处理器的多进程系统中,进程什么时候占用处理器和能占用多长时间,取决于____(重庆大学 2010年)</p>
|
||
<p>A 进程相应的程序段的长度</p>
|
||
<p>B 进程自身和进程调度策略</p>
|
||
<p>C 进程总共需要运行时间多少</p>
|
||
<p>D 进程完成什么功能</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-17 17:39:13</p>
|
||
<p>-----每日一题 Day 27------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 某企业产品部的IP地址块为211.168.15.192/26,市场部的为211.168.15.160/27,财务部的为211.168.15.128/27,这三个地址块经聚合后可用地址数为_____(重庆邮电大学 2008年)</p>
|
||
<p>A 126</p>
|
||
<p>B 62</p>
|
||
<p>C 128</p>
|
||
<p>D 68</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-17 17:38:01</p>
|
||
<p>-----每日一题 Day 27------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下面关于图的存储的叙述中正确的是____(北京师范大学 2015年)</p>
|
||
<p>A 用邻接表法存储图,占用的存储空间大小只与图中边数有关,而与结点个数无关</p>
|
||
<p>B 用邻接表法存储图,占用的存储空间大小与图中边数和结点个数都有关</p>
|
||
<p>C 用邻接矩阵法存储图,占用的存储空间大小与图中结点个数和边数都有关</p>
|
||
<p>D 用邻接矩阵法存储图,占用的存储空间大小只与图中边数有关,而与结点个数无关</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-16 21:12:54</p>
|
||
<p>-----每日一题 Day 26------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol>
|
||
<li>假定一次ALU运算需要1个时钟周期,移位一次用1个时钟周期,则最快的32位原码一位乘法所需的时钟周期数大约为_____(北京大学)</li>
|
||
</ol>
|
||
<p>A.96</p>
|
||
<p>B.32</p>
|
||
<p>C.64</p>
|
||
<p>D.100</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-16 21:12:08</p>
|
||
<p>-----每日一题 Day 26------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法不正确的是______(北京航空航天大学 2012年)</p>
|
||
<p>A 子进程获得父进程的数据空间,堆和栈的复制品</p>
|
||
<p>B 线程可以与同其进程的其他线程共享数据,但是它拥有自己的栈空间且拥有独立的执行序列</p>
|
||
<p>C 线程执行开销小,但是不利于资源管理和保护</p>
|
||
<p>D 进程适合在SMP机器上进行,而线程则可以跨机器迁移</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-16 21:11:24</p>
|
||
<p>-----每日一题 Day 26------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在以下几种拓扑结构中,使用线缆数量最多的是_____(重庆邮电大学 2008年)</p>
|
||
<p>A 总线型</p>
|
||
<p>B 环型</p>
|
||
<p>C 树型</p>
|
||
<p>D 星型</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-16 21:10:17</p>
|
||
<p>-----每日一题 Day 26------</p>
|
||
<p>数据结构</p>
|
||
<p>1.已知有向图G=(V,E),其中V={a,b,c,d,e,f,g},
|
||
E={&lt;a,b&gt;,&lt;a,c&gt;,&lt;a,d&gt;,&lt;b,e&gt;,&lt;c,e&gt;,&lt;c,f&gt;,&lt;d,f&gt;,&lt;e,g&gt;,&lt;f,g&gt;}G的拓扑序列是________(北京工业大学 2013年)</p>
|
||
<p>A a,c,d,f,b,e,g</p>
|
||
<p>B a,c,b,f,d,e,g</p>
|
||
<p>C a,c,d,e,b,f,g</p>
|
||
<p>D a,b,e,c,d,f,g</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-15 18:36:50</p>
|
||
<p>-----每日一题 Day 25------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.用一台主频为40MHz的处理器执行标准测试程序, 测试程序的指令条数(I)一共5000条。它所包含的混合指令数和响应所需的时钟周期如下表给出。这个处理器的MIPS数和程序的执行时间分别为________(上海交通大学)
|
||
|
||
指令类型 CPI 指令占比</p>
|
||
<p>算术和逻辑 1 60%
|
||
|
||
高速缓存命中的访存 2 18%
|
||
|
||
转移指令 4 12%
|
||
|
||
高速缓存失效的访存 8 10%</p>
|
||
<p>A.2.24, 2.8*10^(-4)秒</p>
|
||
<p>B.2.24, 112*10^(-4)秒</p>
|
||
<p>C.17.9, 2.8*10^(-4) 秒</p>
|
||
<p>D.89.6, 112*10^(-4) 秒</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-15 18:35:12</p>
|
||
<p>-----每日一题 Day 25------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>不需要访问内存的寻址方式是_____(北京交通大学 2014年)</li>
|
||
</ol>
|
||
<p>A 直接寻址</p>
|
||
<p>B 立即寻址</p>
|
||
<p>C 间接寻址</p>
|
||
<p>D 变址寻址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-15 18:34:21</p>
|
||
<p>-----每日一题 Day 25------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>要发送的数据为11001001,采用CRC的生成多项式是P(X)=X3+X+1,则应添加在数据后面的余数为_________(北京航空航天大学 2010年)</li>
|
||
</ol>
|
||
<p>A 010</p>
|
||
<p>B 101</p>
|
||
<p>C 110</p>
|
||
<p>D 001</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-15 18:33:22</p>
|
||
<p>-----每日一题 Day 25------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>下列说法错误的是______(中国科学技术大学)</li>
|
||
</ol>
|
||
<p>A 只有在线性表的初始状态为反序的情况下,冒泡排序过程中元素的移动次数才会达到最大值。</p>
|
||
<p>B 只有在线性表的初始状态为反序的情况下,简单选择排序过程中元素的移动次数才会达到最大值。</p>
|
||
<p>C 只有在线性表的初始状态为反序的情况下,在直接插入排序过程中元素的移动次数才会达到最大值。</p>
|
||
<p>D 对n个元素进行快速排序,在进行第一次划分时,关键字的比较次数总是n一1次。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-12 15:07:30</p>
|
||
<p>-----每日一题 Day 24------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>若x=103,y=-25,则下列表达式采用8位定点补码运算实现时,会发生溢出的是_____(太原理工大学 2009年)</li>
|
||
</ol>
|
||
<p>A x+y</p>
|
||
<p>B -x+y</p>
|
||
<p>C x-y</p>
|
||
<p>D -x-y</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-12 15:06:27</p>
|
||
<p>-----每日一题 Day 24------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>在下列有关请求分页管理的叙述中,正确的是_____(厦门大学 2016年)</li>
|
||
</ol>
|
||
<p>A.程序和数据是在开始执行前一次性装入的</p>
|
||
<p>B.产生缺页中断一定要淘汰一个页面</p>
|
||
<p>C.一个淘汰的页面一定要写回外存</p>
|
||
<p>D.在页表中要有&quot;中断位&quot;、&quot;访问位&quot;等信息</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-12 15:05:27</p>
|
||
<p>-----每日一题 Day 24------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>VLAN在现代组网技术中占有重要地位,同一个VLAN中的两台主机______(西北工业大学 2014年)</li>
|
||
</ol>
|
||
<p>A 必须连接在同一交换机上</p>
|
||
<p>B 可以跨越多台交换机</p>
|
||
<p>C 必须连接在同一集线器上</p>
|
||
<p>D 可以跨越多台路由器</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-12 15:04:06</p>
|
||
<p>-----每日一题 Day 24------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>某带链的队列初始状态为 front=rear=NULL 。经过一系列正常的入队与退队操作后, front=rear=10 。该队列中的元素个数为_______(苏州大学 2009年)</li>
|
||
</ol>
|
||
<p>A.1</p>
|
||
<p>B.0</p>
|
||
<p>C.1或0</p>
|
||
<p>D.不确定</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-11 19:20:07</p>
|
||
<p>-----每日一题 Day 23------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>下列说法正确的是________(南京理工大学 2014年)</li>
|
||
</ol>
|
||
<p>A.cache是内存的一部分,它可由指令直接访问。</p>
|
||
<p>B.引入虚拟存储系统的目的,是为了加快外存的存取速度。</p>
|
||
<p>C.在计算机中,存储器是数据传送的中心,但访问存储器的请求是由CPU或I/O所发出的。</p>
|
||
<p>D.CPU中通常都设置若干个寄存器,这些寄存器与主存统一编址。访问这些寄存器的指令格式与访问存储器是相同的。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-11 19:19:02</p>
|
||
<p>-----每日一题 Day 23------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>在下述存储管理技术中,________处理不当会产生抖动。(辽宁大学 2017年)</li>
|
||
</ol>
|
||
<p>A.固定分区</p>
|
||
<p>B.可变分区</p>
|
||
<p>C.简单分页</p>
|
||
<p>D.请求分页</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-11 19:17:42</p>
|
||
<p>-----每日一题 Day 23------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>TCP/IP模型中,下列不属于网络层的协议是______(四川大学 2013年)</li>
|
||
</ol>
|
||
<p>A.IP协议</p>
|
||
<p>B.ARP协议</p>
|
||
<p>C.ICMP协议</p>
|
||
<p>D.RIP协议</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-11 19:16:08</p>
|
||
<p>-----每日一题 Day 23------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>下列排序算法中,某一趟排序结束后未必能选出一个元素放在其最终位置上的是______(南昌大学2015年)</li>
|
||
</ol>
|
||
<p>A.直接插入排序</p>
|
||
<p>B.冒泡排序</p>
|
||
<p>C.快速排序</p>
|
||
<p>D.堆排序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-10 17:41:57</p>
|
||
<p>-----每日一题 Day 22------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.存储器容量为64MB,存储字长为64位,体数m = 8,分别用顺序方式和交叉方式进行组织。一个存储周期T = 100ns,数据总线宽度为64位,总线周期为 10ns 。各从顺序存储器和交叉存储器读出8个字,传输率(单位:位/秒)各是________(上海交通大学)</p>
|
||
<p>A. 8 x 10^7, 1.7 x 10^7</p>
|
||
<p>B. 1.7 x 10^7, 8 x 10^7</p>
|
||
<p>C. 64 x 10^7, 301 x 10^7</p>
|
||
<p>D. 8 x 10^7, 64 x 10^7</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-10 17:38:53</p>
|
||
<p>-----每日一题 Day 22------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>下列说法错误的是_____(南京大学 2012年)</li>
|
||
</ol>
|
||
<p>A.在多道程序设计中,一个进程被中断后交出CPU控制权。一旦中断处理程序执行完成后,被中断的进程立即获得CPU控制权、恢复执行</p>
|
||
<p>B.中断处理中,需要保护被中断进程的所有状态信息</p>
|
||
<p>C.利用中断功能,处理器可以在I/O操作的执行过程中执行其它指令</p>
|
||
<p>D.处理多个中断有两种方法:一种方法是正在处理一个中断时,禁止再发生中断;另一种方法是允许高优先级的中断打断低优先级的中断处理程序的执行</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-10 17:37:53</p>
|
||
<p>-----每日一题 Day 22------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>在数据通信中使用曼彻斯编码主要原因是_____(杭州电子科技大学 2015年)</li>
|
||
</ol>
|
||
<p>A. 实现对通道过程中传输错误的恢复</p>
|
||
<p>B. 实现对通道过程中收发双方的数据同步</p>
|
||
<p>C.提高对数据的有效传输速率</p>
|
||
<p>D.提高传输信号的抗干扰能力</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-10 17:36:53</p>
|
||
<p>-----每日一题 Day 22------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>以下________排序算法的最坏时间复杂度可以做到O(nlog(n))(暨南大学 2010年)</li>
|
||
</ol>
|
||
<p>A.归并排序</p>
|
||
<p>B.快速排序</p>
|
||
<p>C.冒泡排序</p>
|
||
<p>D.插入排序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-09 22:16:42</p>
|
||
<p>-----每日一题 Day 21------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.下列说法错误的是______(上海大学 2016年)</p>
|
||
<p>A.动态RAM和静态RAM都是易失性半导体存储器</p>
|
||
<p>B.计算机的内存由RAM和ROM两种半导体存储器组成。</p>
|
||
<p>C.个人微机使用过程中,突然断电RAM中保存的信息全部丢失,而ROM中保存的信
|
||
息不受影响。</p>
|
||
<p>D.CPU存储器容量越大,访问存储器所需的时间越长。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-09 22:15:52</p>
|
||
<p>-----每日一题 Day 21------</p>
|
||
<p>操作系统</p>
|
||
<p>3.单处理机计算机系统中,______是并行操作的。(中国人民大学 2014年)</p>
|
||
<p>A.处理机操作和通道操作</p>
|
||
<p>B.程序与程序</p>
|
||
<p>C.主程序与子程序</p>
|
||
<p>D.用户程序与操作系统程序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-09 22:14:59</p>
|
||
<p>-----每日一题 Day 21------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>下面关于以太网的描述正确的是_____(四川大学 2013年)</li>
|
||
</ol>
|
||
<p>A.数据是以广播方式发送的</p>
|
||
<p>B.所有节点可以同时发送和接收数据</p>
|
||
<p>C.节点若要发送数据时,检测到总线忙,就不再继续检测</p>
|
||
<p>D.网络中有一个控制中心,用于控制所有节点的发送和接收</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-09 22:14:00</p>
|
||
<p>-----每日一题 Day 21------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>假设在有序线性表A[1..30]上进行二分查找,则比较五次查找成功的结点数为______(厦门大学 2018年)</li>
|
||
</ol>
|
||
<p>A.8</p>
|
||
<p>B.12</p>
|
||
<p>C.15</p>
|
||
<p>D.16</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-08 18:29:32</p>
|
||
<p>-----每日一题 Day 20------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.给定一个32位 Linux 系统,系统中有一个数据容量为128 bytes的2路组关联映射cache,每个cache block的大小为32 bytes. Long long 数据类型的长度为8 bytes, int数据类型的长度为4 bytes. 对如下程序,假设 table数组的内存起始地址是0x0.</p>
|
||
<p>int i, int j; </p>
|
||
<p>int table[4][8];
|
||
|
||
for (j = 0;
|
||
j &lt; 8; j++)
|
||
for (i = 0; i &lt; 4; i++)
|
||
|
||
table[i][j] = i + j;
|
||
|
||
table中元素的访问,cache缺失率为_______(上海交通大学)</p>
|
||
<p>A.1</p>
|
||
<p>B.1/4</p>
|
||
<p>C.1/8</p>
|
||
<p>D.1/16</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-08 18:27:26</p>
|
||
<p>-----每日一题 Day 20------</p>
|
||
<p>操作系统</p>
|
||
<p>3.某文件系统采用位示图法管理外存储空间,每个磁盘块4KB,已知一块磁盘容量为40GB,则表示该磁盘所需的位示图需要占用_______的内存空间(广东工业大学 2018年)</p>
|
||
<p>A.1280KB</p>
|
||
<p>B.10240KB</p>
|
||
<p>C.4096KB</p>
|
||
<p>D.10MB</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-08 18:26:32</p>
|
||
<p>-----每日一题 Day 20------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.以下各项中,不是数据报操作特点的是______(华中科技大学 2011年)</p>
|
||
<p>A.每个分组自身携带有足够的信息,它的传送是被单独处理的</p>
|
||
<p>B.在整个传送过程中,不需建立虚电路</p>
|
||
<p>C.使所有分组按顺序到达目的端系统</p>
|
||
<p>D.网络节点要为每个分组做出路由选择</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-08 18:25:26</p>
|
||
<p>-----每日一题 Day 20------</p>
|
||
<p>数据结构</p>
|
||
<p>1.一棵二叉树的前序遍历序列为ABCDEFG,它的中序遍历序列可能是______(湖南大学 2015年)</p>
|
||
<p>A.CABDEFG</p>
|
||
<p>B.ABCDEFG</p>
|
||
<p>C.DACEFBG</p>
|
||
<p>D.DBCEAFG</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-05 17:34:18</p>
|
||
<p>-----每日一题 Day 19------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>下列说法正确的是______(大连理工大学 2015年)</li>
|
||
</ol>
|
||
<p>A.浮点数的正负由阶码的正负符号决定。</p>
|
||
<p>B.在CPU中执行算术运算和逻辑运算,都是按位进行且各位之间是独立无关的。</p>
|
||
<p>C.全加器和半加器的区别在于是否考虑低位向高位进位。</p>
|
||
<p>D.加法器是构成运算器的基本部件,为提高运算速度,运算器一般都采用串行加法器。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-05 17:33:23</p>
|
||
<p>-----每日一题 Day 19------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>在 Windows操作系统中,磁盘维护包括硬盘的检查、清理和碎片整理等功能,碎片整理的目的是______(广东工业大学 2013年)</li>
|
||
</ol>
|
||
<p>A.删除磁盘小文件</p>
|
||
<p>B.获得更多磁盘可用空间</p>
|
||
<p>C.优化磁盘文件存储</p>
|
||
<p>D.改善磁盘的清洁度</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-05 17:32:25</p>
|
||
<p>-----每日一题 Day 19------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>下列选项中,对正确接收到的数据帧进行确认的MAC协议是_____(东南大学 2013年)</li>
|
||
</ol>
|
||
<p>A.CSMA</p>
|
||
<p>B.CDMA</p>
|
||
<p>C.CSMA/CD</p>
|
||
<p>D.CSMA/CA</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-05 17:31:02</p>
|
||
<p>-----每日一题 Day 19------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>已知 10 个元素 (54,28,16,34,,73,62,95,60,26,43) ,按照依次插入的方法生成一棵二叉排序树,查找值为 62 的结点所需比较次数为_____(复旦大学 2014年)</li>
|
||
</ol>
|
||
<p>A. 2</p>
|
||
<p>B. 3</p>
|
||
<p>C. 4</p>
|
||
<p>D. 5</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-04 18:24:24</p>
|
||
<p>-----每日一题 Day 18------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>某计算机的控制器采用微程序控制方式,微指令中的操作控制字段采用字段直接编码法,共有33 个微命令,构成 5 个互斥类,分别包含 7、 3、 12、 5 和 6 个微命令,则操作控制字段至少有______(大连理工大学 2015年)</li>
|
||
</ol>
|
||
<p>A.5位</p>
|
||
<p>B.6位</p>
|
||
<p>C.15位</p>
|
||
<p>D.33位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-04 18:22:40</p>
|
||
<p>-----每日一题 Day 18------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>在微机系统中,对输入输出设备进行管理的基本程序模块(BIOS)存放在________(复旦大学 2014年)</li>
|
||
</ol>
|
||
<p>A.RAM中</p>
|
||
<p>B.ROM中</p>
|
||
<p>C.硬盘中</p>
|
||
<p>D.寄存器中</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-04 18:21:44</p>
|
||
<p>-----每日一题 Day 18------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>下面关于虚拟局域网 VLAN 的叙述错误的是 _____(东南大学 2013年)</li>
|
||
</ol>
|
||
<p>A.VLAN是由一些局域网网段构成的与物理位置无关的逻辑组。</p>
|
||
<p>B.利用以太网交换机可以很方便地实现VLAN。</p>
|
||
<p>C.每一个VLAN的工作站可处在不同的局域网中。</p>
|
||
<p>D.虚拟局域网是一种新型局域网。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-04 18:20:07</p>
|
||
<p>-----每日一题 Day 18------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>下面关于B和B+树的叙述中,不正确的是______(福州大学 2011年)</li>
|
||
</ol>
|
||
<p>A.B树和B+树都是平衡的多叉树。</p>
|
||
<p>B.B树和B+树都可用于文件的索引结构。</p>
|
||
<p>C.B树和B+树都能有效地支持顺序检索。</p>
|
||
<p>D.B树和B+树都能有效地支持随机检索。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-03 17:31:05</p>
|
||
<p>-----每日一题 Day 17------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>假定采用多模块交叉存储器组织方式,存储器芯片和总线支持突发传送,CPU通过存储器总线读取数据的过程为:发送首地址和读命令需1个时钟周期,存储器准备第一个数据需8个时钟周期,随后每个时钟周期总线上传送1个数据,可连续传送8个数据。若主存和cache之间交换的主存块大小为64B,存储宽度和总线宽度都为8B,则cache的一次缺失损失(缺失开销)至少为______个时钟周期。(北京理工大学 2011年)</li>
|
||
</ol>
|
||
<p>A.33</p>
|
||
<p>B.20</p>
|
||
<p>C.17</p>
|
||
<p>D.65</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-03 17:29:57</p>
|
||
<p>-----每日一题 Day 17------</p>
|
||
<p>操作系统</p>
|
||
<p>3.下面关于采用抢占式调度方式系统中系统调用完成时返回的描述,不正确的是_______(北京大学 2014年)</p>
|
||
<p>A.只有当调用者进程仍具有最高优先级时,才返回到调用者进程继续执行</p>
|
||
<p>B.引发重新调度</p>
|
||
<p>C.无条件返回调用者进程,从调用位置的下一条指令处继续执行</p>
|
||
<p>D.有可能把调用者进程放入就绪队列而执行别的进程</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-03 17:28:42</p>
|
||
<p>-----每日一题 Day 17------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.在 TCP 协议中,建立连接时需要将_____字段中的_______标志位置 1。(北京航空航天大学 2014年)</p>
|
||
<p>A.保留,ACK</p>
|
||
<p>B.保留,SYN</p>
|
||
<p>C.偏移,ACK</p>
|
||
<p>D.控制,SYN</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-03 17:27:33</p>
|
||
<p>-----每日一题 Day 17------</p>
|
||
<p>数据结构</p>
|
||
<p>1.一组记录的关键字为{25,48,16,35,79,82,23,40,36,72},其中,含有5个长度为2的有序表,按归并排序的方法对该序列再进行一趟归并后的结果为_______(北京工业大学 2011年)</p>
|
||
<p>A.16,25,35,48,23,40,79,82,36,72</p>
|
||
<p>B.16,25,35,48,79,82,23,36,40,72</p>
|
||
<p>C.16,25,48,35,79,82,23,36,40,72</p>
|
||
<p>D.16,25,35,48,79,23,36,40,72,82</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-02 20:12:39</p>
|
||
<p>-----每日一题 Day 16------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.某32位计算机的cache容量为16KB,cache行的大小为16B,若主存与cache地址映像采用直接映像方式,则主存地址为0x1234E8F8的单元装入cache的地址是_______(北京科技大学 2012年)
|
||
|
||
A.00010001001101;</p>
|
||
<p>B.11010011101000;</p>
|
||
<p>C.01000100011010;</p>
|
||
<p>D.10100011111000;</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-02 20:11:50</p>
|
||
<p>-----每日一题 Day 16------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>下列关于操作系统的各种功能的说法,正确的是______(北京交通大学 2016年)</li>
|
||
</ol>
|
||
<p>A.虚拟存储器&quot;其实是外存</p>
|
||
<p>B.文件管理可以实现文件的共享,保密和保护</p>
|
||
<p>C.用户必须了解设备及接口的技术细节,才能使设备和计算机协调工作</p>
|
||
<p>D.作业管理的任务主要是使内存资源得到合理使用。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-02 20:10:47</p>
|
||
<p>-----每日一题 Day 16------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.假如正在构建一个有22个子网的B类网络,但不久后该网络有可能会增至80个子网,同时每个子网要求支持至少300个主机,那么应该选择_____子网掩码(北京邮电大学 2015年)
|
||
|
||
A.255.255.248.0</p>
|
||
<p>B.255.255.255.0</p>
|
||
<p>C.255.255.254.0</p>
|
||
<p>D.255.255.0.0</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-02 20:09:55</p>
|
||
<p>-----每日一题 Day 16------</p>
|
||
<p>数据结构</p>
|
||
<p>1.数据表A中有10000个元素,如果仅要求找出其中最大的10个元素,则采用_______方法最节省时间(安徽大学 2015年)</p>
|
||
<p>A.堆排序</p>
|
||
<p>B.希尔排序</p>
|
||
<p>C.快速排序</p>
|
||
<p>D.基数排序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-01 22:00:04</p>
|
||
<p>-----每日一题 Day 15------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.下列说法正确的是_______(上海大学 2015年)</p>
|
||
<p>A.一个正数的补码和这个数的原码表示一样,而正数的反码就不是该数的原码表示,而是原码各位数取反。</p>
|
||
<p>B.表示定点数时,若要求数值0在计算机中惟一地表示为全0,应使用反码表示。</p>
|
||
<p>C.将补码的符号位改用多位来表示,就变成变形补码,一个用双符号位表示的变形补码01.1010是正数。</p>
|
||
<p>D.浮点数的取值范围由阶码的位数决定,而浮点数的精度由尾数的位数决定。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-01 21:59:09</p>
|
||
<p>-----每日一题 Day 15------</p>
|
||
<p>操作系统</p>
|
||
<p>3.在SPOOLing系统中,用户进程实际分配到的是________。(北京交通大学 2014年)
|
||
A.一块内存区,即虚拟设备</p>
|
||
<p>B.共享设备的一部分存储区</p>
|
||
<p>C.用户所要求的外设</p>
|
||
<p>D.虚拟设备的一部分空间</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-01 21:58:17</p>
|
||
<p>-----每日一题 Day 15------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.一个数据报长度为4000字节(固定首部长度)。现在经过一个网络传送,但此网络能够传送的最大数据长度为1500字节。最后一个数据报片的片偏移字段为_____(杭州电子科技大学 2013年)</p>
|
||
<p>A. 360</p>
|
||
<p>B. 365</p>
|
||
<p>C. 370</p>
|
||
<p>D. 375</p>
|
||
<hr>
|
||
<p>该题更新于:2022-08-01 21:56:59</p>
|
||
<p>-----每日一题 Day 15------</p>
|
||
<p>数据结构</p>
|
||
<p>1.设哈希表长m=14,哈希函数H(key)=key MOD 11。表中已有4个节点addr(15)=4,addr(38)=5,addr(61)=6,addr(84)=7,其余地址为空,如用二次探查再散列法处理冲突,则关键字为49的节点的地址是_______(上海科技大学 2016年)</p>
|
||
<p>A.8</p>
|
||
<p>B.3</p>
|
||
<p>C.5</p>
|
||
<p>D.9</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-29 21:58:23</p>
|
||
<p>-----每日一题 Day 14------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>下列说法正确的是______(清华大学 2012年)</li>
|
||
</ol>
|
||
<p>A. 兼容性是计算机的一个重要性能,通常是指向上兼容,即旧型号计算机的软件可以不加修改地在新型号计算机上运行。系列机通常月有这种兼容性。</p>
|
||
<p>B.决定计算机计算精度的主要技术指标是计算机的字长。</p>
|
||
<p>C.计算机&quot;运算速度”指标的含义是指每秒钟能执行多少条操作系统的命令。</p>
|
||
<p>D.利用大规模集成电路技术把计算机的运算部件和控制部件做在一块集成电路芯片上,这样的一块芯片叫做单片机。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-29 21:57:35</p>
|
||
<p>-----每日一题 Day 14------</p>
|
||
<p>操作系统</p>
|
||
<p>3.在请求分页存储管理中,若采用FIFO页面淘汰算法,则当分配 的页面数增加时,缺页中断的次数________。 (厦门大学 2010年)</p>
|
||
<p>A. 减少</p>
|
||
<p>B. 增加</p>
|
||
<p>C. 无影响</p>
|
||
<p>D.可能增加也可能减少</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-29 21:52:10</p>
|
||
<p>-----每日一题 Day 14------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.一个网络有几个子网,其中的一个已经分配了子网掩码74.178.247.96/29。下列网络前缀中的________不能再分配给其他的子网(重庆大学 2010年)</p>
|
||
<p>A. 74.178.247.120/29;</p>
|
||
<p>B. 74.178.247.64/29;</p>
|
||
<p>C. 74.178.247.80/28;</p>
|
||
<p>D. 74.178.247.104/29</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-29 21:51:17</p>
|
||
<p>-----每日一题 Day 14------</p>
|
||
<p>1.设有无向图G=(V,E)和G'=(V',E'),若G'是G的生成树,则下面说法不正确的是______(苏州大学 2009年)</p>
|
||
<p>A.G'为G的连通分量</p>
|
||
<p>B.G'是G的无环子图</p>
|
||
<p>C.G'为G的子图</p>
|
||
<p>D.G'为G的极小连通子图且V'=V</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-28 21:51:13</p>
|
||
<p>-----每日一题 Day 13------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.某中断系统中,每抽取一个输入数据就要中断CPU一次,中断处理程序接收取样的数据,并将其保存到主存缓冲区内,该中断处理需要X秒。另一方面,缓冲区内每存储N个数据,主程序就将其取出进行处理,这种处理需要Y秒。因此,该系统可以每秒跟踪______次中断请求。(西安交通大学 2014年)</p>
|
||
<p>A.N/(NX +Y)</p>
|
||
<p>B.N/(X+Y)N</p>
|
||
<p>C.min[1/X,1/Y]</p>
|
||
<p>D.max[1/X,1/Y]</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-28 21:50:27</p>
|
||
<p>-----每日一题 Day 13------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>在虚拟存储系统中,若进程在内存中占3块(开始时为空),采 用先进先出页面淘汰算法,当执行访问页号序列为1、2、3、4、1、 2、5、1、2、3、4、5、6时,将产生________次缺页中断。 (西安电子科技大学 2015年)</li>
|
||
</ol>
|
||
<p>A. 7</p>
|
||
<p>B. 8</p>
|
||
<p>C. 9</p>
|
||
<p>D. 10</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-28 21:49:34</p>
|
||
<p>-----每日一题 Day 13------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.一个3200bit长的TCP报文传到IP层,加上160bit的首部后成为数据报。下面的互联网由两个局域网通过路由器连接起来。但第二个局域网所能传送的最长数据帧中的数据部分只有1200bit。因此数据报在路由器必须进行分片。则第二个局域网向其上层要传送________比特的数据(西北工业大学 2010年)</p>
|
||
<p>A. 3360</p>
|
||
<p>B. 3520</p>
|
||
<p>C. 3680</p>
|
||
<p>D. 3760</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-28 21:48:47</p>
|
||
<p>-----每日一题 Day 13------</p>
|
||
<p>数据结构</p>
|
||
<p>1.若一个有向图中的顶点不能排成一个拓扑序列,则可断定该有向图______(武汉科技大学 2013年)</p>
|
||
<p>A.是个有根有向图</p>
|
||
<p>B.是个强连通图</p>
|
||
<p>C.含有多个入度为0的顶点</p>
|
||
<p>D.含有顶点数目大于1的强连通分量</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-27 21:22:57</p>
|
||
<p>-----每日一题 Day 12------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>下面内存管理方法中有利于程序动态链接的是________。(中国人民大学 2015年)</li>
|
||
</ol>
|
||
<p>A.分段存储管理</p>
|
||
<p>B.分页存储管理</p>
|
||
<p>C.可变分区分配</p>
|
||
<p>D.固定分区分配</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-27 21:22:14</p>
|
||
<p>-----每日一题 Day 12------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>下面情况下,可能不发生中断请求的是_____(中科院 2014年)</li>
|
||
</ol>
|
||
<p>A.DMA操作结束</p>
|
||
<p>B.一条指令执行完毕</p>
|
||
<p>C.机器出现故障</p>
|
||
<p>D.执行&quot;软中断”指令</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-27 21:20:26</p>
|
||
<p>-----每日一题 Day 12------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>下列关于IP地址说法错误的是_____(中国海洋大学 2010年)</li>
|
||
</ol>
|
||
<p>A.IP地址不能反映任何有关主机位置的物理信息:</p>
|
||
<p>B.一个主机同时连接在多个网络上时,该主机只能拥有一个自己的IP地址:</p>
|
||
<p>C.由转发器或网桥连接起来的若干个局域网仍为一个网络:</p>
|
||
<p>D.IP地址可用来指明一个网络的地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-27 21:19:31</p>
|
||
<p>-----每日一题 Day 12------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>判定一个有向图是否存在回路除了可以利用拓扑排序方法外,还可以用_____(中国石油大学 2013年)</li>
|
||
</ol>
|
||
<p>A.求关键路径的方法</p>
|
||
<p>B.求最短路径的Dijkstra方法</p>
|
||
<p>C.广度优先遍历算法</p>
|
||
<p>D.深度优先遍历算法</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-26 21:25:16</p>
|
||
<p>-----每日一题 Day 11------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.以下论述正确的是_______(哈尔滨工业大学 2010年)</p>
|
||
<p>A.CPU响应中断期间仍执行原程序</p>
|
||
<p>B.在中断过程中,若又有中断源提出中断,CPU立即响应</p>
|
||
<p>C.在中断响应中,保护断点、保护现场应由用户编程完成</p>
|
||
<p>D.在中断响应中,保护断点是由中断响应自动完成的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-26 21:24:06</p>
|
||
<p>-----每日一题 Day 11------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>在可变式分区分配方案中,某一作业完成后,系统收回其主存空 间,并与相邻空闲区合并,为此需修改空闲区表,造成空闲区数减1的 情况是________。 (西安电子科技大学 2012年)</li>
|
||
</ol>
|
||
<p>A. 无上邻空闲区,也无下邻空闲区</p>
|
||
<p>B. 有上邻空闲区,但无下邻空闲区</p>
|
||
<p>C. 有下邻空闲区,但无上邻空闲区</p>
|
||
<p>D. 有上邻空闲区,也有下邻空闲区</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-26 21:23:06</p>
|
||
<p>-----每日一题 Day 11------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>下列关于流量控制和拥塞控制说法正确的是_____(南京大学 2011年)</li>
|
||
</ol>
|
||
<p>A流量控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。</p>
|
||
<p>B.流量控制往往指在给定的发送端和接收端之间的点对点通信量的控制。</p>
|
||
<p>C..拥塞控制几乎总是涉及到接收者,接收者要向发送者反馈另一端情况的一些信息。</p>
|
||
<p>D.拥塞控制体现在接收者不能跟上输入速度,流量控制体现在主机因网络承受能力有限而收到减慢发送的消息。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-26 21:21:57</p>
|
||
<p>-----每日一题 Day 11------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>带权有向图G用邻接矩阵A存储,则顶点i的入度等于A中_______(扬州大学 2013年)</li>
|
||
</ol>
|
||
<p>A.第i行非∞的元素之和</p>
|
||
<p>B.第i列非∞的元素之和</p>
|
||
<p>C.第i行非∞且非0的元素个数</p>
|
||
<p>D.第i列非∞且非0的元素个数</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-25 21:33:10</p>
|
||
<p>-----每日一题 Day 10------</p>
|
||
<p>计算机组成原理</p>
|
||
<ol start="4">
|
||
<li>微型机系统中,主机和高速硬盘进行数据交换一般采用________方式。(北京科技大学 2014年)</li>
|
||
</ol>
|
||
<p>A.程序中断控制</p>
|
||
<p>B.直接存储器存取(DMA)</p>
|
||
<p>C.程序直接控制</p>
|
||
<p>D.通道控制</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-25 21:32:16</p>
|
||
<p>-----每日一题 Day 10------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>分区存储管理方案不能采用虚存技术的原因是________。(电子科技大学 2009年)</li>
|
||
</ol>
|
||
<p>A.分区存储管理要求作业分次全部装入主存</p>
|
||
<p>B.分区存储管理要求作业分次全部装入主存,并一直驻留内存直 到运行结束</p>
|
||
<p>C.分区存储管理作业可以部分装入主存但装入部分必须连续存放</p>
|
||
<p>D.分区存储管理要求作业一次性全部装入主存,并连续存放</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-25 21:31:19</p>
|
||
<p>-----每日一题 Day 10------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>下列关于PPP协议说法错误的是______(北京邮电大学 2013年)</li>
|
||
</ol>
|
||
<p>A. PPP协议是一种面向字节的协议</p>
|
||
<p>B. PPP协议所有的帧长度都是整数个字节</p>
|
||
<p>C. PPP协议使用一种特殊的字符填充法完成数据的填充</p>
|
||
<p>D. PPP协议提供使用序号和确认的可靠传输。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-25 21:30:26</p>
|
||
<p>-----每日一题 Day 10------</p>
|
||
<p>数据结构</p>
|
||
<ol>
|
||
<li>如果一棵二叉树的先序序列是…a…b…,中序序列是…b…a…,则_______(北京师范大学 2015年)</li>
|
||
</ol>
|
||
<p>A.节点a和节点b分别在某节点的左子树和右子树中</p>
|
||
<p>B.节点b在节点a的右子树中</p>
|
||
<p>C.节点b在节点a的左子树中</p>
|
||
<p>D.节点a和节点b分别在某节点的两棵非空子树中</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-22 17:10:11</p>
|
||
<p>-----每日一题 Day 9------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.计算机中常采用下列几种编码表示数据,其中,±0编码相同的是_______(杭州电子科技大学 2012年)</p>
|
||
<p>Ⅰ.原码
|
||
Ⅱ.反码
|
||
Ⅲ.补码 <br>
|
||
Ⅳ.移码</p>
|
||
<p>A.I和Ⅲ</p>
|
||
<p>B.Ⅱ和Ⅲ</p>
|
||
<p>C.Ⅲ和IV</p>
|
||
<p>D.I和IV</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-22 17:07:41</p>
|
||
<p>-----每日一题 Day 9------</p>
|
||
<p>操作系统</p>
|
||
<p>3.进程和程序的本质区别是_______(华东师范大学 2012年)</p>
|
||
<p>A.进程存储在内存,程序存储在外存</p>
|
||
<p>B.进程是非顺序执行机器指令,程序是顺序执行机器指令</p>
|
||
<p>C.进程是分时使用计算机资源,程序是独占计算机资源</p>
|
||
<p>D.进程具有动态特征,程序具有静态特征</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-22 17:06:29</p>
|
||
<p>-----每日一题 Day 9------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.在某协议中,一个站点有数据要发送时,首先侦听信道:若信道为空,则按一定概率发送数据;若信道为忙,则一直监听至空闲,然后以一定概率发送数据。这个协议是_____(重庆大学 2019年)</p>
|
||
<p>A.1-坚持CSMA</p>
|
||
<p>B.非坚持CSMA</p>
|
||
<p>C.P-坚持CSMA</p>
|
||
<p>D.传递轮询</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-22 17:05:07</p>
|
||
<p>-----每日一题 Day 9------</p>
|
||
<p>数据结构</p>
|
||
<p>1.如果用孩子兄弟链来表示一棵具有n(n&gt;1)个节点的树,则在该存储结构中______(河海大学 2012年)</p>
|
||
<p>A.至多有n一1个非空的右指针域</p>
|
||
<p>B.至少有两个空的右指针域</p>
|
||
<p>C.至少有两个非空的左指针域</p>
|
||
<p>D.至多有n一1个空的右指针域</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-21 21:26:22</p>
|
||
<p>-----每日一题 Day 8------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.在微程序控制器中,机器指令和微指令的关系是_______(西北工业大学 2014年)</p>
|
||
<p>A.每一条机器指令由一条微指令来执行</p>
|
||
<p>B.一条微指令由若干条机器指令组成</p>
|
||
<p>C.每一条机器指令由一段用微指令组成的微程序来解释执行</p>
|
||
<p>D.一段微程序由一条机器指令来执行</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-21 21:25:31</p>
|
||
<p>-----每日一题 Day 8------</p>
|
||
<p>操作系统</p>
|
||
<p>3.当作业进入完成状态,操作系统________。 (西北大学 2012年)</p>
|
||
<p>A.将删除该作业并收回所占资源,同时输出结果</p>
|
||
<p>B.将该作业的控制块从当前作业队列中删除,收回其所占资源, 并输出结果</p>
|
||
<p>C.将收回该作业所占资源并输出结果</p>
|
||
<p>D.将输出结果并删除内存中的作业</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-21 21:24:42</p>
|
||
<p>-----每日一题 Day 8------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.关于TCP/IP协议的描述中,说法错误的是_______(中国海洋大学 2012年)</p>
|
||
<p>A.地址解析协议ARP属于应用层</p>
|
||
<p>B.TCP、UDP协议都要通过IP协议来发送、接收数据</p>
|
||
<p>C.TCP协议提供可靠的面向连接服务</p>
|
||
<p>D.UDP协议提供简单的无连接服务</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-21 21:23:30</p>
|
||
<p>-----每日一题 Day 8------</p>
|
||
<p>数据结构</p>
|
||
<p>1.对于一棵具有n个节点、度为4的树来说_________(中国农业大学 2013年)</p>
|
||
<p>A.树的高度至多是n一3</p>
|
||
<p>B.树的高度至多是n一4</p>
|
||
<p>C.第i层上至多有4*(i-1)个节点</p>
|
||
<p>D.至少在某一层上正好有4个节点</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-20 18:56:12</p>
|
||
<p>-----每日一题 Day 7------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.下列有关存储器的描述中,不正确的是_________(哈尔滨工业大学 2011年)</p>
|
||
<p>A.多体交叉存储器主要解决内存的速度问题</p>
|
||
<p>B.访问存储器的请求是由CPU发出的</p>
|
||
<p>C.cache.与主存统一编址,即主存空间的某一部分属于cache</p>
|
||
<p>D.cache的功能全由硬件实现</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-20 18:55:09</p>
|
||
<p>-----每日一题 Day 7------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>下列说法正确的是________。(复旦大学 2015年)</li>
|
||
</ol>
|
||
<p>A.进程轮转调度算法是一种非剥夺式调度方式</p>
|
||
<p>B.若现行进程等待某一事件时引起调度,则该系统采用的是剥夺式调度</p>
|
||
<p>C.实时操作系统中通常采用剥夺式调度方式</p>
|
||
<p>D.在剥夺式系统中,进程的周转时间较之非剥夺式系统是可预见的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-20 18:53:38</p>
|
||
<p>-----每日一题 Day 7------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>以太网上只有两个站,它们同时发送数据,产生了碰撞。于是按二进制指数类型退避算法进行重传。重传次数记为i, i=1,2,3。第3次重传失败的概率为_______(东南大学 2017年)</li>
|
||
</ol>
|
||
<p>A. 0.5</p>
|
||
<p>B. 0.25</p>
|
||
<p>C. 0.125</p>
|
||
<p>D. 0.0625</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-20 18:52:26</p>
|
||
<p>-----每日一题 Day 7------</p>
|
||
<p>数据结构</p>
|
||
<p>1.对稀疏矩阵采用压缩存储,其缺点之一是_______(福州大学 2014年)</p>
|
||
<p>A.无法判断矩阵有多少行多少列</p>
|
||
<p>B.无法根据行列号查找某个矩阵元素</p>
|
||
<p>C.无法根据行列号计算矩阵元素的存储地址</p>
|
||
<p>D.使矩阵元素之间的逻辑关系更加复杂</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-19 20:16:59</p>
|
||
<p>-----每日一题 Day 6------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.关于二地址指令以下论述正确的是________(合肥工业大学 2014年)</p>
|
||
<p>A.二地址指令中,运算结果通常存放在其中一个地址码所提供的地址中</p>
|
||
<p>B.二地址指令中,指令的地址码字段存放的一定是操作数</p>
|
||
<p>C.二地址指令中,指令的地址码字段存放的一定是寄存器号</p>
|
||
<p>D.指令的地址码字段存放的一定是操作数地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-19 20:16:07</p>
|
||
<p>-----每日一题 Day 6------</p>
|
||
<p>操作系统</p>
|
||
<p>3.下列各项工作步骤,________不是创建进程所必需的步骤。(广东工业大学 2015年)</p>
|
||
<p>A.建立一个PCB</p>
|
||
<p>B.由CPU调度程序为进程调度CPU</p>
|
||
<p>C.为进程分配内存等必要资源</p>
|
||
<p>D.将PCB链入进程就绪队列</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-19 20:15:15</p>
|
||
<p>-----每日一题 Day 6------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.当处于同一个局域网中的两个设备拥有相同的静态MAC地址时将会发生______(杭州电子科技大学 2015年)</p>
|
||
<p>A.·先启动的设备可以使用该地址,另一个设备则无法通信</p>
|
||
<p>B.后启动的设备可以使用该地址,另一个设备则无法通信</p>
|
||
<p>C.两个设备都无法正常通信</p>
|
||
<p>D.两个设备都可以正常通信,由于它]可以阅读整个分组的内容,并知道哪个分组
|
||
是发送给自己而不是其他设备的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-19 20:13:57</p>
|
||
<p>-----每日一题 Day 6------</p>
|
||
<p>数据结构</p>
|
||
<p>1.设栈S和队列Q的初始状态为空,元素e1-e6依次通过栈S,一个元素出栈后即入队列Q,若6个元素出队的序列是e2、e4、e3、e6、e5、e1,则栈S的容量至少应该是_______(湖南大学 2016年)</p>
|
||
<p>A.5</p>
|
||
<p>B.4</p>
|
||
<p>C.3</p>
|
||
<p>D.2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-18 17:11:23</p>
|
||
<p>-----每日一题 Day 5------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.某一SRAM芯片,其容量为512×8位,除电源端和接地端外,该芯片引出线的最小数目应为_____(华东师范大学 2012年)</p>
|
||
<p>A.23</p>
|
||
<p>B.25</p>
|
||
<p>C.50</p>
|
||
<p>D.19</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-18 17:10:20</p>
|
||
<p>-----每日一题 Day 5------</p>
|
||
<p>操作系统</p>
|
||
<ol start="3">
|
||
<li>下列有关进程的描述中,不正确的是________。 (辽宁大学 2016年)</li>
|
||
</ol>
|
||
<p>A. 进程是在多程序并行环境中的完整的程序</p>
|
||
<p>B. 进程可以由程序,数据和进程控制块描述</p>
|
||
<p>C. 进程是程序在处理机上的一次执行过程,是一个动态概念</p>
|
||
<p>D. 进程是程序在一个数据集合上运行的过程,它是系统进行资源 分配和调度的单位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-18 17:08:49</p>
|
||
<p>-----每日一题 Day 5------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>信道速率为4kb/s。采用停止等待协议。传播时延t=20ms。确认帧长度和处理时间均可忽略。帧长为______才能使信道利用率达到至少50%.(南京大学 2015年)</li>
|
||
</ol>
|
||
<p>A. 80bit</p>
|
||
<p>B. 100bit</p>
|
||
<p>C. 160bit</p>
|
||
<p>D. 200bit</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-18 17:07:37</p>
|
||
<p>-----每日一题 Day 5------</p>
|
||
<p>数据结构</p>
|
||
<p>1.假设用Q[0..M]实现环形队列,f作为队头指针指向队头元素的前一个位置,r作为队尾指针指向队尾元素。若用(r+1)%(M+1)==f作为队满的标志,则_________(上海科技大学 2017年)</p>
|
||
<p>A.可用f==r作为队空的标志</p>
|
||
<p>B.可用f&gt;r作为队空的标志</p>
|
||
<p>C.可用(f+1)%(M+1)==r作为队空的标志
|
||
D.队列中最多可以有M+1个元素</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-15 16:25:52</p>
|
||
<p>-----每日一题 Day 4------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.字长12位,用定点补码规格化小数表示时,所能表示的正数范围是_______(西安交通大学 2018)
|
||
A. 2^-12~(1-2^-12)
|
||
B. 2^-11~(1-2^-11)
|
||
C.1/2~(1-2^-11)
|
||
D. (1/2+2^-11)~(1-2^-11)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-15 16:19:46</p>
|
||
<p>-----每日一题 Day 4------</p>
|
||
<p>操作系统</p>
|
||
<p>3.下面叙述正确的是________。 (中科院 2015)</p>
|
||
<p>A. 中断服务程序的后一条指令是无条件转移指令
|
||
B. 中断响应过程是由硬件和中断服务程序共同完成的</p>
|
||
<p>C. 在每条指令执行过程中,每个总线周期都要检查一次有无中断请求</p>
|
||
<p>D. 检测有无DMA请求,通常安排在一条指令执行过程的末尾</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-15 16:17:16</p>
|
||
<p>-----每日一题 Day 4------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.长度为100字节的应用层数据交给传输层传送,需加20字节的TCP首部。再交给网络层传送,需加上20字节的IP首部。最后交给数据链路层的以太网传送,再加上首部和尾部共18字节。数据的传输效率是________.(中国人民大学 2019)</p>
|
||
<p>A.63.3%</p>
|
||
<p>B.72.5%</p>
|
||
<p>C.56.2%</p>
|
||
<p>D.71.4%</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-15 16:13:07</p>
|
||
<p>-----每日一题 Day 4------</p>
|
||
<p>数据结构</p>
|
||
<p>1.下列说法正确的是_______(中国农业大学 2015)</p>
|
||
<p>A.分配给单链表的内存单元地址必须是连续的。</p>
|
||
<p>B.与顺序表相比,在链表中顺序访问所有节点,其算法的效率比较低。</p>
|
||
<p>C.从长度为n的顺序表中删除任何一个元素,时间复杂度都是O(1)。
|
||
D.向顺序表中插人一个元素,平均要移动大约一半的元素。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-14 21:51:32</p>
|
||
<p>-----每日一题 Day 3------</p>
|
||
<p>计算机组成原理
|
||
4.在补码加法运算时,产生溢出的情况是_______.(广东工业大学 2018年)</p>
|
||
<p>I .两个操作数的符号位相同,运算时采用单符号位,结果的符号位与操作数相同</p>
|
||
<p>Ⅱ.两个操作数的符号位相同,运算时采用单符号位,结果的符号位与操作数不同</p>
|
||
<p>Ⅲ.运算时采用单符号位,结果的符号位和最高数位不同时产生进位</p>
|
||
<p>Ⅳ.运算时采用单符号位,结果的符号位和最高数位同时产生进位</p>
|
||
<p>V.运算时采用双符号位,运算结果的两个符号位相同</p>
|
||
<p>Ⅵ.运算时采用双符号位,运算结果的两个符号位不同</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-14 21:49:34</p>
|
||
<p>-----每日一题 Day 3------</p>
|
||
<p>操作系统</p>
|
||
<p>3.假设作业1、2、3、4同时到达,需要运行的时间分别为2、5、 8、3,作业的优先数分别为4、9、1、8。采用高优先数优先调度算法时,作业的平均周转时间为________小时。(北京交通大学 2014年)</p>
|
||
<p>A.4.5</p>
|
||
<p>B.10.5</p>
|
||
<p>C.4.75</p>
|
||
<p>D.10.25</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-14 21:48:29</p>
|
||
<p>-----每日一题 Day 3------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.假设信号在媒体上的传播速率为2.3×10^8 m/s,当媒体长度为10cm,数据率为1M/s时,媒体中正在传播的比特数为_________。(中国海洋大学 2017年)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-14 21:46:37</p>
|
||
<p>-----每日一题 Day 3------</p>
|
||
<p>数据结构
|
||
1.设高度为h的二叉树只有度为0和度为2的结点,则此类二叉树中所包含的结点数至少为______(安徽大学 2014年)</p>
|
||
<p>A.h+1</p>
|
||
<p>B.2h-1</p>
|
||
<p>C.2h</p>
|
||
<p>D.2h+1</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-13 17:26:08</p>
|
||
<p>-----每日一题 Day 2------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4..某机器字长为32位,存储器按半字编址,每取出一条指令后PC的值自动+2,说明其指令长度是______(北京航空航天大学 2018年)</p>
|
||
<p>A.16位</p>
|
||
<p>B.32位</p>
|
||
<p>C.64位</p>
|
||
<p>D.128位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-13 17:24:29</p>
|
||
<p>-----每日一题 Day 2------</p>
|
||
<p>操作系统</p>
|
||
<p>3.关于临界区,正确的说法是________(北京交通大学 2009年)</p>
|
||
<p>A.访问不同临界资源的两个进程不要求必须互斥的进入临界区</p>
|
||
<p>B.临界区是包含临界资源的一段数据区</p>
|
||
<p>C.临界区是一种用于进程同步的机制</p>
|
||
<p>D.临界区是访问临界资源的一个进程或者线程</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-13 17:22:26</p>
|
||
<p>-----每日一题 Day 2------</p>
|
||
<p>计算机网络</p>
|
||
<p>2.下列选项正确的是__________(北京大学 2019年)</p>
|
||
<p>A.频分复用每个用户可以一直占用全部信道带宽;</p>
|
||
<p>B.时分复用每个用户可以一直占用全部信道带宽;</p>
|
||
<p>C.码分复用每个用户可以一直占用全部信道带宽;</p>
|
||
<p>D.码分复用每个用户不可以一直占用全部信道带宽。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-13 17:19:02</p>
|
||
<p>-----每日一题 Day 2------</p>
|
||
<p>数据结构
|
||
1.带头结点的双向循环链表L为空表的条件是________(安徽大学 2014年)
|
||
A. L-&gt;next = L;</p>
|
||
<p>B. L = NULL;</p>
|
||
<p>C. L-&gt;next-&gt;prior = NULL;</p>
|
||
<p>D. L-&gt;prior = NULL;</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-12 18:44:47</p>
|
||
<p>-----每日一题 Day 1------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4.下列哪个不是DMA的传送方式 ________(上海大学 2018年)</p>
|
||
<p>A.多路选择</p>
|
||
<p>B.周期挪用</p>
|
||
<p>C.与CPU交替访存</p>
|
||
<p>D.停止CPU访问内存</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-12 18:43:14</p>
|
||
<p>-----每日一题 Day 1------</p>
|
||
<p>操作系统</p>
|
||
<p>3.下面关于处理机调度的描述错误的是______.(北京大学 2020年)</p>
|
||
<p>A.进程处于临界区时不能进行处理器调度</p>
|
||
<p>B.进程读取的文件数据不在内存时,进程让出处理机进入睡眠状态</p>
|
||
<p>C.先来先服务调度算法中有可能发生饥饿现象</p>
|
||
<p>D.在实际操作系统设计中,时间片轮转调度算法、优先级调度算法以及多级反馈队列</p>
|
||
<p>大家可以在评论区发布自己的答案交流哦!</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-12 18:41:43</p>
|
||
<p>-----每日一题 Day 1------</p>
|
||
<p>计算机网络
|
||
2.从滑动窗口的观点看,当发送窗口为1,接收窗只也为1时,相当于ARQ的_____方式。(中国海洋大学 2018年)</p>
|
||
<p>A.回退N帧ARQ</p>
|
||
<p>B.选择重传ARQ</p>
|
||
<p>C.停止等待</p>
|
||
<p>D.连续ARQ</p>
|
||
<hr>
|
||
<p>该题更新于:2022-07-12 18:35:31</p>
|
||
<p>-----每日一题 Day 1------</p>
|
||
<p>数据结构</p>
|
||
<p>1.假设一个栈由一个线性链表实现,其中仅有一个指针指向链表的第一个元素(栈顶)。
|
||
下面哪一个关于进栈和出栈操作的算法复杂度是正确的?_______(上海科技大学 2018年)</p>
|
||
<p>A.(1)0(1) (2)0(1)</p>
|
||
<p>B.(1)0(1) (2)0(n)</p>
|
||
<p>C.(1)0(n) (2)0(1)</p>
|
||
<p>D.(1)0(n) (2)0(n)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-05 18:55:29</p>
|
||
<p>-----每日一题 Day 40------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设相对寻址的转移指令占两个字节,第1字节是操作码,第2字节是相对位移量(用补码表示)。每当CPU从存储器取出第一个字节时,即自动完成(PC)+1→PC。若PC的内容为2008H,要求转移到2001H地址,则该转移指令第2字节的内容应为______(中科院 2013年)</p>
|
||
<p>A F6H</p>
|
||
<p>B F7H</p>
|
||
<p>C F8H</p>
|
||
<p>D F9H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-05 18:54:46</p>
|
||
<p>-----每日一题 Day 40------</p>
|
||
<p>操作系统</p>
|
||
<p>3 CPU的运算速度与许多因素有关,下面______是提高速度的有效措施(中国人民大学 2015年)</p>
|
||
<p>(1) 增加CPU中寄存器的数目</p>
|
||
<p>(2) 提高CPU的主频</p>
|
||
<p>(3) 增加高速缓存(cache)容量</p>
|
||
<p>(4) 优化BIOS的设计</p>
|
||
<p>A (2)和(3)</p>
|
||
<p>B (1)、(2)和(3)</p>
|
||
<p>C (1)和(2)</p>
|
||
<p>D (1)、(2)、(3)和(4)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-05 18:53:59</p>
|
||
<p>-----每日一题 Day 40------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列不属于数据链路层的功能是_____(重庆大学 2010年)</p>
|
||
<p>A.封装成帧</p>
|
||
<p>B.差错检测</p>
|
||
<p>C.可靠传输</p>
|
||
<p>D.拥塞控制</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-05 18:53:07</p>
|
||
<p>-----每日一题 Day 40------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列叙述中正确的是_____(上海科技大学 2015年)</p>
|
||
<p>A 在栈中,栈顶指针的动态变化决定栈中元素的个数</p>
|
||
<p>B 在循环队列中,队尾指针的动态变化决定队列的长度</p>
|
||
<p>C 在循环链表中,头指针和链尾指针的动态变化决定链表的长度</p>
|
||
<p>D 在线性链表中,头指针和链尾指针的动态变化决定链表的长度</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-06 18:35:57</p>
|
||
<p>-----每日一题 Day 41------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列计算机系统性能评价的描述中正确的是_____(北京科技大学 2015年)</p>
|
||
<p>A.主频高的机器性能不一定高</p>
|
||
<p>B.程序MIPS值越高,计算机的性能越高</p>
|
||
<p>C.程序的CPI值越低,计算机的性能越高</p>
|
||
<p>D.同一程序在不同机器上运行时得到的MIPS值一定相同</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-06 18:35:12</p>
|
||
<p>-----每日一题 Day 41------</p>
|
||
<p>操作系统</p>
|
||
<p>3 若一个文件经常更新,且经常随机访问,则应选用的物理文件是_____(北京交通大学 2014年)</p>
|
||
<p>A 顺序文件</p>
|
||
<p>B 记录式文件</p>
|
||
<p>C 索引文件</p>
|
||
<p>D 链接文件</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-06 18:34:27</p>
|
||
<p>-----每日一题 Day 41------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列不能隔离碰撞域的设备是_____(重庆邮电大学 2009年)</p>
|
||
<p>A.网桥</p>
|
||
<p>B.集线器</p>
|
||
<p>C.交换机</p>
|
||
<p>D.路由器</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-06 18:33:39</p>
|
||
<p>-----每日一题 Day 41------</p>
|
||
<p>数据结构</p>
|
||
<p>1 以下结构类型可用来构造链表的是_____(安徽大学 2013)</p>
|
||
<p>A struct aa{ int a;int * b;};</p>
|
||
<p>B struct bb{ int a;bb * b;};</p>
|
||
<p>C struct cc{ int * a;cc b;};</p>
|
||
<p>D struct dd{ int * a;aa b;};</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-07 22:27:44</p>
|
||
<p>-----每日一题 Day 42------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法中,错误的是____(北京理工大学 2014年)</p>
|
||
<p>A.软件与硬件具有逻辑功能的等价性</p>
|
||
<p>B.寄存器的数据位对微程序级用户透明</p>
|
||
<p>C.固件功能类似软件,形态类似硬件</p>
|
||
<p>D.计算机系统层次结构中,微程序属于硬件级</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-07 22:27:07</p>
|
||
<p>-----每日一题 Day 42------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列叙述中,正确的是______(东南大学 2012年)</p>
|
||
<p>A CPU能直接读取硬盘上的数据</p>
|
||
<p>B CPU能直接存取内存储器</p>
|
||
<p>C CPU由存储器、运算器和控制器组成</p>
|
||
<p>D CPU主要用来存储程序和数据</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-07 22:26:11</p>
|
||
<p>-----每日一题 Day 42------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 主机A发送IP数据报给主机B,途中经过了8个路由器,则在此过程中使用ARP的次数为_____(北京航空航天大学 2014年)</p>
|
||
<p>A.8</p>
|
||
<p>B.9</p>
|
||
<p>C.10</p>
|
||
<p>D.11</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-07 22:25:32</p>
|
||
<p>-----每日一题 Day 42------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一个长度为100的循环链表,指针A和指针B都指向了链表中的同一个节点,A以步长为1向前移动,B以步长为3向前移动,至少需要同时移动多少步A和B才能再次指向同一个节点____。(北京大学 2014年)</p>
|
||
<p>A 100</p>
|
||
<p>B 49</p>
|
||
<p>C 50</p>
|
||
<p>D 51</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-08 15:41:58</p>
|
||
<p>-----每日一题 Day 43------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 如果某系统15*4=112成立,则系统采用的进制是______(华中科技大学)</p>
|
||
<p>A.8</p>
|
||
<p>B.7</p>
|
||
<p>C.6</p>
|
||
<p>D.9</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-08 15:41:09</p>
|
||
<p>-----每日一题 Day 43------</p>
|
||
<p>操作系统</p>
|
||
<p>3 若某磁盘平均找道时间为20ms,数据传输速率为2MB/s,控制器延迟为2ms,转速为5000转/分。则读写一个扇区(512个字节)的平均时间为_____(复旦大学 2016年)</p>
|
||
<p>A 20</p>
|
||
<p>B 20.244</p>
|
||
<p>C 26</p>
|
||
<p>D 28.244</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-08 15:40:02</p>
|
||
<p>-----每日一题 Day 43------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 若将网络16.0.0.0/8划分为4096个规模相同的子网,则每个子网可分配的最大IP地址个数是____(北京邮电大学 2015年)</p>
|
||
<p>A.2046</p>
|
||
<p>B.2048</p>
|
||
<p>C.4094</p>
|
||
<p>D.4096</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-08 15:38:46</p>
|
||
<p>-----每日一题 Day 43------</p>
|
||
<p>数据结构</p>
|
||
<p>1 适用于压缩存储稀疏矩阵的两种存储结构是______(北京工业大学 2013年)</p>
|
||
<p>A 三元组表和十字链表</p>
|
||
<p>B 三元组表和邻接矩阵</p>
|
||
<p>C 十字链表和二叉链表</p>
|
||
<p>D 邻接矩阵和十字链表</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-09 15:05:31</p>
|
||
<p>-----每日一题 Day 44------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列关于补码和移码关系的描述中,错误的是_____(上海大学 2013年)</p>
|
||
<p>A.零的补码和移码相同</p>
|
||
<p>B.一般用译码表示浮点数的阶码,而用补码表示定点数</p>
|
||
<p>C.同一个数的补码和移码,其数值部分相同,而符号相反</p>
|
||
<p>D.相同位数的补码和移码具有相同的数据表示范围</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-09 15:04:48</p>
|
||
<p>-----每日一题 Day 44------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法错误的是______(南京大学 2010年)</p>
|
||
<p>A 存储管理不仅是软件的任务,操作系统需要硬件支持来实 现较复杂的存储器管理。</p>
|
||
<p>B 通常,用户不能直接访问存储器管理硬件,而是由操作系 统负责对其控制。</p>
|
||
<p>C 虚地址即程序执行时所要访问的内存地址。</p>
|
||
<p>D 请求分页系统允许进程的内存需求超过当前实际物理内存 的大小。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-09 15:04:08</p>
|
||
<p>-----每日一题 Day 44------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列关于UDP协议的叙述中,正确的是_____(杭州电子科技大学 2012年)</p>
|
||
<p>I. 是TCP/IP参考模型网际层中的协议</p>
|
||
<p>II. 提供无连接服务</p>
|
||
<p>III. 通过差错校验,保证可靠数据传输</p>
|
||
<p>IV. 提供复用/分用服务</p>
|
||
<p>A.仅I</p>
|
||
<p>B.仅I、III</p>
|
||
<p>C.仅II、IV</p>
|
||
<p>D.I、II、III、IV</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-09 15:03:24</p>
|
||
<p>-----每日一题 Day 44------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在快速排序、冒泡排序、堆排序、归并排序、插入排序这五种排序算法中,属于稳定排序的有几个_____(大连理工大学 2015年)</p>
|
||
<p>A 2</p>
|
||
<p>B 3</p>
|
||
<p>C 4</p>
|
||
<p>D 5</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-13 20:40:12</p>
|
||
<p>-----每日一题 Day 45------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 关于内存的下列说法中,正确的是_____(北京科技大学 2014年)</p>
|
||
<p>A.采用虚拟内存技术后程序可以在硬盘上直接运行</p>
|
||
<p>B.某计算机内存容量为8GB,按字节编址,那么它的地址总线为33位</p>
|
||
<p>C.内存的存取速度不能低于CPU速度,否则会造成数据丢失</p>
|
||
<p>D.程序只有在数据和代码等被调入内存后才能运行</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-13 20:39:08</p>
|
||
<p>-----每日一题 Day 45------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列必须在核心态下执行的指令是____(电子科技大学 2009年)</p>
|
||
<p>A.I/O操作</p>
|
||
<p>B.从内存中取数 </p>
|
||
<p>C.算术运算</p>
|
||
<p>D.将运算结果装入内存</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-13 20:38:08</p>
|
||
<p>-----每日一题 Day 45------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在一条点对点的链路上,为了减少IPv4地址的浪费,可为其分配的地址块为_____(北京邮电大学 2013年)</p>
|
||
<p>A./8</p>
|
||
<p>B./16</p>
|
||
<p>C./30</p>
|
||
<p>D./31</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-13 20:24:14</p>
|
||
<p>-----每日一题 Day 45------</p>
|
||
<p>数据结构</p>
|
||
<p>1 红黑树的插入算法复杂度最坏情况是_____</p>
|
||
<p>A O(n)</p>
|
||
<p>B O(log(n))</p>
|
||
<p>C O(nlog(n))</p>
|
||
<p>D O(n^2)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-14 18:33:28</p>
|
||
<p>-----每日一题 Day 46------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某计算机存储器按照字节编址,采用小端方式存储数据,假定编译器规定int和short型长度分别为32位和16位,并且数据按照边界对齐存储。 某C语言的程序段如下:</p>
|
||
<p>struct </p>
|
||
<p>{</p>
|
||
<p> int a;</p>
|
||
<p> char b;</p>
|
||
<p> short c;</p>
|
||
<p>} record;</p>
|
||
<p>record.a = 273;</p>
|
||
<p>若record变量的首地址为0xC008,则地址0xC008的内容是0X _____(中科院 2011年)</p>
|
||
<p>A 0</p>
|
||
<p>B 01</p>
|
||
<p>C 10</p>
|
||
<p>D 11</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-14 18:32:32</p>
|
||
<p>-----每日一题 Day 46------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法错误的是_____。(中国人民大学 2015年)</p>
|
||
<p>A. 线程也具有就绪、阻塞和运行三种基本状态。</p>
|
||
<p>B. 多对一模型的缺点是不能实现真正的并发</p>
|
||
<p>C.用户线程是在用户空间管理的,内核也能感知。</p>
|
||
<p>D.同一个进程内的多个线程之间共享进程的资源。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-14 18:31:38</p>
|
||
<p>-----每日一题 Day 46------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列属于数据链路层互连设备的是_____(中国海洋大学 2010年)</p>
|
||
<p>A.集线器</p>
|
||
<p>B.网桥和交换机</p>
|
||
<p>C.路由器</p>
|
||
<p>D.网关</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-14 18:30:54</p>
|
||
<p>-----每日一题 Day 46------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在平衡二叉树中插入一个结点后造成了不平衡,设最低的不平衡结点为A,并已知A的左孩子的平衡因子为0右孩子的平衡因子为1,则应作_____型调整以使其平衡。(中国石油大学 2013年)</p>
|
||
<p>A LL</p>
|
||
<p>B LR</p>
|
||
<p>C RL</p>
|
||
<p>D RR</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-15 18:34:56</p>
|
||
<p>-----每日一题 Day 47------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某计算机按字节编址,采用大端方式存储信息。其中,某指令的一个操作数的机器数为ABCD 00FFH,该操作数采用基址寻址方式,指令中形式地址(用补码表示)为FF00H,当前基址寄存器的内容为C000 0000H,则该操作数的LSB(即该操作数的最低位FFH)存放的地址是______(华中科技大学)</p>
|
||
<p>A.BFFF FF00H</p>
|
||
<p>B.BFFF FF03H</p>
|
||
<p>C.C000 FF00H</p>
|
||
<p>D.C000 FF03H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-15 18:33:43</p>
|
||
<p>-----每日一题 Day 47------</p>
|
||
<p>操作系统</p>
|
||
<p>3 对信号量S执行P操作后,使进程进入等待队列的条件是______。(西安交通大学)</p>
|
||
<p>A.S.value&gt;0</p>
|
||
<p>B.S.value&lt;=0</p>
|
||
<p>C.S.value&gt;=0</p>
|
||
<p>D.S.value&lt;0</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-15 18:33:06</p>
|
||
<p>-----每日一题 Day 47------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 .32 个用户共享 2.048 Mbps 链路,使用TDM(时分多路复用)。当每个用户轮流使用时,以全速度发送8位。用户需要多长时间才能发送一次_______(华南理工大学)</p>
|
||
<p>A.任何阶段都可被使用</p>
|
||
<p>B.4 us</p>
|
||
<p>C.125 us</p>
|
||
<p>D.4 ms</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-15 18:32:17</p>
|
||
<p>-----每日一题 Day 47------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一个队列只能从右侧入队,左右侧皆可出队。顺序为Ka、Kb、Kc、Kd、Ke的序列入队后,不能得到的输出是_____(苏州大学 2009年)</p>
|
||
<p>A Ka-&gt;Kb-&gt;Kc-&gt;Kd-&gt;Ke</p>
|
||
<p>B Ke-&gt;Kd-&gt;Kc-&gt;Kb-&gt;Ka</p>
|
||
<p>C Ka-&gt;Kb-&gt;Ke-&gt;Kc-&gt;Kd</p>
|
||
<p>D Ke-&gt;Ka-&gt;Kc-&gt;Kb-&gt;Kd</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-16 20:45:16</p>
|
||
<p>-----每日一题 Day 48------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 假定指令地址码给出的是寄存器的编号,则该操作数采用的寻址方式不可能是____(华中科技大学)</p>
|
||
<p>A.变址寻址</p>
|
||
<p>B.相对寻址</p>
|
||
<p>C.寄存器寻址</p>
|
||
<p>D.寄存器间接寻址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-16 20:44:32</p>
|
||
<p>-----每日一题 Day 48------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列关于常规存储器的论述中,正确的论述是_____(西安交通大学)</p>
|
||
<p>A.作业在运行前,不必全部装入内存,但在运行过程中必须一直驻留内存</p>
|
||
<p>B.存业在运行前,必须全部装入内存,且在运行过程中也一直驻留内存</p>
|
||
<p>C.作业在运行前,必须全部装入内存,但在运行过程中不必一直驻留内存</p>
|
||
<p>D.作业在运行前,不必全部装入内存,且在运行过程中也不必一直驻留内存</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-16 20:43:48</p>
|
||
<p>-----每日一题 Day 48------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 数据链路层采用选择重传协议(SR)传输数据,发送方已发送了0~3号数据帧,现已收到1号帧的确认,而0、2号帧依次超时,则此时需要重传的帧数是______(华南理工大学)</p>
|
||
<p>A.1</p>
|
||
<p>B.2</p>
|
||
<p>C.3</p>
|
||
<p>D.4</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-16 20:43:05</p>
|
||
<p>-----每日一题 Day 48------</p>
|
||
<p>数据结构</p>
|
||
<p>1 假设以数组A[60]存放循环队列的元素,其头指针是front=47,当前队列有50个元素,则队列的尾指针值为____(上海大学 2016年)</p>
|
||
<p>A 3</p>
|
||
<p>B 37</p>
|
||
<p>C 97</p>
|
||
<p>D 50</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-19 17:49:35</p>
|
||
<p>-----每日一题 Day 49------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法正确的是____(北京理工大学)</p>
|
||
<p>A 为了保证中断服务程序执行完毕以后,能正确返回到被中断的断点继续执行程序,必须进行现场保存操作。</p>
|
||
<p>B 中断屏蔽技术是用中断屏蔽寄存器对中断请求线进行屏蔽控制,因此,只有多级中断系统(CPU提供多条中断请求输入线)才能采用中断屏蔽技术。</p>
|
||
<p>C 一旦有中断请求出现,CPU立即停止当前指令的执行,转而去受理中断请求。</p>
|
||
<p>D 中断级别最高的是不可屏蔽中断。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-19 17:48:22</p>
|
||
<p>-----每日一题 Day 49------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是____(北京交通大学)</p>
|
||
<p>A 在多级目录结构中对文件的访问是通过路径名和用户目录名进行的</p>
|
||
<p>B 文件可以被划分成大小相等的若干物理块且物理块大小也可任意指定</p>
|
||
<p>C 文件的逻辑结构是指文件在磁盘上的存储组织方式。</p>
|
||
<p>D 文件分配时,采用连续分配方式会产生外碎片。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-19 17:47:02</p>
|
||
<p>-----每日一题 Day 49------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 假设一个经典的以太网站点正试图发送一个帧,在它要传输这个帧之前已有两个连续冲突。此时,可供该站点选择的随机等待时隙有_____个(北京邮电大学)</p>
|
||
<p>A.4</p>
|
||
<p>B.16</p>
|
||
<p>C.8</p>
|
||
<p>D.2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-19 17:45:41</p>
|
||
<p>-----每日一题 Day 49------</p>
|
||
<p>数据结构</p>
|
||
<p>1 有一组数据“12,15,1,18,2,35,30,11”,用简单选择排序由小到大排序,第2趟交换数据后数据的顺序是_____(安徽大学 )</p>
|
||
<p>A 11,1,2,12,35,18,30,15</p>
|
||
<p>B 1,2,12,18,15,35,30,11</p>
|
||
<p>C 1,2,11,12,15,18,30,35</p>
|
||
<p>D 1,2,11,12,15,18,35,30</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-20 15:03:58</p>
|
||
<p>-----每日一题 Day 50------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法正确的是_____(北京理工大学)</p>
|
||
<p>A DMA是主存与外设之间交换数据的方式,它也可用于主存与主存之间的数据交换。</p>
|
||
<p>B CPU响应中断时暂停运行当前程序,自动转移到中断服务程序。</p>
|
||
<p>C 一个通道可以连接多个外部设备控制器,一个外部设备控制器可以管理一台或多台外部设备。</p>
|
||
<p>D 一个更高优先级的中断请求可以中断另一个中断处理程序的执行。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-20 15:03:18</p>
|
||
<p>-----每日一题 Day 50------</p>
|
||
<p>操作系统</p>
|
||
<p>3 有关设备管理的叙述中不正确的是_____。(北京交通大学)</p>
|
||
<p>A.所有设备的启动工作都由系统统一来做</p>
|
||
<p>B.通道是处理输入/输出的软件</p>
|
||
<p>C.I/O操作完成后会触发中断</p>
|
||
<p>D.编制好的通道程序是存放在主存中的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-20 15:02:36</p>
|
||
<p>-----每日一题 Day 50------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 考虑一个与主机 A 和 B 连接的交换机 (其他端口是空的)。交换机刚刚开始启动和运作。A发送一帧到B,然后B回复一帧到A。检查下列所有语句,当第二个帧 (从 B 发送给 A) 被交换机处理时,下列说法正确的是_____(北京邮电大学)</p>
|
||
<p>A.该交换机不学习任何新的东西。</p>
|
||
<p>B. 交换机不会学习 B的端口</p>
|
||
<p>C.交换机通过广播帧到达 A.</p>
|
||
<p>D.交换机将帧直接转发到 A</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-20 15:01:46</p>
|
||
<p>-----每日一题 Day 50------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列哪种算法平均情况、最好情况和最坏情况下的时间复杂度都为O(n^2)_____(安徽大学 )</p>
|
||
<p>A 直接选择排序</p>
|
||
<p>B 直接插入排序</p>
|
||
<p>C 冒泡排序</p>
|
||
<p>D 归并排序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-21 18:40:12</p>
|
||
<p>-----每日一题 Day 51------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 异步通信方式传送ASCII码,数据位8位,奇校验1位,停止位1位。当波特率为4800</p>
|
||
<p>波特时,数据位的传送速率是_____(北京理工大学)</p>
|
||
<p>A 4800 b/s</p>
|
||
<p>B 6000b/s</p>
|
||
<p>C 3840b/s</p>
|
||
<p>D 4267b/s</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-21 18:39:23</p>
|
||
<p>-----每日一题 Day 51------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列选项中,_______可能是抢占方式进程调度中引起调度的原因 (四川大学)</p>
|
||
<p>A 当前的运行进程调用阻塞原语而进入阻塞状态</p>
|
||
<p>B 当前的运行进程因提出申请I/O而阻塞</p>
|
||
<p>C 有更高优先级的进程到达而从执行状态变为就绪状态</p>
|
||
<p>D 正在执行的进程执行了P原语操作,由于资源不足而阻塞</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-21 18:37:17</p>
|
||
<p>-----每日一题 Day 51------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 以下关于MAC地址的描述中,错误的是_______(北京航空航天大学)</p>
|
||
<p>A.目的地址与源地址分别表示帧的接收主机与发送主机的硬件地址</p>
|
||
<p>B.硬件地址通常称为“物理地址”或“MAC地址”</p>
|
||
<p>C.源地址可以是单播、多播或广播地址</p>
|
||
<p>D.MAC地址长度为48bit</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-21 18:36:25</p>
|
||
<p>-----每日一题 Day 51------</p>
|
||
<p>数据结构</p>
|
||
<p>1 执行____操作时,需要使用队列作为辅助存储空间。(北京工业大学)</p>
|
||
<p>A 查找哈希(hash)表</p>
|
||
<p>B 广度优先搜索图</p>
|
||
<p>C 先序(根)遍历二叉树</p>
|
||
<p>D 深度优先搜索图</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-22 21:46:55</p>
|
||
<p>-----每日一题 Day 52------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某计算机系统共有五级中断,其中断响应优先级从高到低为1--2--3--4--5 。现按如下规定修改:各级中断处理时均屏蔽本级中断,且处理1 级中断时屏蔽2 、3 、4和5 级中断;处理2级中断时屏蔽3 、4 、5级中断;处理4级中断时不屏蔽其他级中断;处理3 级中断时屏蔽4级和5 级中断;处理5 级中断时屏蔽4级中断。则中断处理优先级(从高到低)顺序为_____(北京理工大学)</p>
|
||
<p>A 1--2--3--4--5</p>
|
||
<p>B 1--2--3--5--4</p>
|
||
<p>C 1--2--5--4--3</p>
|
||
<p>D 1--2--4--3--5</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-22 21:46:00</p>
|
||
<p>-----每日一题 Day 52------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法错误的是______(辽宁大学)</p>
|
||
<p>A 共享数据的并发访问可能会产生数据的不一致性。</p>
|
||
<p>B 系统中只要存在相关进程就有可能存在进程之间的同步和互斥。</p>
|
||
<p>C 对临界资源不能实现共享。</p>
|
||
<p>D 一个临界资源可能对应多个临界区。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-22 21:44:50</p>
|
||
<p>-----每日一题 Day 52------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 一台交换机具有24个100Mbps的全双工端口和2个1000Mbps的全双工端口,如果所有的端口都工作在全双工状态,那么交换机总带宽等于_____(北京航空航天大学)</p>
|
||
<p>A.6.4Gbps</p>
|
||
<p>B.4.4Gbps</p>
|
||
<p>C.8.8Gbps</p>
|
||
<p>D.6.8Gbps</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-22 21:43:55</p>
|
||
<p>-----每日一题 Day 52------</p>
|
||
<p>数据结构</p>
|
||
<p>1 若 A=10、B=4、C=6、D=4、E=15 则后缀表达式“ AB*CD+-E+ ”的值为______(北京工业大学)</p>
|
||
<p>A 45</p>
|
||
<p>B 31</p>
|
||
<p>C 53</p>
|
||
<p>D 65</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-23 16:44:18</p>
|
||
<p>-----每日一题 Day 53------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法正确的是_____(大连理工大学)</p>
|
||
<p>A 流水线中相关问题是指在一段程序的相邻指令之间存在某种关系,这种关系影响指令的并行执行。</p>
|
||
<p>B 在CPU中,译码器主要用在运算器中挑选多路输入数据中的某一路数据送到ALU 。</p>
|
||
<p>C 控制存储器是用来存放微程序的存储器,它应该比主存储器速度快。</p>
|
||
<p>D 机器的主频最快,机器的速度就最快。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-23 16:43:38</p>
|
||
<p>-----每日一题 Day 53------</p>
|
||
<p>操作系统</p>
|
||
<p>3 设一磁盘盘面共有磁道200道,盘面总存储容量为1.6MB, 磁盘旋转一周的时间为25ms, 每道有4个区,各区之间有一间隙,磁头通过每个间隙需1.25ms 。则磁盘通道所需最大传输率是_____(复旦大学)</p>
|
||
<p>A 200KB/s</p>
|
||
<p>B 320KB/s</p>
|
||
<p>C 400KB/s</p>
|
||
<p>D 480KB/s</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-23 16:42:54</p>
|
||
<p>-----每日一题 Day 53------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 一个网络的网络地址是:115.25.0.0,其子网掩码是255.255.224.0,下面的哪一个是合法的主机地址______(东南大学)</p>
|
||
<p>A.115.25.31.255</p>
|
||
<p>B.115.25.0.0</p>
|
||
<p>C.115.25.0.255</p>
|
||
<p>D.以上都不是</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-23 16:41:52</p>
|
||
<p>-----每日一题 Day 53------</p>
|
||
<p>数据结构</p>
|
||
<p>1 某二叉树的前序序列为 ABCDEFG ,中序序列为 DCBAEFG ,则该二叉树的深度(根结点在第 1 层)为_______(福州大学)</p>
|
||
<p>A 2</p>
|
||
<p>B 3</p>
|
||
<p>C 4</p>
|
||
<p>D 5</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-26 17:35:20</p>
|
||
<p>-----每日一题 Day 54------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 若某计算机数据线、地址线均是8bit, 有一条相对寻址的无条件转移指令存千内存的20H单元中,指令给出的位移量D =00010101 B, 设该指令占用2个字节,则该指令执行结束时PC的内容为______(哈尔滨工业大学)</p>
|
||
<p>A 20H</p>
|
||
<p>B 35H</p>
|
||
<p>C 37H</p>
|
||
<p>D 22H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-26 17:34:36</p>
|
||
<p>-----每日一题 Day 54------</p>
|
||
<p>操作系统</p>
|
||
<p>3 已知页面走向为1、2、1、3、1、2、4、2、1、3、4,且开始执 行时主存中没有页面。若只给作业分配2个物理块,当采用FIFO页面淘 汰算法时缺页率为_____(华东师范大学)</p>
|
||
<p>A 7/11</p>
|
||
<p>B 8/11</p>
|
||
<p>C 9/11</p>
|
||
<p>D 10/11</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-26 17:33:54</p>
|
||
<p>-----每日一题 Day 54------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 某自治系统内采用 RIP 协议,若该自治系统内的路由器 R1 收到其邻居路由器 R2 的距离矢量中包含的信 息&lt;net1,16&gt;,则可能得出的结论是_____(杭州电子科技大学)</p>
|
||
<p>A.R1 不能通过R2到达net1</p>
|
||
<p>B.R1 可以通过R2到达 net1,代价是17</p>
|
||
<p>C.R2 可以通过R1到达net1 ,代价是17</p>
|
||
<p>D.R2 可以到达 net1,代价是 16</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-26 17:32:49</p>
|
||
<p>-----每日一题 Day 54------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法正确的是_____(河海大学)</p>
|
||
<p>A 已知一颗二叉树的前序遍历顺序和后序遍历顺序,可以唯一确定这棵二叉树</p>
|
||
<p>B 将一个递归算法改为非递归算法时,通常使用队列作为辅助结构</p>
|
||
<p>C 快速排序和堆排序都是不稳定排序</p>
|
||
<p>D 二分查找法,平均时间复杂度为O(n)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-27 18:45:19</p>
|
||
<p>-----每日一题 Day 55------</p>
|
||
<p>注意:第二天发布题目同一时间评论区公布答案哦!</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设有一个1MB容量的存储器,字长为32位,按半字编址,编址范围为____</p>
|
||
<p>A 00000H-3FFFFH</p>
|
||
<p>B 00000H-7FFFFH</p>
|
||
<p>C 00000H-FFFFFH</p>
|
||
<p>D 以上选项均不对</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-27 18:44:34</p>
|
||
<p>-----每日一题 Day 55------</p>
|
||
<p>操作系统</p>
|
||
<p>3 若干个等待访问磁盘的访问柱面为20、44、40、4、80、12、 76,假设每移动一个柱面需要5毫秒,磁头臂当前位于第77号柱面,请 按短寻道时间优先算法完成上述各次访问总共花费的寻道时间为_____</p>
|
||
<p>A 81</p>
|
||
<p>B 329</p>
|
||
<p>C 405</p>
|
||
<p>D 1645</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-27 18:43:55</p>
|
||
<p>-----每日一题 Day 55------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 一条MTU是1000字节的链路,假设每个数据分组有 20字节的头部信息,传输有效载荷为1980字节所需数据分组的最小数目是多少?假设先前的数据分组是最大尺寸,那么最后一个数据分组的大小是多少?____</p>
|
||
<p>A.2 个数据包,第二个数据分组大小为 976 字节</p>
|
||
<p>B.3 个数据包,第三个数据分组大小为 48 字节</p>
|
||
<p>C.3 个数据包,第三个数据分组大小为 28 字节</p>
|
||
<p>D.2 个数据包,第二个数据分组大小为 980 字节</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-27 18:42:52</p>
|
||
<p>-----每日一题 Day 55------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设n为3的倍数,则以下算法的时间复杂度为_______</p>
|
||
<p>void fun(int n)</p>
|
||
<p>{ int i, j, x, y;</p>
|
||
<p>for (i = 1; i &lt; = n; i ++)</p>
|
||
<pre><code> if (3 * i &lt; = n)
|
||
|
||
for (j = 3 * i; j &lt; = n; j++)
|
||
|
||
{
|
||
|
||
x++ ; y = 3 * x + 2;
|
||
|
||
}
|
||
</code></pre>
|
||
<p>}</p>
|
||
<p>A O(logn)</p>
|
||
<p>B O(n)</p>
|
||
<p>C O(nlogn)</p>
|
||
<p>D O(n^2)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-28 16:18:59</p>
|
||
<p>-----每日一题 Day 56------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 已知cache命中率H=0.98, 主存周期是cache 的4倍,主存存取周期为200ns, 则cache</p>
|
||
<p>-主存的效率为______。</p>
|
||
<p>A 92%</p>
|
||
<p>B 92.6%</p>
|
||
<p>C 95.4%</p>
|
||
<p>D 98%</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-28 16:18:24</p>
|
||
<p>-----每日一题 Day 56------</p>
|
||
<p>操作系统</p>
|
||
<p>3 现有含40个磁道的盘面,文件在磁盘上非连续存放,逻辑上相邻的数据块的平均距离为13个磁道,磁头从一个磁道移到另一个磁道 需要6毫秒。已知每块的旋转延迟时间及传输时间分别为100毫秒、25 毫秒,则读取一个100块的文件需要多少时间?____</p>
|
||
<p>A 131ms</p>
|
||
<p>B 203ms</p>
|
||
<p>C 13100ms</p>
|
||
<p>D 20300ms</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-28 16:17:46</p>
|
||
<p>-----每日一题 Day 56------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下面的IPv4地址,哪些属于私有地址_____</p>
|
||
<p>A.172.33.9.6</p>
|
||
<p>B.192.0.2.3</p>
|
||
<p>C.10.10.10.10</p>
|
||
<p>D.172.15.1.9</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-28 16:17:06</p>
|
||
<p>-----每日一题 Day 56------</p>
|
||
<p>数据结构</p>
|
||
<p>1 二维数组A[4][4](即A[0...3][0...3] )的元素起始地址是LOC(A[0][0]) = 1000,元素的长度为2 ,则LOC(A[2][2] )为_____</p>
|
||
<p>A 1018</p>
|
||
<p>B 1020</p>
|
||
<p>C 1022</p>
|
||
<p>D 1024</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-29 21:20:52</p>
|
||
<p>-----每日一题 Day 57------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 已知cache-主存系统效率为85% ,平均访问时间为60ns, cache 比主存快4倍,则</p>
|
||
<p>cache命中率是_____</p>
|
||
<p>A 93.2%</p>
|
||
<p>B 95%</p>
|
||
<p>C 96.5%</p>
|
||
<p>D 98%</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-29 21:20:08</p>
|
||
<p>-----每日一题 Day 57------</p>
|
||
<p>操作系统</p>
|
||
<p>3 一个磁盘的转速为7200转/分钟,每个磁道有160个扇区,每个 扇区大小为512B,那么在理想情况下,其数据传输率是_____</p>
|
||
<p>A 4608KB/秒</p>
|
||
<p>B 5760KB/秒</p>
|
||
<p>C 7680KB/秒</p>
|
||
<p>D 9600KB/秒</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-29 21:19:20</p>
|
||
<p>-----每日一题 Day 57------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下面哪一种动态路由选择协议用作连接不同的互联网服务商自治系统间的协议_____</p>
|
||
<p>A.OSPF</p>
|
||
<p>B.IS-IS</p>
|
||
<p>C.BGP</p>
|
||
<p>D.RIP</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-29 21:17:42</p>
|
||
<p>-----每日一题 Day 57------</p>
|
||
<p>数据结构</p>
|
||
<p>1 有一个有序表R[1...13] = { 1, 3, 9, 12, 32, 41, 45, 62, 75, 77, 82, 95, 100} ,当用二分查找法查找关键字为82 的节点时,经_____次比较后查找成功</p>
|
||
<p>A 2</p>
|
||
<p>B 3</p>
|
||
<p>C 4</p>
|
||
<p>D 5</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-30 15:08:26</p>
|
||
<p>-----每日一题 Day 58------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 在页式虚拟存储器中,若主存容量为16MB, 页面容量为4KB, 程序地址空间为1G,则页表长度为_____行</p>
|
||
<p>A 2^12</p>
|
||
<p>B 2^15</p>
|
||
<p>C 2^18</p>
|
||
<p>D 2^20</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-30 15:07:29</p>
|
||
<p>-----每日一题 Day 58------</p>
|
||
<p>操作系统</p>
|
||
<p>3 某磁盘有26310个柱面,16个读写头,并且每个磁道有63个扇区。相邻磁道之间的寻道时间为1毫秒,磁盘以7200转/分钟的速度旋转。假设读写磁头当前位于0号磁道上,则读整个磁盘需要多长时间? _____</p>
|
||
<p>A 3506597毫秒</p>
|
||
<p>B 3532906毫秒</p>
|
||
<p>C 3532907毫秒</p>
|
||
<p>D 3532908毫秒</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-30 15:06:46</p>
|
||
<p>-----每日一题 Day 58------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 假设一个 TCP 流在慢启动阶段,k 个数据段在 t 与 t + RTT 之间被发送。假设仍然保持在慢启动阶段,预期有多少个数据段在 t + RTT 和t + 2 * RTT 发送?_____</p>
|
||
<p>A.k+1</p>
|
||
<p>B.2^K</p>
|
||
<p>C.k</p>
|
||
<p>D.2k</p>
|
||
<hr>
|
||
<p>该题更新于:2022-09-30 15:05:54</p>
|
||
<p>-----每日一题 Day 58------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设n 是偶数,下列程序段的时间复杂度为______</p>
|
||
<p>int m = 0, i, j;</p>
|
||
<p>for (i = 1; i &lt; = n; i++)</p>
|
||
<p>for (j = 2 * i; j &lt; = n; j++)</p>
|
||
<pre><code> m++;
|
||
</code></pre>
|
||
<p>A O(logn)</p>
|
||
<p>B O(n)</p>
|
||
<p>C O(nlogn)</p>
|
||
<p>D O(n^2)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-08 20:59:23</p>
|
||
<p>-----每日一题 Day 59------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 存储体按照一定顺序划分成许多存储单元。每个存储单元有一个编号,称为存储单元的地址。访问存储器必须按地址进行访问,存储单元中存放的是______</p>
|
||
<p>A.存储器单元的地址编号</p>
|
||
<p>B.指定单元存放的数据</p>
|
||
<p>C.将要写人存储单元的内容</p>
|
||
<p>D.访问存储器的控制命令</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-08 20:58:43</p>
|
||
<p>-----每日一题 Day 59------</p>
|
||
<p>操作系统</p>
|
||
<p>3 某操作系统的文件管理采用直接索引和多级索引混合的方 式,文件索引表共有16项,其中9项是直接索引项,4项是一级间接索 引项,3项是二次间接索引项,假定每个物理块的大小是1KB,每个索 引项占2B。则该文件系统大的文件可以达到______KB</p>
|
||
<p>A 788489</p>
|
||
<p>B 788480</p>
|
||
<p>C 788490</p>
|
||
<p>D 787465</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-08 20:55:31</p>
|
||
<p>-----每日一题 Day 59------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法正确的是______</p>
|
||
<p>A 用顺序表和单链表存储的有序表均可使用二分查找方法来提高查找速度。</p>
|
||
<p>B n 个数据元素存放在一维数组A[1.. n] 中,在进行顺序查找时,其平均查找长度与</p>
|
||
<p>这n个数的排列次序有关。</p>
|
||
<p>C 若哈希表的装填因子a&lt;l ,则可避免冲突的产生。</p>
|
||
<p>D 在二叉排序树的任意一棵子树中,关键字最小的节点必无左孩子,关键字最大的节</p>
|
||
<p>点必无右孩子。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-09 19:18:02</p>
|
||
<p>-----每日一题 Day 60------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 计算机存储器用来存放被运算的数据和程序,如果读出一个存储单元的内容后,该单元的内容_______</p>
|
||
<p>A.清零</p>
|
||
<p>B.保持不变</p>
|
||
<p>C.被取走</p>
|
||
<p>D.不定</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-09 19:17:19</p>
|
||
<p>-----每日一题 Day 60------</p>
|
||
<p>操作系统</p>
|
||
<p>3 在一个分页存储管理系统中,某作业的页表如下所示。已 知页面大小为1024字节,逻辑地址2148相应的物理地址为______。</p>
|
||
<p>页号 块号</p>
|
||
<p>0 2</p>
|
||
<p>1 3</p>
|
||
<p>2 1</p>
|
||
<p>3 6</p>
|
||
<p>A 2148</p>
|
||
<p>B 1124</p>
|
||
<p>C 1976</p>
|
||
<p>D 3059</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-09 19:16:30</p>
|
||
<p>-----每日一题 Day 60------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在下面这些点分十进制表示的IP地址中,哪一个是子网172.25.0.64/26中的最后一个可用地址?_____</p>
|
||
<p>A.172.25.0.128</p>
|
||
<p>B.172.25.0.94</p>
|
||
<p>C.172.25.0.127</p>
|
||
<p>D.172.25.0.126</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-09 19:15:42</p>
|
||
<p>-----每日一题 Day 60------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是______</p>
|
||
<p>A n 个顶点的无向图至多有n(n-1) 条边。</p>
|
||
<p>B 在有向图中,各顶点的入度之和等于各顶点的出度之和。</p>
|
||
<p>C 无论是有向图还是无向图,其邻接矩阵表示都是唯一的。</p>
|
||
<p>D 对同一个有向图来说,只保存出边的邻接表中节点的数目总是和只保存入边的邻接表中节点的数目一样多。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-10 18:49:13</p>
|
||
<p>-----每日一题 Day 61------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 动态存储器DRAM芯片共有16位地址,其中行地址8位,列地址8位,按异步刷新方案,每次刷新一行,2ms内将全部单元刷新一遍。则芯片刷新信号周期时间为______</p>
|
||
<p>A 2.5μs</p>
|
||
<p>B 12.5μs</p>
|
||
<p>C 7.8μs</p>
|
||
<p>D 3.9μs</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-10 18:48:32</p>
|
||
<p>-----每日一题 Day 61------</p>
|
||
<p>操作系统</p>
|
||
<p>3 两个进程A和B,每一个进程都需要读取数据库中的记录1、2、 3,假如这两个进程都以1、2、3的次序读取记录,系统将不会发生死 锁。但如果A以3、2、1的次序读取记录,B以1、2、3的次序读取记录,则死锁可能发生。两个进程读取记录的次序如果不确定, 那么系统保证不发生死锁的概率是____</p>
|
||
<p>A 1/9</p>
|
||
<p>B 1/6</p>
|
||
<p>C 1/3</p>
|
||
<p>D 1/12</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-10 18:47:52</p>
|
||
<p>-----每日一题 Day 61------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 若路由器R因为拥塞丢弃IP分组,则此时R可以向发出该IP分组的源主机发送的ICMP报文件类型是____</p>
|
||
<p>A.目的不可达</p>
|
||
<p>B.参数不正确</p>
|
||
<p>C.路由重定向</p>
|
||
<p>D.源抑制</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-10 18:47:06</p>
|
||
<p>-----每日一题 Day 61------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法正确的是_____</p>
|
||
<p>A 如果表示图的邻接矩阵是对称矩阵,则该图一定是无向图。</p>
|
||
<p>B 连通图的生成树包含了图中所有顶点。</p>
|
||
<p>C 对n 个顶点的连通图G 来说,如果其中的某个子图有n 个顶点、n-1 条边,则该子图一定是G 的生成树。</p>
|
||
<p>D 最小生成树是指边数最少的生成树。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-11 18:37:30</p>
|
||
<p>-----每日一题 Day 62------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 作业调度程序完成整个作业运行工作。</p>
|
||
<p>B 如果现有两道作业同时运行,一道以计算为主,另一道 以输入/输出为主,则应该让以计算为主的作业优先级高于以输入/输出 为主的作业。</p>
|
||
<p>C 与单道批处理不同,多道批处理系统必须具有作业调度 功能和进程调度功能,内存中可以存放多道作业。</p>
|
||
<p>D 在多道批处理系统中,当一个作业反复执行多次时,该作业每次的运行时间可能都不相同。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-11 17:41:19</p>
|
||
<p>-----每日一题 Day 62------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某计算机字长32位,采用4体交叉工作,若每个存储体的存取周期为200ns,用低2位地址作为体地址,存储数据按地址顺序存放。存储器的带宽是_____Mb/s</p>
|
||
<p>A 320</p>
|
||
<p>B 480</p>
|
||
<p>C 640</p>
|
||
<p>D 800</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-11 17:39:50</p>
|
||
<p>-----每日一题 Day 62------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 FTP客户和服务器间传递FTP命令时,使用的连接是_____</p>
|
||
<p>A.建立在UDP之上的控制连接</p>
|
||
<p>B.建立在TCP之上的数据连接</p>
|
||
<p>C.建立在TCP之上的控制连接</p>
|
||
<p>D.建立在UDP之上的数据连接</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-11 17:38:59</p>
|
||
<p>-----每日一题 Day 62------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是______</p>
|
||
<p>A 强连通图不能进行拓扑排序。</p>
|
||
<p>B 只要无向网中没有权值相同的边,其最小生成树就是唯一的。</p>
|
||
<p>C 如果表示某个图的邻接矩阵是对称矩阵,则该图不一定是无向图。</p>
|
||
<p>D 从n 个顶点的连通图中选取n-1 条权值最小的边,即可构成最小生成树。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-12 18:43:07</p>
|
||
<p>-----每日一题 Day 63------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 系统总线中地址线的作用是______</p>
|
||
<p>A.用于选择主存单元</p>
|
||
<p>B.用于选择进行信息传输的设备</p>
|
||
<p>C.用于指定主存单元和I/0设备接口电路的地址</p>
|
||
<p>D.用于传送主存物理地址和逻辑地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-12 18:42:28</p>
|
||
<p>-----每日一题 Day 63------</p>
|
||
<p>操作系统</p>
|
||
<p>3 某请求页式存储管理,允许用户编程空间为32个页面(每页 1KB),主存为16KB。如果一个用户程序有10页长,且某时刻该用户页面映射关系如下所示,则逻辑地址OAC5H相应的物理地址为______</p>
|
||
<p>页号 块号</p>
|
||
<p>0 8</p>
|
||
<p>1 7</p>
|
||
<p>2 4</p>
|
||
<p>3 10</p>
|
||
<p>A 12C5H</p>
|
||
<p>B 22C5H</p>
|
||
<p>C 1EC5H</p>
|
||
<p>D 3AC5H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-12 18:41:47</p>
|
||
<p>-----每日一题 Day 63------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在下列有关曼彻斯特编码的说法中,正确的是______</p>
|
||
<p>A.曼彻斯特编码不是自含时钟编码的数字数据编码</p>
|
||
<p>B.曼彻斯特编码实际上就是差分曼彻斯特编码</p>
|
||
<p>C.曼彻斯特编码前后的比特率相差两倍</p>
|
||
<p>D.曼彻斯特编码并没有完全消除直流分量</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-12 18:40:57</p>
|
||
<p>-----每日一题 Day 63------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是______</p>
|
||
<p>A 在一个有向图的拓扑序列中若顶点a 在顶点b 之前,则图中必有一条边&lt;a,b&gt;</p>
|
||
<p>B 强连通分量是有向图中的极大强连通子图。</p>
|
||
<p>C 连通图的广度优先遍历中一般要采用队列来暂存刚访问过的顶点。</p>
|
||
<p>D 图的深度优先遍历中一般要采用栈来暂存刚访问过的顶点。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-13 17:18:34</p>
|
||
<p>-----每日一题 Day 64------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 已知[X]补=1.X1X2X3X4X5,若要X&gt;-1/2,X1X2X3X4X5应满足_____</p>
|
||
<p>A. X1必须为1,X2X3X4X5至少有一个1</p>
|
||
<p>B. X1必须为1,X2X3X4X5任意</p>
|
||
<p>C. X1必须为0,X2X3X4X5至少有一个1</p>
|
||
<p>D. X1必须为0,X2X3X4X5任意</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-13 17:15:05</p>
|
||
<p>-----每日一题 Day 64------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 香农定理从定量的角度描述了“带宽”与“速率”的关系。在香农定理的公式中,与信道的最大传输速率相关的参数主要有信道带宽与______</p>
|
||
<p>A.频率特性</p>
|
||
<p>B.信噪比</p>
|
||
<p>C.相位特性</p>
|
||
<p>D.噪声功率</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-13 17:13:39</p>
|
||
<p>-----每日一题 Day 64------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法正确的是_____</p>
|
||
<p>A 当改变网上某一关键路径上的任一关键活动后,必将产生不同的关键路径。</p>
|
||
<p>B 在表示某工程的AOE 网中,加速其关键路径上的任意关键活动均可缩短整个下程的完成时间。</p>
|
||
<p>C 在AOE 图中,关键路径上某个活动的时间缩短,整个工程的时间也就必定缩短。</p>
|
||
<p>D 在AOE 图中,关键路径上活动的时间延长多少,整个工程的时间也就随之延长多少。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-14 21:07:38</p>
|
||
<p>-----每日一题 Day 65------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 一个8位二进制整数,若采用补码表示,且由4个1和4个0组成,则最小值为______</p>
|
||
<p>A. -120</p>
|
||
<p>B.-7</p>
|
||
<p>C. -112</p>
|
||
<p>D.-121</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-14 21:06:54</p>
|
||
<p>-----每日一题 Day 65------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法错误的是_____</p>
|
||
<p>A 由于短作业优先调度算法的作业平均周转时间小于先来 先服务调度算法,因此短作业优先调度算法可用于分时系统。</p>
|
||
<p>B 分时系统中,时间片越小越好。</p>
|
||
<p>C 用户程序部分包含着进程具体执行的指令,因而是进程映 像中重要的部分。</p>
|
||
<p>D 为了避免出现内存中进程全部处于阻塞状态的情况,操作 系统可选择将一些进程转移到磁盘,再调入新进程运行。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-14 21:06:12</p>
|
||
<p>-----每日一题 Day 65------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在下列数据交换方式中,数据经过网络的传输延迟长而且是不固定的,不能用于语音数据传输的是______</p>
|
||
<p>A.线路交换</p>
|
||
<p>B.报文交换</p>
|
||
<p>C.虚电路分组交换</p>
|
||
<p>D.数据报分组交换</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-14 21:05:18</p>
|
||
<p>-----每日一题 Day 65------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是_____</p>
|
||
<p>A 求单源最短路径的Dijkstra算法不适用于有负权边的有向网络。</p>
|
||
<p>B 最短路径一定是简单路径。</p>
|
||
<p>C 对有向图G ,如果以任一顶点出发进行一次深度优先或广度优先遍历能访问到每个顶点,则该图一定是完全图。</p>
|
||
<p>D 拓扑排序算法不适合无向图的拓扑顺序。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-17 19:07:37</p>
|
||
<p>-----每日一题 Day 66------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 零地址的运算类指令在指令格式中不给出操作数地址,参加的两个操作数来_____</p>
|
||
<p>A.累加器和寄存器</p>
|
||
<p>B.累加器和暂存器</p>
|
||
<p>C.堆栈的栈顶和次栈顶单元</p>
|
||
<p>D.暂存器和堆栈的栈顶单元</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-17 19:06:45</p>
|
||
<p>-----每日一题 Day 66------</p>
|
||
<p>操作系统</p>
|
||
<p>3 采用可重入程序是通过使用_______的方法来改善响应时间的。</p>
|
||
<p>A 减少用户数目 </p>
|
||
<p>B 改变时间片长短</p>
|
||
<p>C 加快对换速度 </p>
|
||
<p>D 减少对换信息量</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-17 19:05:24</p>
|
||
<p>-----每日一题 Day 66------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 流量控制是数据链路层的基本功能之一,有关流量控制,下列说法中正确的是_____</p>
|
||
<p>A.只有数据链路层存在流量控制</p>
|
||
<p>B.不只是数据链路层存在流量控制,不过各层的流量控制对象都一样</p>
|
||
<p>C.不只是数据链路层存在流量控制,但是各层的流量控制对象都不一样</p>
|
||
<p>D.以上都不对</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-17 19:03:17</p>
|
||
<p>-----每日一题 Day 66------</p>
|
||
<p>数据结构</p>
|
||
<p>1 如果在树的孩子兄弟链存储结构中有6 个空的左指针域, 7 个空的右指针域, 5 个节</p>
|
||
<p>点左右指针域都为空,则该树中叶子节点______</p>
|
||
<p>A. 有7个</p>
|
||
<p>B.有6个</p>
|
||
<p>C 有5个</p>
|
||
<p>D. 不能确定</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-18 18:16:45</p>
|
||
<p>-----每日一题 Day 67------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 在关于一地址运算类指令的叙述中,正确的是_____</p>
|
||
<p>A.仅有一个操作数,其地址由指令的地址码提供</p>
|
||
<p>B.可能有一个操作数,也可能有两个操作数</p>
|
||
<p>C.一定有两个操作数,另一个是隐含的</p>
|
||
<p>D.指令的地址码字段存放的一定是操作码</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-18 18:15:57</p>
|
||
<p>-----每日一题 Day 67------</p>
|
||
<p>操作系统</p>
|
||
<p>3 设基址寄存器的内容为 1000,在采用动态重定位的系统中,当执行指令“LOAD A,2000”时,操作数的实际地址是______ 。</p>
|
||
<p>A 1000 </p>
|
||
<p>B 2000</p>
|
||
<p>C 3000 </p>
|
||
<p>D 4000</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-18 18:15:06</p>
|
||
<p>-----每日一题 Day 67------</p>
|
||
<p>计算机网络</p>
|
||
<ol start="2">
|
||
<li>在数据帧中,当所传送的数据中出现控制字符时,就必须采取适当的措施,使接收方不至于将数据误认为是控制信息。这样才能保证数据链路层的传输是_____的。</li>
|
||
</ol>
|
||
<p>A.透明</p>
|
||
<p>B.面向连接</p>
|
||
<p>C.冗余</p>
|
||
<p>D.无连接</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-18 18:14:03</p>
|
||
<p>-----每日一题 Day 67------</p>
|
||
<p>数据结构</p>
|
||
<p>1 若3叉树中有a 个度为1 的节点、b 个度为2 的节点、c 个度为3 的节点,则该树有_____</p>
|
||
<p>个叶子节点。</p>
|
||
<p>A. 1+2b+3c</p>
|
||
<p>B. 1+2b+3c</p>
|
||
<p>C. 2b+3c</p>
|
||
<p>D. 1+b+2c</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-20 17:35:04</p>
|
||
<p>-----每日一题 Day 68------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 直接、间接、立即3种寻址方式指令的执行速度,由快至慢的排序是______</p>
|
||
<p>A.直接、立即、间接</p>
|
||
<p>B.直接、间接、立即</p>
|
||
<p>C.立即、直接、间接</p>
|
||
<p>D.立即、间接、直接</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-20 17:34:18</p>
|
||
<p>-----每日一题 Day 68------</p>
|
||
<p>操作系统</p>
|
||
<p>3 以下叙述中正确的是_________。</p>
|
||
<p>A 请求页式管理中,只要发生缺页中断,就应该淘汰内存中的一页,然后将当前要访问的页放入内存</p>
|
||
<p>B 在单用户、单任务系统中,在任何时候都只有一个程序运行,内存中只能放一道用户程序,也只有在一个程序运行完毕之后,才能装入下一个程序</p>
|
||
<p>C 请求页式管理中的置换算法是为了解决逻辑地址与物理地理的映射问题</p>
|
||
<p>D 页式管理中,地址越界保护是界地址寄存器来完成的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-20 17:33:35</p>
|
||
<p>-----每日一题 Day 68------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 大量的广播信息会降低整个网络的性能是因为______</p>
|
||
<p>A.网络上的每台计算机必须为每个广播信息发送一个确认信息</p>
|
||
<p>B.网络上的每台计算机必须处理每个广播信息</p>
|
||
<p>C.广播信息被自动路由到每个网段</p>
|
||
<p>D广播信息不能自动转送到目的计算机</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-20 17:32:44</p>
|
||
<p>-----每日一题 Day 68------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一棵有124 个叶子节点的完全二叉树,最多有______个节点。</p>
|
||
<p>A 247</p>
|
||
<p>B 248</p>
|
||
<p>C 249</p>
|
||
<p>D 250</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-21 18:24:34</p>
|
||
<p>-----每日一题 Day 69------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 在变址寄存器寻址方式中,若变址寄存器的内容是4E3CH,指令中的形式地址是63H,则它对应的有效地址是_____</p>
|
||
<p>A. 63H</p>
|
||
<p>B. 4D9FH</p>
|
||
<p>C. 4E3CH</p>
|
||
<p>D. 4E9FH</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-21 18:23:52</p>
|
||
<p>-----每日一题 Day 69------</p>
|
||
<p>操作系统</p>
|
||
<p>3 以下叙述中错误的是_________。 </p>
|
||
<p>A 段式管理把一个进程的虚拟地址空间设计成二维结构,即段号与段内绝对地址</p>
|
||
<p>B 段页式管理的虚拟地址空间是三维的,即段号、页号和页内地址</p>
|
||
<p>C 段式管理中,段的划分不是固定长度的</p>
|
||
<p>D 动态页式管理中的几种常用的淘汰算法都可以用于段页式管理时的淘汰算法中</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-21 18:23:05</p>
|
||
<p>-----每日一题 Day 69------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 载波侦听多路访问即CSMA________</p>
|
||
<p>A 只用于总线拓扑结构</p>
|
||
<p>B.只用于环状拓扑结构</p>
|
||
<p>C 只用于星状拓扑结构</p>
|
||
<p>D.能用于星状拓扑结构和总线拓扑结构</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-21 18:22:08</p>
|
||
<p>-----每日一题 Day 69------</p>
|
||
<p>数据结构</p>
|
||
<p>1 若二叉树采用二叉链存储结构,如果要交换其所有分支节点的左、右子树位置,利用______遍历方法最合适。</p>
|
||
<p>A. 先序</p>
|
||
<p>B. 中序</p>
|
||
<p>C. 后序</p>
|
||
<p>D. 按层次</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-24 16:31:14</p>
|
||
<p>-----每日一题 Day 70------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 _______方式用来支持浮动程序设计。</p>
|
||
<p>A.相对寻址</p>
|
||
<p>B.变址寻址</p>
|
||
<p>C.寄存器间接寻址</p>
|
||
<p>D.基址寻址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-24 16:30:33</p>
|
||
<p>-----每日一题 Day 70------</p>
|
||
<p>操作系统</p>
|
||
<p>3 在配有操作系统的计算机中,用户程序通过____向操作系统指出使用外部设备的要求。</p>
|
||
<p>A 作业申请 </p>
|
||
<p>B 原语</p>
|
||
<p>C 系统调用 </p>
|
||
<p>D I/O指令</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-24 16:29:52</p>
|
||
<p>-----每日一题 Day 70------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 有关虚拟局域网的概念,下面说法中不正确的是______</p>
|
||
<p>A.虚拟网络是建立在局域网交换机上的,以软件方式实现的逻辑工作组</p>
|
||
<p>B.可以使用交换机的端口划分虚拟局域网,且虚拟局域网可以跨越多个交换机</p>
|
||
<p>C.在使用MAC地址划分的虚拟局域网中,连接到集线器上的所有结点只能被划分到一个虚拟局域网中</p>
|
||
<p>D.在虚拟局域网中的逻辑工作组各结点可以分布在同一物理网段上,也可以分布在不同的物理网段上</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-24 16:29:01</p>
|
||
<p>-----每日一题 Day 70------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是_____</p>
|
||
<p>A 哈夫曼树是带权路径长度最短的树,路径上权值较大的节点离根较近。</p>
|
||
<p>B 在先序遍历二叉树的序列中,任何节点其子树的所有节点都是直接跟在该节点之后的。</p>
|
||
<p>C 存在这样的二叉树,对它采用任何次序的遍历,结果都相同。</p>
|
||
<p>D 若一个叶子节点是某二叉树先序遍历序列中的最后一个节点,则它必是该树中序遍历序列中的最后一个节点。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-25 17:52:05</p>
|
||
<p>-----每日一题 Day 71------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 将子程序返回地址放在______中时,子程序允许嵌套和递归。</p>
|
||
<p>A.寄存器</p>
|
||
<p>B.堆栈</p>
|
||
<p>C.子程序的结束位置</p>
|
||
<p>D.子程序的起始位置</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-25 17:51:26</p>
|
||
<p>-----每日一题 Day 71------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列有关设备的叙述中错误的是___________。</p>
|
||
<p>A 缓冲区的引入,使得CPU和外设之间速度的不匹配现象得到了缓解,同时也缓解了通道方式的瓶颈问题</p>
|
||
<p>B 打印机通过SPOOLING技术改造后,可以成为供多个用户同时使用的虚拟设备</p>
|
||
<p>C 通道程序是由发出I/O设备请求的用户编制的,所以,该用户必须指出通道程序在内存的存放位置</p>
|
||
<p>D 缓冲区是外设在进行数据传输期间专门用来暂存这些数据的主存区域</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-25 17:50:36</p>
|
||
<p>-----每日一题 Day 71------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 如果一个局域网有11台主机与1台服务器,使用一个12端口的集线器连接了主机与服务器,则同时可以有______条并发的连接。</p>
|
||
<p>A. 11</p>
|
||
<p>B. 12</p>
|
||
<p>C 1</p>
|
||
<p>D. 2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-25 17:49:38</p>
|
||
<p>-----每日一题 Day 71------</p>
|
||
<p>数据结构</p>
|
||
<p>1 数组A[0...5][0...6] 的每个元素占5 个单元,将其按列优先次序存储在起始地址为1000 的连续内存单元中,则元素a[5][5] 的地址为______</p>
|
||
<p>A. 1175</p>
|
||
<p>B. 1180</p>
|
||
<p>C. 1205</p>
|
||
<p>D. 1210</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-26 17:32:19</p>
|
||
<p>-----每日一题 Day 72------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 变址寻址和基址寻址的有效地址形成方式类似,但______</p>
|
||
<p>A.变址寄存器的内容在程序执行过程中是不能改变的</p>
|
||
<p>B.基址寄存器的内容在程序执行过程中是可以改变的</p>
|
||
<p>C 在程序执行过程中,变址寄存器的内容不能改变而基址寄存器的内容可变</p>
|
||
<p>D.在程序执行过程中,基址寄存器的内容不能改变而变址寄存器的内容可变</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-26 17:31:40</p>
|
||
<p>-----每日一题 Day 72------</p>
|
||
<p>操作系统</p>
|
||
<p>3 在下列叙述中,正确的一条是_____。</p>
|
||
<p>A 在设备I/O中引入缓冲技术的目的是为了节省内存</p>
|
||
<p>B 指令中的地址结构和外存容量是决定虚存作业地址空间的两个因素</p>
|
||
<p>C 处于阻塞状态的进程被唤醒后,可直接进入运行状态</p>
|
||
<p>D 在请求页式管理中,FIFO置换算法的内存利用率是较高的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-26 17:31:02</p>
|
||
<p>-----每日一题 Day 72------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 假如需要构建一个办公室网络,包含22台主机和1台服务器,并与学校的交换网相连接,下列设计中哪项性能最优_______</p>
|
||
<p>A.使用一个24端口/10M的集线器</p>
|
||
<p>B.使用一个24端口/10M的集线器,其中两个端口为10/100M</p>
|
||
<p>C.使用一个24端口/10M的交换机</p>
|
||
<p>D 使用一个24端口/10M的交换机,其中两个端口为10/100M</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-26 17:30:11</p>
|
||
<p>-----每日一题 Day 72------</p>
|
||
<p>数据结构</p>
|
||
<p>1 最适合用做链式队列的链表是______</p>
|
||
<p>A. 带队首指针和队尾指针的循环单链表</p>
|
||
<p>B. 带队首指针和队尾指针的非循环单链表</p>
|
||
<p>C. 只带队首指针的非循环单链表</p>
|
||
<p>D.只带队首指针的循环单链表</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-27 18:07:48</p>
|
||
<p>-----每日一题 Day 73------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法正确的是______</p>
|
||
<p>A 数据寻址的最终目的是寻找操作数的有效地址。</p>
|
||
<p>B 若操作数在寄存器中,可以采用直接寻址。</p>
|
||
<p>C 寄存器堆栈的栈指针SP指向栈顶。</p>
|
||
<p>D 对于自底向上生成的软堆栈,进栈时应先修改栈指针,再将数据压入堆栈。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-27 18:07:07</p>
|
||
<p>-----每日一题 Day 73------</p>
|
||
<p>操作系统</p>
|
||
<p>3 正在运行的进程在信号量S上作P操作之后,当S&lt;0,进程将进入信号量的______ 。</p>
|
||
<p>A 等待队列 </p>
|
||
<p>B 提交队列</p>
|
||
<p>C 后备队列 </p>
|
||
<p>D 就绪队列</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-27 18:06:29</p>
|
||
<p>-----每日一题 Day 73------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列各项中,不属于基于网络层地址的虚拟局域网的优势的是_____</p>
|
||
<p>A.能够按协议类型来划分网段</p>
|
||
<p>B.用户可以在网络内部自由移动</p>
|
||
<p>C.可以缩小网络规模</p>
|
||
<p>D.能够减小由于协议转换而造成的网络延迟</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-27 18:02:29</p>
|
||
<p>-----每日一题 Day 73------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在一个具有n 个结点的有序单链表中插入一个新结点并仍然保待有序的时间复杂度是_____。</p>
|
||
<p>A. O(1)</p>
|
||
<ol start="8">
|
||
<li>O(n)</li>
|
||
</ol>
|
||
<p>C. O(n^2)</p>
|
||
<p>D. O(nlogn)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-28 18:09:39</p>
|
||
<p>-----每日一题 Day 74------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 I/O编址方式通常可分统一编址和独立编址,___________</p>
|
||
<p>A.统一编址是将I/O地址看作是存储器地址的一部分,可用专门的I/O指令对设备进行访问</p>
|
||
<p>B.独立编址是指I/O地址和存储器地址是分开的,所以对I/O访问必须有专门的I/O指令</p>
|
||
<p>C.统一编址是指I/O地址和存储器地址是分开的,所以可用访存指令实现CPU对设备的访问</p>
|
||
<p>D.独立编址是将I/O地址看作是存储器地址的一部分,所以对I/O访问必须有专门的I/O指令</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-28 18:08:56</p>
|
||
<p>-----每日一题 Day 74------</p>
|
||
<p>操作系统</p>
|
||
<p>3 预先静态分配法是通过破坏______条件,来达到预防死锁目的的。</p>
|
||
<p>A 互斥使用资源/循环等待资源</p>
|
||
<p>B 非抢占式分配/互斥使用资源</p>
|
||
<p>C 占有且等待资源/循环等待资源</p>
|
||
<p>D 循环等待资源/互斥使用资源</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-28 18:08:09</p>
|
||
<p>-----每日一题 Day 74------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 虚拟局域网中逻辑工作组的结点组成不受物理位置的限制,逻辑工作组的划分与管理是通过______实现的。</p>
|
||
<p>A.硬件方式</p>
|
||
<p>B.存储转发方式</p>
|
||
<p>C.改变接口连接方式</p>
|
||
<p>D软件方式</p>
|
||
<p>我发起了一个</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-28 18:05:51</p>
|
||
<p>-----每日一题 Day 74------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设线性表中有2n 个元素,算法______在单链表上实现要比在顺序表上实现效率更高。</p>
|
||
<p>A. 删除所有值为x 的元素</p>
|
||
<p>B. 在最后一个元素的后面插入一个新元素</p>
|
||
<p>C. 顺序输出前K 个元素</p>
|
||
<p>D. 交换第i 个元素和第2n-i-1 个元素的值( i=0, 1, …, n-1)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-31 18:46:35</p>
|
||
<p>-----每日一题 Day 75------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 将用8位二进制补码表示的十进制数-121,扩展成16位二进制补码,结果用十六进制表示为______</p>
|
||
<p>A. 0087H</p>
|
||
<p>B. FF87H</p>
|
||
<p>C. 8079H</p>
|
||
<p>D. FFF9H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-31 18:45:57</p>
|
||
<p>-----每日一题 Day 75------</p>
|
||
<p>操作系统</p>
|
||
<p>3 一个进程的某个基本状态可以从其他两种基本状态转变过来,这个基本状态一定</p>
|
||
<p>是______。</p>
|
||
<p>A.运行状态</p>
|
||
<p>B.阻塞状态</p>
|
||
<p>C.就绪状态</p>
|
||
<p>D.完成状态</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-31 18:45:16</p>
|
||
<p>-----每日一题 Day 75------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 有一个连接20台计算机的网络,其中5台连接到一个以太网集线器上,另外5台连接到另一个以太网集线器上,每个集线器分别连接到两个不同的交换机上,而两个交换机又分别连接到两个不同的路由器上,两个路由器通过以太网网桥互联,剩下的10台计算机直接连接到其中1台交换机上。那么,该网络有_______个以太网网段</p>
|
||
<p>A. 7</p>
|
||
<p>B. 12</p>
|
||
<p>C. 13</p>
|
||
<p>D. 16</p>
|
||
<hr>
|
||
<p>该题更新于:2022-10-31 18:44:27</p>
|
||
<p>-----每日一题 Day 75------</p>
|
||
<p>数据结构</p>
|
||
<p>1 二维数组M 的元素是4 个字符(每个字符占一个存储单元)组成的串,行下标i的范围从0 到4, 列下标j的范围从0到5, M按行存储时元素M[3][5] 的起始地址与M 按列存储时元素______的起始地址相同。</p>
|
||
<p>A. M[2][4]</p>
|
||
<p>B. M[3)[4]</p>
|
||
<p>C. M[3][5]</p>
|
||
<p>D. M[4][4]</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-01 18:12:07</p>
|
||
<p>-----每日一题 Day 76------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 在加法器、寄存器的基础上增加部分控制电路实现乘除法时,用B寄存器存放______</p>
|
||
<p>A.被乘数和被除数</p>
|
||
<p>B.被乘数和除数</p>
|
||
<p>C.乘数和被除数</p>
|
||
<p>D.乘数和除数</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-01 17:56:10</p>
|
||
<p>-----每日一题 Day 76------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列选项中,降低进程优先级的合理时机是_______ 。</p>
|
||
<p>A.进程的时间片用完</p>
|
||
<p>B.进程刚完成 I/O 而进入就绪队列</p>
|
||
<p>C.进程长期处于就绪队列中</p>
|
||
<p>D.进程从就绪状态转为运行状态</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-01 17:55:30</p>
|
||
<p>-----每日一题 Day 76------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 要构建一个可连接10个主机的网络(与其他网络互联),如果该网络采用划分子网的方法,则子网掩码为_______</p>
|
||
<p>A. 255.255. 255.0</p>
|
||
<p>B. 255.255.248.0</p>
|
||
<p>C. 255.255. 240.0</p>
|
||
<p>D. 255.255. 224.0</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-01 17:54:48</p>
|
||
<p>-----每日一题 Day 76------</p>
|
||
<p>数据结构</p>
|
||
<p>1 数组A中,每个元素A的长度为3个字节,行下标i从1到8, 列下标j从1 到10,从首地址SA开始连续存放在存储器内,该数组按行存放时,元素A[8][5]的起始地址为_______。</p>
|
||
<p>A. SA+141</p>
|
||
<p>B. SA+144</p>
|
||
<p>C. SA+222</p>
|
||
<p>D. SA+225</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-02 19:05:52</p>
|
||
<p>-----每日一题 Day 77------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 若浮点数用补码表示,判断运算结果是否是规格化数的方法是_____</p>
|
||
<p>A.阶符与数符相同</p>
|
||
<p>B.阶符与数符相异</p>
|
||
<p>C. 数符与尾数最高有效数位相同</p>
|
||
<p>D.数符与尾数最高有效数位相异</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-02 19:05:14</p>
|
||
<p>-----每日一题 Day 77------</p>
|
||
<p>操作系统</p>
|
||
<p>3 有3 个作业J1、J2 和J3,其运行时间分别是2、5 和3 小时,假定它们同时到达并在</p>
|
||
<p>同一台CPU 上以单道方式运行,则平均周转时间最小的执行序列是_______ 。</p>
|
||
<p>A.J1、J2、J3</p>
|
||
<p>B.J3、J2、J1</p>
|
||
<p>C.J2、J1、J3</p>
|
||
<p>D.J1、J3、J2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-02 19:04:34</p>
|
||
<p>-----每日一题 Day 77------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 假如一台连接到网络上的计算机的网络配置为:IP地址为136.62.2.55,子网掩码为255.255.192.0,网关地址为136.62.89.1。这台计算机在网络中不能与其他主机进行通信。其中哪一项设置导致了问题的产生______</p>
|
||
<p>A. 子网掩码</p>
|
||
<p>B. 网关地址</p>
|
||
<p>C. IP地址</p>
|
||
<p>D.其他配置</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-02 19:03:48</p>
|
||
<p>-----每日一题 Day 77------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在线索化二叉树t中, t所指结点没有左子树的充要条件是_______</p>
|
||
<p>A. t- &gt;lchild = NULL</p>
|
||
<p>B. t-&gt;ltag==1</p>
|
||
<p>C. t- &gt;ltag==1 且t-&gt;lchild==NULL</p>
|
||
<p>D . 以上都不对</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-03 18:12:58</p>
|
||
<p>-----每日一题 Day 78------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 两个浮点数相加,一个数的阶码值为7,另一个数的阶码值为9,则需要将阶码值较小的浮点数的小数点______</p>
|
||
<p>A.左移1位</p>
|
||
<p>B.右移1位</p>
|
||
<p>C.左移2位</p>
|
||
<p>D.右移2位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-03 18:12:21</p>
|
||
<p>-----每日一题 Day 78------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下面关于线程的叙述中,正确的是______。</p>
|
||
<p>A.内核态线程的切换都需要内核的支持</p>
|
||
<p>B.线程是资源的分配单位而进程是调度和分配的单位</p>
|
||
<p>C.不管系统中是否有线程,线程都是拥有资源的独立单位</p>
|
||
<p>D.在引入线程的系统中,进程仍然是资源分配和调度分派的基本单位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-03 18:11:37</p>
|
||
<p>-----每日一题 Day 78------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 IP数据报穿越Internet过程中有可能被分片。在IP数据报分片以后,下列_____设备(负责IP数据报的重组</p>
|
||
<p>A.源主机</p>
|
||
<p>B.目的主机</p>
|
||
<p>C.分片途经的路由器</p>
|
||
<p>D.分片途经的路由器或目的主机</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-03 18:10:45</p>
|
||
<p>-----每日一题 Day 78------</p>
|
||
<p>数据结构</p>
|
||
<p>1 某二叉树的先序遍历序列和后序遍历序列正好相反,则该二叉树一定是______</p>
|
||
<p>A. 空或只有—个结点</p>
|
||
<p>B. 完全二叉树</p>
|
||
<p>C. 二叉排序树</p>
|
||
<p>D . 高度等于其结点数</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-04 21:36:16</p>
|
||
<p>-----每日一题 Day 79------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列叙述中,错误的是____</p>
|
||
<p>运算器中通常都有一个状态标志寄存器,为计算机提供判断条件,以实现程序转移</p>
|
||
<p>B.补码乘法器中,被乘数和乘数的符号都不参加运算</p>
|
||
<p>C.并行加法器中高位的进位依赖于低位</p>
|
||
<p>D.在小数除法中,为了避免溢出,要求被除数的绝对值小于除数的绝对值</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-04 21:35:37</p>
|
||
<p>-----每日一题 Day 79------</p>
|
||
<p>操作系统</p>
|
||
<p>3 对两个并发进程,设互斥信号量为 mutex (mutex.value 初值为 1 ),若 mutex.value 当前值为-1 ,则______。</p>
|
||
<p>A 表示没有进程进入临界区</p>
|
||
<p>B 表示有一个进程进入临界区</p>
|
||
<p>C 表示有 一个进程进入临界区,而另一个进程等待进入临界区</p>
|
||
<p>D 表示有两个进程进入临界区</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-04 21:34:25</p>
|
||
<p>-----每日一题 Day 79------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下面哪个IP地址是有效的________</p>
|
||
<p>A. 202. 280.130.45</p>
|
||
<p>B. 130.192.33.45</p>
|
||
<p>C. 192.256.130.45</p>
|
||
<p>D. 280. 192.33.456</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-04 21:33:40</p>
|
||
<p>-----每日一题 Day 79------</p>
|
||
<p>数据结构</p>
|
||
<p>1 对某个无向图的邻接矩阵来说_______。</p>
|
||
<p>A. 第i 行上的非零元素个数和第i 列的非零元素个数一定相等</p>
|
||
<p>B .矩阵中的非零元素个数等于图中的边数</p>
|
||
<p>C. 第i 行上,第i 列上非零元素总数等于顶点vi的度数</p>
|
||
<p>D . 矩阵中非全零行的行数等于图中的顶点数</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-07 18:53:10</p>
|
||
<p>-----每日一题 Day 80------</p>
|
||
<p>4 若数据在存储器中采用以低字节地址为字地址的存放方式,则十六进制数12345678H的存储字节顺序按地址由小到大依次为______</p>
|
||
<p>A. 12345678</p>
|
||
<p>B. 78563412</p>
|
||
<p>C. 87654321</p>
|
||
<p>D. 34127856</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-07 18:52:30</p>
|
||
<p>-----每日一题 Day 80------</p>
|
||
<p>操作系统</p>
|
||
<p>3 在 9 个生产者、 6 个消费者共享 8 个单元缓冲区的生产者 消费者问题中,互斥使用</p>
|
||
<p>缓冲区的信号量其初始值为_______。</p>
|
||
<p>A 1</p>
|
||
<p>B 6</p>
|
||
<p>C 8</p>
|
||
<p>D 9</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-07 18:51:50</p>
|
||
<p>-----每日一题 Day 80------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 网络中发生了拥塞,根据是_______</p>
|
||
<p>A.随着通信子网的负载的增加,吞吐量也增加</p>
|
||
<p>B.网络结点接收和发出的分组越来越少</p>
|
||
<p>C.网络结点接收和发出的分组越来越多</p>
|
||
<p>D.随着通信子网的负载的增加,吞吐量反而降低</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-07 18:51:00</p>
|
||
<p>-----每日一题 Day 80------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一棵深度为k的平衡二叉树,其每个非终端结点的平衡因子均为0,则该树共有_____个结点。</p>
|
||
<p>A. 2^(k-1)-1</p>
|
||
<p>B. 2^(k-1)</p>
|
||
<p>C. 2^(k-1)+1</p>
|
||
<p>D. 2^(k)-1</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-08 18:04:46</p>
|
||
<p>-----每日一题 Day 81------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 存储器采用部分译码法片选时_____</p>
|
||
<p>A.不需要地址译码器</p>
|
||
<p>B.不能充分利用存储器空间</p>
|
||
<p>C.会产生地址重叠</p>
|
||
<p>D. CPU的地址线全参与译码</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-08 18:04:04</p>
|
||
<p>-----每日一题 Day 81------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下面关于重定位的描述中,错误的是 _____</p>
|
||
<p>A 绝对地址是内存空间的地址编号</p>
|
||
<p>B 用户程序中使用从 0 地址开始的地址编号是逻辑地址</p>
|
||
<p>C 动态重定位中装入内存的程序仍保持原来的逻辑地址</p>
|
||
<p>D 静态重定位中装入内存的程序仍保持原来的逻辑地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-08 18:03:25</p>
|
||
<p>-----每日一题 Day 81------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 关于子网与子网掩码,下列说法中正确的是______</p>
|
||
<p>通过子网掩码,可以从一个IP地址中提取出网络号、子网号与主机号</p>
|
||
<p>子网掩码可以把一个网络进一步划分成几个规模相同或不同的子网</p>
|
||
<p>C.子网掩码中的0和1一定是连续的</p>
|
||
<p>D.一个B类地址采用划分子网的方法,最多可以划分为255个子网</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-08 18:02:45</p>
|
||
<p>-----每日一题 Day 81------</p>
|
||
<p>数据结构</p>
|
||
<p>1 假定n&gt;2,计算机执行下面的语句时,语句S的执行次数为_____。</p>
|
||
<p>for (i=1; i&lt;n-1; i++)</p>
|
||
<pre><code> for (j=n;j&gt;=i; j- -)
|
||
|
||
S;
|
||
</code></pre>
|
||
<p>A. n(n-1)</p>
|
||
<p>B. (n+3)(n-2)/2</p>
|
||
<p>C. (n+2)(n-1)/2</p>
|
||
<p>D. n(n-1)/2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-09 19:36:30</p>
|
||
<p>-----每日一题 Day 82------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 双端口存储器发生读写冲突的情况是______</p>
|
||
<p>A.左端口与右端口的地址码不同</p>
|
||
<p>B.左端口与右端口的地址码相同</p>
|
||
<p>C.左端口与右端口的数据码相同</p>
|
||
<p>D.左端口与右端口的数据码不同</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-09 19:35:53</p>
|
||
<p>-----每日一题 Day 82------</p>
|
||
<p>操作系统</p>
|
||
<p>3 分区分配内存管 理方式的主要保护措施是 ______</p>
|
||
<p>A 界地址保护</p>
|
||
<p>B 程序代码保护</p>
|
||
<p>C 数据保护</p>
|
||
<p>D 栈保护</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-09 19:35:16</p>
|
||
<p>-----每日一题 Day 82------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列哪项不属于路由选择协议的功能_____</p>
|
||
<p>A.获取网络拓扑结构的信息</p>
|
||
<p>B 选择到达每个目的网络的最优路径</p>
|
||
<p>C.构建路由表</p>
|
||
<p>D.发现下一跳的物理地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-09 19:34:40</p>
|
||
<p>-----每日一题 Day 82------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设abcd以所给的次序进栈,在进栈操作时,允许退栈操作。若要使输出序列变为cbad,栈的操作序列为_____</p>
|
||
<p>A. Push, Pop, Push, Pop, Push, Pop, Push, Pop</p>
|
||
<p>B. Push, Push, Push, Pop, Pop, Push, Pop, Pop</p>
|
||
<p>C. Push, Push, Pop, Push, Pop, Pop, Push, Pop</p>
|
||
<p>D. Push, Push, Push, Pop, Pop, Pop, Push, Pop</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-10 18:00:56</p>
|
||
<p>-----每日一题 Day 83------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 容量为64块的cache采用组相联映射方式,字块大小为128个字,每4块为一组。若主存4096块,且以字编址,那么主存地址和主存标记的位数分别为_____</p>
|
||
<p>A. 16,6</p>
|
||
<p>B. 17,6</p>
|
||
<p>C. 18,8</p>
|
||
<p>D. 19,8</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-10 18:00:21</p>
|
||
<p>-----每日一题 Day 83------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下面最有可能使得高地址空间成为大的空闲区的分配算法是 ______。</p>
|
||
<p>A 首次适应算法</p>
|
||
<p>B 最佳适应算法</p>
|
||
<p>C 最 差 适应算法</p>
|
||
<p>D 循环首次适应算法</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-10 17:59:38</p>
|
||
<p>-----每日一题 Day 83------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在IP数据报头部中有两个有关长度的字段,一个为头部长度字段,一个为总长度字段。其中_____</p>
|
||
<p>A.头部长度字段和总长度字段都以8比特为计数单位</p>
|
||
<p>B.头部长度字段以8比特为计数单位,总长度字段以32比特为计数单位</p>
|
||
<p>C.头部长度字段以32比特为计数单位,总长度字段以8比特为计数单位</p>
|
||
<p>D.头部长度字段和总长度字段都以32比特为计数单位</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-10 17:58:59</p>
|
||
<p>-----每日一题 Day 83------</p>
|
||
<p>数据结构</p>
|
||
<p>1 用不带头结点的单链表存储队列时,其队头指针指向队头结点,其队尾指针指向队尾结点,则在进行删除操作时______</p>
|
||
<p>A.仅修改队头指针</p>
|
||
<p>B.仅修改队尾指针</p>
|
||
<p>C.队头和队尾指针都要修改</p>
|
||
<p>D.队头和队尾指针都可能要修改</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-11 16:22:39</p>
|
||
<p>-----每日一题 Day 84------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 虚拟存储器中的页表有快表和慢表之分,下面关于页表的叙述中正确的______</p>
|
||
<p>A.快表与慢表都存储在主存中,但快表比慢表容量小</p>
|
||
<p>B.快表采用了优化的搜索算法,因此查找速度快</p>
|
||
<p>C.快表比慢表的命中率高,因此快表可以得到更多的搜索结果</p>
|
||
<p>D.快表采用快速存储器件组成,按照查找内容访问,因此比慢表查找速度快</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-11 16:22:00</p>
|
||
<p>-----每日一题 Day 84------</p>
|
||
<p>操作系统</p>
|
||
<p>3 操作系统采用分页存储管理方式,要求______。</p>
|
||
<p>A 每个进程拥有一张页表,且进程的页表驻留在内存 中</p>
|
||
<p>B 每个进程拥有一张页表,但只有当前运行进程的页表驻留在内存中</p>
|
||
<p>C 所有进程共享一张页表以节约有限的内存,但页表必须驻留在内存中</p>
|
||
<p>D 所有进程共享一张页表,只有页表中当前使用的页必须驻留在内存中</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-11 16:21:24</p>
|
||
<p>-----每日一题 Day 84------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 提供虚电路服务是网络层向传输层提供的一种服务,在进行数据交换的两个端系统之间_______</p>
|
||
<p>只能有一条虚电路,但能为不同的进程服务</p>
|
||
<p>B.可以有多条虚电路为不同的进程服务</p>
|
||
<p>C.只能有一条虚电路为一个进程服务</p>
|
||
<p>D.可以有多条虚电路为一个进程服务</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-11 16:20:36</p>
|
||
<p>-----每日一题 Day 84------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法不正确的是_____</p>
|
||
<p>A.在算法中消除递归不一定需要使用栈</p>
|
||
<p>B.栈是实现过程和函数等子程序调用时所必需的结构</p>
|
||
<p>C.任何一个递归过程都可以转换成非递归过程</p>
|
||
<p>D.只有使用了局部变量的递归过程在转换成非递归过程时才必须使用栈</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-14 18:30:12</p>
|
||
<p>-----每日一题 Day 85------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法中正确的是_____</p>
|
||
<p>微程序控制方式与硬布线控制方式相比较,前者可以使指令的执行速度更快</p>
|
||
<p>B.若采用微程序控制方式,则可用μPC取代PC</p>
|
||
<p>C.控制存储器可以用掩膜ROM、EPROM或闪速存储器实现</p>
|
||
<p>D.指令周期也称为CPU周期</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-14 18:29:27</p>
|
||
<p>-----每日一题 Day 85------</p>
|
||
<p>操作系统</p>
|
||
<p>3 虚存管理和实存管理的主要区别是 ______。</p>
|
||
<p>A 虚存管理区分逻辑地址和物理地址,实存管理则不区分</p>
|
||
<p>B 实存管理要求一程序在内存必须连续,而虚存管理则不需要连续的内存</p>
|
||
<p>C 实存管理要求程序必须全部装入内存才开始运行,而虚存管理则允许程序在执行</p>
|
||
<p>过程中逐步装入</p>
|
||
<p>D 虚存管理以逻辑地址执行程序,而实存管理以物理地址执行程序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-14 18:28:49</p>
|
||
<p>-----每日一题 Day 85------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 动态路由选择和静态路由选择的主要区别在哪里_____</p>
|
||
<p>A.动态路由选择需要维护整个网络的拓扑结构信息,而静态路由选择只需要维护有限的拓扑结构信息</p>
|
||
<p>B.动态路由选择需要使用路由选择协议去发现和维护路由信息,而静态路由选择只需要手动配置路由信息</p>
|
||
<p>C.动态路由选择的可扩展性要大大优于静态路由选择,因为在网络拓扑发生变化时路由选择不需要手动配置去通知路由器</p>
|
||
<p>D.动态路由选择使用路由表,而静态路由选择不使用路由表</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-14 18:28:08</p>
|
||
<p>-----每日一题 Day 85------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下述说法不正确的是_____</p>
|
||
<p>A.数组可看成线性结构的一种推广,因此与线性表一样,可以对它进行插入、删除等操作</p>
|
||
<p>B.稀疏矩阵以三元组表压缩存储后,必会失去随机存取功能</p>
|
||
<p>C.从逻辑结构上看,n维数组的每个元素均属于n个向量</p>
|
||
<p>D.数组也能采用链式存储结构</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-15 17:09:26</p>
|
||
<p>-----每日一题 Day 86------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列叙述中正确的是_____</p>
|
||
<p>A.控制器产生的所有控制信号称为微指令</p>
|
||
<p>B.微程序控制器比硬布线控制器更加灵活</p>
|
||
<p>C.微处理器的程序称为微程序</p>
|
||
<p>D.采用微程序控制器的处理器称为微处理器</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-15 17:08:53</p>
|
||
<p>-----每日一题 Day 86------</p>
|
||
<p>操作系统</p>
|
||
<p>3 为了使虚拟系统有效地发挥其预期的作用,所运行的程序应具有的特性是 _______。</p>
|
||
<p>A 该程序不应含有过多的 I/O 操作</p>
|
||
<p>B 该程序的大小不应超过实际的内存容量</p>
|
||
<p>C 该程序应具有较好的局部性</p>
|
||
<p>D 该程序的指令相关不应过多</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-15 17:08:21</p>
|
||
<p>-----每日一题 Day 86------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 使用距离矢量路由选择协议的路由器通过以下哪种方式获得最佳路径____</p>
|
||
<p>A.通过向相邻路由器发送一次广播以询问最佳路径</p>
|
||
<p>B.运行最短路径优先(SPF)算法</p>
|
||
<p>C.将接收到的路径的度量增加1</p>
|
||
<p>D.测试每条路径</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-15 17:07:43</p>
|
||
<p>-----每日一题 Day 86------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一棵左右子树均不空的二叉树在先序线索化后,其中空的链域的个数是______</p>
|
||
<p>A. 0</p>
|
||
<p>B. 1</p>
|
||
<p>C 2</p>
|
||
<p>D.不确定</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-16 17:11:09</p>
|
||
<p>-----每日一题 Day 87------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 微程序控制器中,机器指令与微指令的关系是______</p>
|
||
<p>A.每一条机器指令由一条微指令来执行</p>
|
||
<p>B.一条机器指令由一段用微指令编成的微程序来解释执行</p>
|
||
<p>C.一段机器指令组成的程序可由一个微程序来执行</p>
|
||
<p>D.每一条微指令由一条机器指令来解释执行</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-16 17:10:24</p>
|
||
<p>-----每日一题 Day 87------</p>
|
||
<p>操作系统</p>
|
||
<p>3 程序在执行中发 生缺页中断,由系统将该缺页调入内存后应继续执行______ 。</p>
|
||
<p>A.被中断的前一条指令</p>
|
||
<p>B.被中断的指令</p>
|
||
<p>C.被中断的后一条指令</p>
|
||
<p>D.程序的第一条指令</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-16 17:09:29</p>
|
||
<p>-----每日一题 Day 87------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在距离矢量路由选择协议中,下列哪项最可能导致路由回路问题?_____</p>
|
||
<p>A.由于网络带宽的限制,某些路由更新数据包被丢弃,</p>
|
||
<p>B.由于路由器不知道整个网络的拓扑结构信息,当收到一个路由更新信息时,又将该更新信息发回向自己发送该路由信息的路由器</p>
|
||
<p>C.当一个路由器发现自己的一条直接相邻链路断开时,没能将这个变化报告给其他路由器</p>
|
||
<p>D.慢收敛导致路由器接收了无效的路由信息</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-16 17:08:26</p>
|
||
<p>-----每日一题 Day 87------</p>
|
||
<p>数据结构</p>
|
||
<p>1 当一棵有n个结点的二叉树按层次从上到下,同层次从左到右将结点中的数据存放在一维数组A[1..n]中时,数组中第i个结点的左孩子为_____</p>
|
||
<p>A. A[i/2]</p>
|
||
<p>B. A[2i](若2i&lt;=n)</p>
|
||
<p>C. A[2i+1](若2i+1&lt;=n)</p>
|
||
<p>D.不能确定</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-17 17:54:38</p>
|
||
<p>-----每日一题 Day 88------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 微程序控制器中,微程序的入口地址是由_____形成的。</p>
|
||
<p>A.机器指令的地址码字段</p>
|
||
<p>B.微指令的微地址码字段</p>
|
||
<p>C.机器指令的操作码字段</p>
|
||
<p>D.微指令的微操作码字段</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-17 17:53:58</p>
|
||
<p>-----每日一题 Day 88------</p>
|
||
<p>操作系统</p>
|
||
<p>3 有关虚拟存储器的叙述中,正确的是_____</p>
|
||
<p>A 程序运行前必须全部装入内存,且在运行中必须常驻内存</p>
|
||
<p>B 程序运行前不必全部装入内存,且在运行中不必常驻内存</p>
|
||
<p>C 程序运行前不必全部装入内存,但在运行中必须常驻内存</p>
|
||
<p>D 程序运行前必须全部装入内存,但 在运行中不必常驻内存</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-17 17:53:18</p>
|
||
<p>-----每日一题 Day 88------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 当一个IP分组进行直接交付时,要求发送站和目的站具有相同的_____</p>
|
||
<p>A. IP地址</p>
|
||
<p>B.主机号</p>
|
||
<p>C.网络号</p>
|
||
<p>D.子网地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-17 17:52:32</p>
|
||
<p>-----每日一题 Day 88------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在下列叙述中,正确的叙述是______</p>
|
||
<p>A.树的先序遍历和中序遍历可以得到树的后序遍历</p>
|
||
<p>B.将一棵树转换成二叉树后,根结点没有右子树</p>
|
||
<p>C.采用二叉链表作存储结构,树的先序遍历和其相应的二叉树的先序遍历的结果不同</p>
|
||
<p>D.一棵树中的叶子结点数一定等于与其对应的二叉树的叶子结点数</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-18 17:09:18</p>
|
||
<p>-----每日一题 Day 89------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 微指令执行的顺序控制问题,实际上是如何确定下一条微指令的地址问题。通常采用的一种方法是断定方式。其基本思想是_______</p>
|
||
<p>A.用程序计数器PC来产生后继微指令地址</p>
|
||
<p>B.用微程序计数器μPC来产生后继微指令地址</p>
|
||
<p>C.通过微指令顺序控制字段由设计者指定或者由判断字段控制产生后继微指令地址</p>
|
||
<p>D.通过指令中指定一个专门字段来控制产生后继微指令地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-18 17:08:38</p>
|
||
<p>-----每日一题 Day 89------</p>
|
||
<p>操作系统</p>
|
||
<p>3 在请求分页存储管理中,若进程访问的页不在内存且内存又没有可用的 物理 块时,系</p>
|
||
<p>统正确的处理顺序为 _______。</p>
|
||
<p>A.决定淘汰页,页调出,缺页中断,页调入</p>
|
||
<p>B.决定淘汰页,页调入,缺页中断,页调出</p>
|
||
<p>C.缺页中断,决定淘汰页,页调出,页调入</p>
|
||
<p>D.缺页中断,决定淘汰页,页调入,页调出</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-18 17:07:56</p>
|
||
<p>-----每日一题 Day 89------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 关于TCP和UDP端口,下列说法中正确的是______</p>
|
||
<p>TCP和UDP分别拥有自己的端口号,二者互不干扰,可以共存于同一台主机</p>
|
||
<p>TCP和UDP分别拥有自己的端口号,但二者不能共存于同一台主机</p>
|
||
<p>C TCP和UDP的端口号没有本质区别,二者互不干扰,可以共存于同一台主机</p>
|
||
<p>D. TCP和UDP的端口号没有本质区别,但二者相互干扰,不能共存于同一台主机</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-18 17:07:18</p>
|
||
<p>-----每日一题 Day 89------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在下列叙述中,错误的叙述是_____</p>
|
||
<p>A.哈夫曼树是带权路径最短的树,路径上权值较大的结点离根较近</p>
|
||
<p>B.哈夫曼树的结点个数不能是偶数</p>
|
||
<p>C.给定一组叶结点的权值,构造出的哈夫曼树结构不唯一</p>
|
||
<p>D.一棵哈夫曼树的带权路径长度等于其中所有分支结点的权值之和</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-21 19:41:55</p>
|
||
<p>-----每日一题 Day 90------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 在下列存储器中,若按存取速度从快到慢的顺序排列,应当为_______</p>
|
||
<p>高速缓存、寄存器组、主存、磁带、软磁盘、活动头硬磁盘</p>
|
||
<p>寄存器组、高速缓存、主存、磁带、软磁盘、活动头硬磁盘</p>
|
||
<p>寄存器组、高速缓存、主存、软磁盘、活动头硬磁盘、磁带</p>
|
||
<p>寄存器组、高速缓存、主存、活动头硬磁盘、软磁盘、磁带</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-21 19:41:08</p>
|
||
<p>-----每日一题 Day 90------</p>
|
||
<p>操作系统</p>
|
||
<p>3 与设备相关的中断处理过程是由_______完成的。</p>
|
||
<p>A 用户级 I/O</p>
|
||
<p>B 与设备无关的操作系统软件</p>
|
||
<p>C 中断处理</p>
|
||
<p>D 设备驱动程序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-21 19:40:21</p>
|
||
<p>-----每日一题 Day 90------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列关于TCP协议的叙述中,正确的是______</p>
|
||
<p>A. TCP是一个点到点的通信协议</p>
|
||
<p>B. TCP提供了无连接的可靠数据传输</p>
|
||
<p>TCP将来自上层的字节流组织成数据报,然后交给IP协议</p>
|
||
<p>D. TCP将收到的报文段组织成字节流提交给上层</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-21 19:39:28</p>
|
||
<p>-----每日一题 Day 90------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列关于AOE网的说法正确的是_____。</p>
|
||
<p>A. AOE网的含义是以顶点表示活动的网</p>
|
||
<p>B.从源点到汇点的最短路径称作关键路径</p>
|
||
<p>C.存在关键路径的AOE网一定是有向无环图</p>
|
||
<p>D.关键路径上某个活动的时间缩短,整个工程的时间也就必定缩短</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-22 18:34:17</p>
|
||
<p>-----每日一题 Day 91------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 以下论述正确的是_____</p>
|
||
<p>A. CPU响应中断期间仍执行原程序</p>
|
||
<p>B.在中断过程中,若又有中断源提出中断请求,CPU立即响应</p>
|
||
<p>C.在中断响应中,保护断点、保护现场应由用户编程完成</p>
|
||
<p>D.在中断响应中,保护断点是由中断隐指令自动完成的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-22 18:32:46</p>
|
||
<p>-----每日一题 Day 91------</p>
|
||
<p>操作系统</p>
|
||
<p>3 为提高存储器存取效率,在安排磁盘上信息分布时,通常是_____</p>
|
||
<p>A.存满一面,再存另一面</p>
|
||
<p>B.尽量将同一文件存放在一个扇区或相邻扇区的各磁道上</p>
|
||
<p>C.尽量将同一文件存放在不同面的同一磁道上</p>
|
||
<p>D.上述方法均有效</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-22 18:31:26</p>
|
||
<p>-----每日一题 Day 91------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在客户/服务器模式的网络环境下,如何提高整个网络的性能?_____</p>
|
||
<p>A.根据网络流量的大小改变传输的数据包的大小</p>
|
||
<p>B.只传送“请求”和“结果”来减少网络的流量</p>
|
||
<p>C.通过客户端本地存储所有的数据来降低网络流量</p>
|
||
<p>D.在服务器上执行所有的数据处理</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-22 18:30:43</p>
|
||
<p>-----每日一题 Day 91------</p>
|
||
<p>数据结构</p>
|
||
<p>1 一个有序表中有5个数据记录,其查找概率分别为p1=0.2,p2=0.15,p3=0.4,p4=0.15和p5=0.1,顺序查找时的查找成功的平均查找长度为_____。</p>
|
||
<p>A. 1</p>
|
||
<p>B. 2.5</p>
|
||
<p>C. 2.8</p>
|
||
<p>D. 3</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-23 17:55:24</p>
|
||
<p>-----每日一题 Day 92------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 DMA方式是在_______之间建立一条直接数据通路。</p>
|
||
<p>A. I/O设备和主存</p>
|
||
<p>B.两个I/O设备</p>
|
||
<p>C. I/O设备和CPU</p>
|
||
<p>D. CPU和主存</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-23 17:54:35</p>
|
||
<p>-----每日一题 Day 92------</p>
|
||
<p>操作系统</p>
|
||
<p>3 某磁盘的转速为7200r/min,传输速度为4MB/s,控制器开销为1ms。要保证读或写一个512B的扇区的平均时间为11.3ms。那么,该磁盘的平均寻道时间不超过_____</p>
|
||
<p>A. 3.9ms</p>
|
||
<p>B. 4.7ms</p>
|
||
<p>C. 5.5ms</p>
|
||
<p>D. 6.1ms</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-23 17:54:00</p>
|
||
<p>-----每日一题 Day 92------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 一台主机希望解析域名www.nankai. edu.cn,如果这台服务器配置的域名服务器为202.120.66.68, Internet根域名服务器为10.2.8.6,而存储www.nankai.edu. cn与其IP地址对应关系的域名服务器为202.113.16.10,那么这台主机解析该域名通常首先查询______</p>
|
||
<p>A.地址为202.120.66.68的域名服务器</p>
|
||
<p>B.地址为10.2.8.6的域名服务器</p>
|
||
<p>C.地址为202.113.16.10的域名服务器</p>
|
||
<p>D.不能确定,可以从这3个域名服务器中任选一个</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-23 17:53:19</p>
|
||
<p>-----每日一题 Day 92------</p>
|
||
<p>注意:第二天发布题目同一时间评论区公布答案哦!</p>
|
||
<p>数据结构</p>
|
||
<p>1 适用于折半查找的表的存储方式的要求为______</p>
|
||
<p>A.顺序存储,记录可以无序</p>
|
||
<p>B.顺序存储,记录必须有序</p>
|
||
<p>C.链式存储,记录可以无序</p>
|
||
<p>D.链式存储,记录必须有序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-24 17:03:21</p>
|
||
<p>-----每日一题 Day 93------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 DMA方式中,周期“窃取”是窃取一个_____</p>
|
||
<p>A.存取周期</p>
|
||
<p>B.指令周期</p>
|
||
<p>C. CPU周期</p>
|
||
<p>D.时钟周期</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-24 17:02:15</p>
|
||
<p>-----每日一题 Day 93------</p>
|
||
<p>操作系统</p>
|
||
<p>3 在采用 SPOOLing 技术的系统中,用户的打印数据首先被送到______ 。</p>
|
||
<p>A 内存固定区域</p>
|
||
<p>B 磁盘固定区域</p>
|
||
<p>C 终端</p>
|
||
<p>D 打印机</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-24 17:01:38</p>
|
||
<p>-----每日一题 Day 93------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在数据传输速率为50kb/s的卫星信道上发送长度为1kb的帧。假设确认总是由数据帧捎带。帧头很短,帧序号的长度为3比特。对于停止等待协议,可以取得的最大信道利用率是_____ (假设卫星信道端到端的单向传播延迟时间为270ms)</p>
|
||
<p>A 3.4%</p>
|
||
<p>B 6.8%</p>
|
||
<p>C 13.8%</p>
|
||
<p>D 24.1%</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-24 17:00:49</p>
|
||
<p>-----每日一题 Day 93------</p>
|
||
<p>数据结构</p>
|
||
<p>1 对于具有152个记录的文件,采用分块查找法,且每块长度为8。若索引表和各块内均用顺序查找,则平均查找长度为_______</p>
|
||
<p>A. 4.5</p>
|
||
<p>B. 9</p>
|
||
<p>C. 14.5</p>
|
||
<p>D. 24</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-25 18:39:44</p>
|
||
<p>-----每日一题 Day 94------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 在采用DMA方式高速传输数据时,数据传送是______</p>
|
||
<p>A.在总线控制器发出的控制信号控制下完成的</p>
|
||
<p>B.在DMA控制器本身发出的控制信号控制下完成的</p>
|
||
<p>C.由CPU执行的程序完成的</p>
|
||
<p>D.由CPU响应硬中断处理完成的</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-25 18:38:57</p>
|
||
<p>-----每日一题 Day 94------</p>
|
||
<p>操作系统</p>
|
||
<p>3 以下关于计算机外部设备说法中错误的是______ 。</p>
|
||
<p>A 计算机外部设备可以分为存储型设备和输入输出型设备</p>
|
||
<p>B 存储型设备可以作为内存的扩充,信息传输以块为单位</p>
|
||
<p>C 输入输出型设备负责内存与外部设备间的信息传递,信息传输单位是字符</p>
|
||
<p>D 存储型设备一般属于共享设备,而输入输出型设备则属于独占设备</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-25 18:38:13</p>
|
||
<p>-----每日一题 Day 94------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在理想状态的信道中,数据从发送端到接收端是无差错的,但实际应用中,数据传输会产生差错。下列______不是由于物理传输介质影响差错的因素</p>
|
||
<p>A.信号在物理线路上随机产生的信号幅度、频率、相位的畸形和衰减</p>
|
||
<p>B.电气信号在线路上产生反射造成的回波效应</p>
|
||
<p>C.数据的压缩率太高,造成在传输中出现的错误无法克服</p>
|
||
<p>D.相邻线路之间的串线干扰,以及闪电、电磁的干扰等</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-25 18:33:19</p>
|
||
<p>-----每日一题 Day 94------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下面说法错误的是______</p>
|
||
<p>A.在索引顺序表中实现分块查找,在等概率查找情况下,其平均查找长度不仅与表中元素个数有关,而且与每块中元素个数有关</p>
|
||
<p>B.对大小均为n的有序表和无序表分别进行顺序查找,在等概率查找的情况下,对于查找成功,它们的平均查找长度是相同的;而对于查找失败,它们的平均查找长度是不同的</p>
|
||
<p>C.当采用分块查找时,记录的组织方式为每块内关键字不必有序,但块间必须有序</p>
|
||
<p>D.就平均查找长度而言,分块查找最小,折半查找次之,顺序查找最大</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-28 18:05:40</p>
|
||
<p>-----每日一题 Day 95------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 已知大写英文字母A的ASCII码为41H,现字母F被存放在某个存储单元中,若采用偶校验(假设最高位作为校验位),则该存储单元中存放的十六进制数据是_____</p>
|
||
<p>A. 46H</p>
|
||
<p>B. C6H</p>
|
||
<p>C. 47H</p>
|
||
<p>D. C7H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-28 18:05:07</p>
|
||
<p>-----每日一题 Day 95------</p>
|
||
<p>操作系统</p>
|
||
<p>3 设有一个记录式文件采用链接分配方式,逻辑记录的固定长度 100 字节,在磁盘上存</p>
|
||
<p>储时采用记录成组分解技术,物理块(盘块)长度为 512 字节。如果该文件的目录项已经读</p>
|
||
<p>入内存,要修改第 22 个逻辑记录共需启动磁盘 ______次。</p>
|
||
<p>A 1</p>
|
||
<p>B 2</p>
|
||
<p>C 5</p>
|
||
<p>D 6</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-28 18:04:31</p>
|
||
<p>-----每日一题 Day 95------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在CSMA/CD中,如果网络中某个发送站点一旦检测到冲突,就立即停止发送,并发冲突码,其他站点都会______</p>
|
||
<p>A.处于待发送状态</p>
|
||
<p>B 相继竞争发送权</p>
|
||
<p>C 接收到阻塞信号</p>
|
||
<p>D.有可能继续发送数据</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-28 18:03:51</p>
|
||
<p>-----每日一题 Day 95------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在平衡二叉树中插入一个结点后造成了不平衡,设最低的不平衡结点为A,并已知A的左孩子的平衡因子为一1,右孩子的平衡因子为0,则应作____型调整以使其平衡。</p>
|
||
<p>A. LL</p>
|
||
<p>B. LR</p>
|
||
<p>C. RL</p>
|
||
<p>D RR</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-29 16:56:18</p>
|
||
<p>-----每日一题 Day 96------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某机器字长16位,主存按字节编址,转移指令采用相对寻址,由两个字节组成,第一字节为操作码字段,第二字节为相对位移量字段。假定取指令时,每取一个字节PC自动加1。若某转移指令所在主存地址为2000H,相对位移量字段的内容为06H,则该转移指令成功转移后的目标地址是______</p>
|
||
<p>A. 2006H</p>
|
||
<p>B. 2007H</p>
|
||
<p>C. 2008H</p>
|
||
<p>D. 2009H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-29 16:55:46</p>
|
||
<p>-----每日一题 Day 96------</p>
|
||
<p>操作系统</p>
|
||
<p>3 位示图可用于磁盘空间的管理。设某系统磁盘共有 500 块,块号为 0~499 ,第 0 行的</p>
|
||
<p>第 0 位表示第 0 块,第 0 行的第 1 位表示第 1 块,以此类推。若用位示图管理这 500 块的磁</p>
|
||
<p>盘空间,当字长为 32 位时,第 i 个字节第 j 位对应的块号是______</p>
|
||
<p>A 32 × i+j</p>
|
||
<p>B 32 × i+j-1</p>
|
||
<p>C 32 × i+j-32</p>
|
||
<p>D 32 × i+j -32 -1</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-29 16:55:07</p>
|
||
<p>-----每日一题 Day 96------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在CSMA/CD中,假设站点发送数据帧所需的时间为1,任意两个站点之间的传播延迟时间为r,若能正常检测到冲突,对于基带总线网络,r的值应为______</p>
|
||
<p>A r&lt;=0.5</p>
|
||
<p>B r&lt;0.5</p>
|
||
<p>C r&gt;=1</p>
|
||
<p>D 0.5&lt;r&lt;1</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-29 16:54:29</p>
|
||
<p>-----每日一题 Day 96------</p>
|
||
<p>数据结构</p>
|
||
<p>1 高度为8的平衡二叉树的结点数至少为______</p>
|
||
<p>A. 15</p>
|
||
<p>B. 54</p>
|
||
<p>C. 87</p>
|
||
<p>D. 255</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-30 18:46:18</p>
|
||
<p>-----每日一题 Day 97------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 指令操作所需的数据不会来自______</p>
|
||
<p>A.寄存器</p>
|
||
<p>B.指令本身</p>
|
||
<p>C.主存</p>
|
||
<p>D.控制存储器</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-30 18:45:46</p>
|
||
<p>-----每日一题 Day 97------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 采用多道程序设计的系统中,系统中的程序道数越多则系统的效率越高。</p>
|
||
<p>B 多道程序设计可以缩短系统中程序的执行时间。</p>
|
||
<p>C 通常将 CPU 模式分为内核态(核心态)和用户态,这样做的目的是为了提高运行速度。</p>
|
||
<p>D 微内核结构操作系统具有较高的灵活性和扩展性。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-30 18:45:03</p>
|
||
<p>-----每日一题 Day 97------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 已知以太网局域网的总线电缆长为200m,数据传输速率为10Mb/s,电磁波信号在电缆中的传播速率为200m/μs。则该局域网允许的帧的最小长度为______。</p>
|
||
<p>A 10b</p>
|
||
<p>B 20b</p>
|
||
<p>C 30b</p>
|
||
<p>D 40b</p>
|
||
<hr>
|
||
<p>该题更新于:2022-11-30 18:44:26</p>
|
||
<p>-----每日一题 Day 97------</p>
|
||
<p>注意:第二天发布题目同一时间评论区公布答案哦!</p>
|
||
<p>数据结构</p>
|
||
<p>1设有哈希表中的关键字为(15,39,23,80, 44, 84, 27,55, 11, 10,69),用链地址法解决冲突,哈希函数为H(key)=key MOD 11,哈希地址为3的链中记录个数为_______</p>
|
||
<p>A. 1</p>
|
||
<p>B. 2</p>
|
||
<p>C. 3</p>
|
||
<p>D 4</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-01 17:27:45</p>
|
||
<p>-----每日一题 Day 98------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设相对寻址的转移指令占两个字节,第一个字节是操作码,第二个字节是相对位移量(用补码表示)。每当CPU从存储器取出第一个字节时,即自动完成(PC)+1→PC。设当前PC的内容为2003H,要求转移到200AH地址,则该转移指令第二字节的内容应为______</p>
|
||
<p>A 04H</p>
|
||
<p>B 05H</p>
|
||
<p>C 06H</p>
|
||
<p>D 07H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-01 17:23:47</p>
|
||
<p>-----每日一题 Day 98------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是______</p>
|
||
<p>A 分时操作系统允许两个以上的用户共享一个计算机系统。</p>
|
||
<p>B 操作系统的存储管理就是指对磁盘存储器的管理。</p>
|
||
<p>C 实时操作系统只能用于控制系统而不能用于信息管理系统。</p>
|
||
<p>D 从响应的角度看,分时系统与实时系统的要求相似。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-01 17:23:07</p>
|
||
<p>-----每日一题 Day 98------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 一个48端口的交换机的冲突域和广播域个数分别是______</p>
|
||
<p>A. 1,1</p>
|
||
<p>B. 48,48</p>
|
||
<p>C. 48.1</p>
|
||
<p>D. 1,48</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-01 17:22:12</p>
|
||
<p>-----每日一题 Day 98------</p>
|
||
<p>数据结构</p>
|
||
<p>1 哈希函数为H(key)=key MOD 11,表中已存入关键字分别为7、14,37、60和83的五个记录,此时哈希表的装填因子a=0.33。用二次探测再散列法解决冲突,则再放入关键字为49的记录时,它的位置下标是_______</p>
|
||
<p>A. 5</p>
|
||
<p>B. 8</p>
|
||
<p>C.9</p>
|
||
<p>D. 14</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-02 17:58:46</p>
|
||
<p>-----每日一题 Day 99------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 堆栈寻址方式中,设A为累加器,SP为堆栈指示器,Msp为SP指示的栈顶单元,如果进栈操作的动作顺序是(A)→Msp, (SP)-1→SP,那么出栈操作的动作顺序应为_____</p>
|
||
<p>A. (Msp)→A,(SP)+1→SP</p>
|
||
<p>B. (SP)-1→SP, (Msp)→A</p>
|
||
<p>C. (SP)+1→SP, (Msp)→A</p>
|
||
<p>D.以上都不对</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-02 17:58:11</p>
|
||
<p>-----每日一题 Day 99------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法错误的是_____</p>
|
||
<p>A 系统调用与程序级的子程序调用是一致的。</p>
|
||
<p>B 访管指令为非特权指令,在用户态下执行时会将 CPU 转换为核心态。</p>
|
||
<p>C 执行系统调用时会产生中断。</p>
|
||
<p>D 系统调用返回时,由核心态变为用户态执行用户程序。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-02 17:57:33</p>
|
||
<p>-----每日一题 Day 99------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 一个以太网局域网中有A、B、C、D 4台主机,A给B发信息_____</p>
|
||
<p>A.只有B收到信息</p>
|
||
<p>B 4台主机都收到信息</p>
|
||
<p>C.4台主机都收不到信息</p>
|
||
<p>D. B C D 3台主机收到信息</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-02 17:56:37</p>
|
||
<p>-----每日一题 Day 99------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列关于哈希表的说法错误的是______</p>
|
||
<p>A.除留余数法是所有哈希函数中最好的。</p>
|
||
<p>B.采用链地址法解决冲突时,不存在聚集现象。</p>
|
||
<p>C.在哈希表查找中,比较操作一般也是不可避免的。</p>
|
||
<p>D.若散列表的装填因子a&lt;1,仍可能产生冲突。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-05 19:42:13</p>
|
||
<p>-----每日一题 Day 100------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 一台8位微机的地址总线为16条,其RAM存储器容量为32KB,首地址为4000H,且地址是连续的。问可用的最高地址是______</p>
|
||
<p>A 7FFFH</p>
|
||
<p>B AFFFH</p>
|
||
<p>C BFFFH</p>
|
||
<p>D CFFFH</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-05 19:41:29</p>
|
||
<p>-----每日一题 Day 100------</p>
|
||
<p>操作系统</p>
|
||
<p>3 操作系统中的三级调度是指 ______</p>
|
||
<p>A CPU 调度、资源调度和网络调度</p>
|
||
<p>B CPU 调度、设备调度和存储器调度</p>
|
||
<p>C 作业调度、进程调度和资源调度</p>
|
||
<p>D 作业调度、进程调度和中级调度</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-05 19:40:47</p>
|
||
<p>-----每日一题 Day 100------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 有一个连接10台计算机的网络,其中5台连接到一个以太网集线器上,另外5台连接到另一个以太网集线器上,两个集线器连接到一个交换机上,而该交换机又通过一个路由器连接到另一个配置相同的远程办公室。那么,该交换机将能获知_______个MAC地址</p>
|
||
<p>A 10</p>
|
||
<p>B 11</p>
|
||
<p>C 12</p>
|
||
<p>D 14</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-05 19:39:54</p>
|
||
<p>-----每日一题 Day 100------</p>
|
||
<p>数据结构</p>
|
||
<p>1 对序列(67, 56,34,45,78,12,23)进行递增的希尔排序,经一趟后序列变为(67,12, 23, 45,78,56, 34),则该趟采用的增量是______。</p>
|
||
<p>A. 1</p>
|
||
<p>B. 2</p>
|
||
<p>C. 3</p>
|
||
<p>D. 4</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-06 17:40:16</p>
|
||
<p>-----每日一题 Day 101------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 有一个16KX16的存储器,由1KX4的DRAM芯片(内部结构为64×64)构成,如采用集中刷新方式,设存储器的读写周期为0.5us,死时间率为______</p>
|
||
<p>A 0.6%</p>
|
||
<p>B 1%</p>
|
||
<p>C 1.6%</p>
|
||
<p>D 2%</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-06 17:39:36</p>
|
||
<p>-----每日一题 Day 101------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 进程状态的转换是由操作系统完成的,对用户是透明的。</p>
|
||
<p>B 不同的进程必然对应不同的程序。</p>
|
||
<p>C 进程控制块( PCB )是用户进程的私有数据结构,每个进程仅有一个 PCB 。</p>
|
||
<p>D 当一个进程从阻塞态变为就绪态时,一定有一个进程从就绪态变为运行态。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-06 17:35:13</p>
|
||
<p>-----每日一题 Day 101------</p>
|
||
<p>数据结构</p>
|
||
<p>1 若用冒泡排序方法对序列(12,24,36,48,60,72)从大到小排序,需要的比较次数是_____</p>
|
||
<p>A. 5</p>
|
||
<p>B. 10</p>
|
||
<p>C. 15</p>
|
||
<p>D. 25</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-07 17:10:44</p>
|
||
<p>-----每日一题 Day 102------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设计算机的存储器为64Kx16位,直接地址映像的cache容量为1KW(KW,千字),每块4字。则cache中可装入____块数据</p>
|
||
<p>A 1024</p>
|
||
<p>B 128</p>
|
||
<p>C 256</p>
|
||
<p>D 512</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-07 17:10:04</p>
|
||
<p>-----每日一题 Day 102------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 进程从运行态变为阻塞态是由于时间片中断发生。</p>
|
||
<p>B 进程可以自身决定从运行态转换为阻塞态。</p>
|
||
<p>C 在抢占式进程调度下,现运行进程的优先级不低于系统中所有进程的优先级。</p>
|
||
<p>D 在任何情况下采用短作业优先调度算法都能够使作业的平均周转时间最小。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-07 17:09:19</p>
|
||
<p>-----每日一题 Day 102------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 IP协议可能将原主机的IP数据报分片后再进行传输,在到达目的主机之前,分片后的IP数据报_____</p>
|
||
<p>A. 可能再次分片,但不进行重组</p>
|
||
<p>B.不可能再次分片和重组</p>
|
||
<p>C 不可能再次分片,但能进行重组</p>
|
||
<p>D.可能再次分片和重组</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-07 17:08:25</p>
|
||
<p>-----每日一题 Day 102------</p>
|
||
<p>数据结构</p>
|
||
<p>1 序列(16,10,8,9,20,-1,5)进行一趟排序后变为(5,10,-1,9,20,8,16),则采用的排序方法是_____。</p>
|
||
<p>A.选择排序</p>
|
||
<p>B.快速排序</p>
|
||
<p>C.冒泡排序</p>
|
||
<p>D.希尔排序</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-08 15:13:07</p>
|
||
<p>-----每日一题 Day 103------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某计算机的主存地址位数为32位,按字节编址。假定数据cache中最多存放128个主存块,采用4路组相联方式,块大小为64B,每块设置了1位有效位。采用一次性写回策略,为此每块设置了1位"脏”位。该数据cache的总位数为_____</p>
|
||
<p>A 65536</p>
|
||
<p>B 68480</p>
|
||
<p>C 68224</p>
|
||
<p>D 68352</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-08 15:12:28</p>
|
||
<p>-----每日一题 Day 103------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 在分时系统 中,进程调度都采用优先级调度算法为主,短进程优先调度算法为辅。</p>
|
||
<p>B 在单 CPU 上的进程就绪队列和阻塞队列都只能有一个。</p>
|
||
<p>C 某进程被唤醒后立即投入运行,因此系统采用的一定是抢占式进程调度。</p>
|
||
<p>D 时间片的大小对轮转法的性能有很大影响,时间片太短会导致系统开销增加。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-08 15:11:45</p>
|
||
<p>-----每日一题 Day 103------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在Internet中,IP数据报的传输需要经由源主机和中间路由器到达目的主机,通常_____</p>
|
||
<p>A. 源主机和中间路由器都知道IP数据报到达目的主机需要经过的完整路径</p>
|
||
<p>B. 源主机知道IP数据报到达目的主机需要经过的完整路径,而中间路由器不知道</p>
|
||
<p>C. 源主机不知道IP数据报到达目的主机需要经过的完整路径,而中间路由器知道</p>
|
||
<p>D.源主机和中途路由器都不知道IP数据报到达目的主机需要经过的完整路径</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-08 15:10:37</p>
|
||
<p>-----每日一题 Day 103------</p>
|
||
<p>数据结构</p>
|
||
<p>1 以下关于外部排序的说法错误的是____。</p>
|
||
<p>A.影响外部排序的时间因素主要是内存与外存交换信息的总次数</p>
|
||
<p>B.外部排序的两个基本操作过程是生成初始归并段和归并</p>
|
||
<p>C.采用败者树进行k路平衡归并,其总的归并效率与k无关</p>
|
||
<p>D.外部排序通过减少初始归并段个数和增加归并路数可以提高排序效率</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-09 17:35:57</p>
|
||
<p>-----每日一题 Day 104------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 某个系统拥有48位的虚拟地址和36位的物理地址,并且主存储器的容量为128MB。如果系统中使用的页的大小为4096字节,该地址空间能够支持的虚页数和实页数分别是______</p>
|
||
<p>A 2^36个,2^24个</p>
|
||
<p>B 2^48个,2^36个</p>
|
||
<p>C 2^48个,2^12个</p>
|
||
<p>D 2^36个,2^12个</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-09 17:35:24</p>
|
||
<p>-----每日一题 Day 104------</p>
|
||
<p>操作系统</p>
|
||
<p>3 一个正在访问临界资源的进程由于 又申请 I/O 操作而被阻塞时, ________。</p>
|
||
<p>A 可以允许其他进程进入该进程的临界区</p>
|
||
<p>B 不允许其他进程进入临界区和占用 CPU 执行</p>
|
||
<p>C 可以允许其他就绪进程占用 CPU 执行</p>
|
||
<p>D 不允许其他进程占用 CPU 执行</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-09 17:34:44</p>
|
||
<p>-----每日一题 Day 104------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 子网掩码是255.255.192.0,那么下列的_____主机必须通过路由器才能与主机129.23.144.16通信</p>
|
||
<p>A.129.23.191.21</p>
|
||
<p>B.129.23.127.222</p>
|
||
<p>C.129. 23.130.33</p>
|
||
<p>D. 129,23.148.122</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-09 17:31:16</p>
|
||
<p>-----每日一题 Day 104------</p>
|
||
<p>数据结构</p>
|
||
<p>1 设有如下遗产继承规则:丈夫和妻子可以互相继承遗产,子女可以继承父亲和母亲的遗产,子女间不能相互继承,则表示该遗产继承关系最合适的数据结构应该是_______。</p>
|
||
<p>A.树</p>
|
||
<p>B.图</p>
|
||
<p>C.线性表</p>
|
||
<p>D.集合</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-12 16:53:50</p>
|
||
<p>-----每日一题 Day 105------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法正确的是______</p>
|
||
<p>A 存取周期是指启动一次存储器操作到完成该操作所需的时间</p>
|
||
<p>B 随机存储器需要定时地进行刷新。</p>
|
||
<p>C 集中刷新方式在刷新时间内并不影响CPU的读写操作.</p>
|
||
<p>D CPU访问主存储器的时间与存储体的容量无关。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-12 16:53:11</p>
|
||
<p>-----每日一题 Day 105------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 在信号量上除了能执行 P 、 V 操作外,不能执行其他任何操作。</p>
|
||
<p>B 若信号量的初值为 1 ,则用 P 、 V 操作可以禁止任何进程进入临界区。</p>
|
||
<p>C P、 V 操作只能实现进程互斥,不能 实现进程同步。</p>
|
||
<p>D 进程 A 与进程 B 共享变量 S1 ,需要互斥;进程 B 与进程 C 共享变量 S2 ,需要互斥</p>
|
||
<p>从而进程 A 与进程 C 也必须互斥。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-12 16:52:31</p>
|
||
<p>-----每日一题 Day 105------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 假定TCP拥塞窗口值被设定为18KB,然后发生了超时事件。如果紧接着的4次突发传输都是成功的,那么拥塞窗口将为_______.(假设最大报文段长度MSS为1KB)。</p>
|
||
<p>A 4KB</p>
|
||
<p>B 8KB</p>
|
||
<p>C 9KB</p>
|
||
<p>D 10KB</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-12 16:51:46</p>
|
||
<p>-----每日一题 Day 105------</p>
|
||
<p>数据结构</p>
|
||
<p>1 若有m个关键字互为同义词,若用线性探测法处理冲突,把这m个元素存人哈希表中,至少要进行______次探测。</p>
|
||
<p>A. m-1</p>
|
||
<p>B. m</p>
|
||
<p>C. m+1</p>
|
||
<p>D. m(m+1)/2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-13 17:39:03</p>
|
||
<p>-----每日一题 Day 106------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列关于RISC的叙述中,错误的是_____</p>
|
||
<p>A. RISC普遍采用微程序控制器</p>
|
||
<p>B. RISC大多数指令在一个时钟周期内完成</p>
|
||
<p>C. RISC的内部通用寄存器数量相对CISC多</p>
|
||
<p>D. RISC的指令数、寻址方式和指令格式种类相对CISC少</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-13 17:37:45</p>
|
||
<p>-----每日一题 Day 106------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 当进程数 大于资源数时,进程竞争资源必然产生死锁。</p>
|
||
<p>B 一旦出现死锁,所有进程都不能运行。</p>
|
||
<p>C 有 m 个进程的操作系统出现死锁时,死锁进程的个数为 1 &lt;k≤m 。</p>
|
||
<p>D 银行家算法是防止死锁发生的方法之一。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-13 17:36:40</p>
|
||
<p>-----每日一题 Day 106------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 TCP为了提高效率又引入了滑动窗口协议,协议规定重传______的报文段</p>
|
||
<p>A. 未被确认及至窗口首端的所有报文段</p>
|
||
<p>B.未被确认</p>
|
||
<p>C 未被确认及至退回N值的所有报文段</p>
|
||
<p>D.仅丢失</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-13 17:35:41</p>
|
||
<p>-----每日一题 Day 106------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是_____</p>
|
||
<p>A 进行折半查找的表必须是顺序存储的有序表。</p>
|
||
<p>B 折半查找所对应的判定树是一棵平衡二叉树</p>
|
||
<p>C 对二叉排序树进行先序遍历得到的结点的值的序列是一个有序序列。</p>
|
||
<p>D 在由n个元素组成的有序表上进行折半查找时,对任一个元素进行查找的长度都不会大于log2(n)+1</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-14 18:10:29</p>
|
||
<p>-----每日一题 Day 107------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 微程序控制器的速度比硬布线控制器慢,主要是因为______</p>
|
||
<p>A.增加了从磁盘存储器读取微指令的时间</p>
|
||
<p>B.增加了从主存储器读取微指令的时间</p>
|
||
<p>C.增加了从指令寄存器读取微指令的时间</p>
|
||
<p>D.增加了从控制存储器读取微指令的时间</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-14 18:07:48</p>
|
||
<p>-----每日一题 Day 107------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 TCP协议采用超时重传、捎带确认技术,其中捎带确认技术指的是在确认信息中捎带_____</p>
|
||
<p>的序号以减少通信量。</p>
|
||
<p>A.上一个已接收的报文段</p>
|
||
<p>B.下一个希望接收的报文段</p>
|
||
<p>C.正在发送的报文段</p>
|
||
<p>D.下一个将要发送的报文段</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-14 18:07:10</p>
|
||
<p>-----每日一题 Day 107------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是_____</p>
|
||
<p>A 对于同一组记录,若生成二叉排序树时插入记录的次序不同,则可得到不同结构的二叉排序树。</p>
|
||
<p>B 在分块查找中,在等概率情况下,其平均查找长度不仅与查找表的长度有关,而且与每块中的记录个数有关。</p>
|
||
<p>C 哈希函数越复杂,随机性越好,冲突的概率越小</p>
|
||
<p>D 在二叉排序树中插入的结点,总是叶子结点</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-15 17:55:33</p>
|
||
<p>-----每日一题 Day 108------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法正确的是_____</p>
|
||
<p>A 在冯·诺依曼计算机中,指令流是由数据流驱动的。</p>
|
||
<p>B 执行指令时,指令在主存中的地址存放在指令寄存器中。</p>
|
||
<p>C 指令周期是指CPU从主存中读出一条指令的时间。</p>
|
||
<p>D 取指周期的操作与指令的操作码无关。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-15 17:54:57</p>
|
||
<p>-----每日一题 Day 108------</p>
|
||
<p>操作系统</p>
|
||
<p>3 段页式存储管理汲取了分页和分段的优点,其实现原理结合了分页和分段管理的基本</p>
|
||
<p>思想,即 _______</p>
|
||
<p>A用分段方法来分配和管理内存物理空间,用分页方法来管理用户地址空间</p>
|
||
<p>B用分段方法来分配和管理用户地址空间,用分页方法来管理内存物理空间</p>
|
||
<p>C用分段方法来分配和管理内存空间,用分页方法来管理辅存空间</p>
|
||
<p>D用分段方法来分配和管理辅存空间,用分页方法来管理内存 空间</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-15 17:54:13</p>
|
||
<p>-----每日一题 Day 108------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 下列协议中属于面向连接的是_____</p>
|
||
<p>A. IP</p>
|
||
<p>B. UDP</p>
|
||
<p>C. DHCP</p>
|
||
<p>D. TCP</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-15 17:53:36</p>
|
||
<p>-----每日一题 Day 108------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在有向图G的拓扑序列中,若顶点Vi在顶点Vj之前,则下列情形不可能出现的是______</p>
|
||
<p>A.G中有弧&lt;Vi,Vj&gt;</p>
|
||
<p>B.G中有一条从Vi到Vj的路径</p>
|
||
<p>C.G中没有弧&lt;Vi,Vj&gt;</p>
|
||
<p>D.G中有一条从Vj到Vi的路径</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-16 17:44:25</p>
|
||
<p>-----每日一题 Day 109------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 下列说法正确的是______</p>
|
||
<p>A 指令周期又称为CPU周期</p>
|
||
<p>B 微指令是指控制存储器中的一个单元的内容。</p>
|
||
<p>C 在微程序控制器中,微指令寄存器用来存放微程序。</p>
|
||
<p>D 微指令的操作控制字段采用字段编码时,兼容的微命令应安排在同一段中。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-16 17:43:42</p>
|
||
<p>-----每日一题 Day 109------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是____</p>
|
||
<p>A 在分页存储管理中,程序装入内存后其地址是连续的。</p>
|
||
<p>B 分页存储管理中一个程序可以占用不连续的内存空间,而分段存储管理中一个程序则</p>
|
||
<p>需要占用连续的内存空间。</p>
|
||
<p>C 分段存储管理中的分段是由用户决定的。</p>
|
||
<p>D 请求分页存储管理系统若把页的大小增加一倍,则缺页中断次数就会减少一半。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-16 17:43:03</p>
|
||
<p>-----每日一题 Day 109------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 TCP/IP的传输层协议使用______地址形式将数据传送给上层应用程序</p>
|
||
<p>A. IP地址</p>
|
||
<p>B. MAC地址</p>
|
||
<p>C.端口号</p>
|
||
<p>D.套接字(socket)地址</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-16 17:40:49</p>
|
||
<p>-----每日一题 Day 109------</p>
|
||
<p>数据结构</p>
|
||
<p>1 下列说法错误的是_____</p>
|
||
<p>A 对任意一个图,从它的某个顶点出发,进行一次深度优先或广度优先搜索,即可访问图的每个顶点。</p>
|
||
<p>B 连通图上各边权值均不相同,则该图的最小生成树是惟一的</p>
|
||
<p>C 有n个顶点的无向图,采用邻接矩阵表示,图中的边数等于邻接矩阵中非零元素之和的一半</p>
|
||
<p>D 树的先根遍历算法可以理解为深度优先遍历算法的一种特殊形式.</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-20 18:20:23</p>
|
||
<p>-----每日一题 Day 111------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设相对寻址的转移指令占4字节,其中第1、第2字节是操作码,第3、第4字节是相对位移量(用补码表示)。设当前PC的内容为2008H,要求转移到2001H的地址,则该转移指令第3、第4字节的内容应为______</p>
|
||
<p>A FFF5H</p>
|
||
<p>B FFF9H</p>
|
||
<p>C 000BH</p>
|
||
<p>D 0007H</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-20 18:19:48</p>
|
||
<p>-----每日一题 Day 111------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_______</p>
|
||
<p>A 磁盘高速缓冲区是设 在磁盘上的一块磁盘空间。</p>
|
||
<p>B 磁盘移臂调度的目标是使磁盘旋转的周数最小。</p>
|
||
<p>C 最短寻道时间优先( SSTF )算法的调度原则是要求磁头的移动距离最小,该算法有产生饥饿 的可能。</p>
|
||
<p>D 磁盘扇区的编号必须连续。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-20 18:19:07</p>
|
||
<p>-----每日一题 Day 111------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在OSI参考模型中,当相邻高层的实体把______传到低层实体后,被低层实体视为_____</p>
|
||
<p>A. IDU, PDU</p>
|
||
<p>B. PDU, IDU</p>
|
||
<p>C. IDU, SDU</p>
|
||
<p>D. PDU,SDU</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-20 18:18:21</p>
|
||
<p>-----每日一题 Day 111------</p>
|
||
<p>数据结构</p>
|
||
<p>1 从一个栈顶指针为top的链栈中删除一个结点时,用x保存被删除的结点,应执行______</p>
|
||
<p>A.x=top-&gt;data; top=top-&gt;next;</p>
|
||
<p>B. top = top - &gt;next; x=top;</p>
|
||
<p>C. x=top-&gt;data;</p>
|
||
<p>D. x=top; top=top-&gt;next;</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-21 18:52:46</p>
|
||
<p>-----每日一题 Day 112------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 X、Y为定点二进制数,其格式为1位符号位,n位数值位。若采用Booth补码一位乘法实现乘法运算,则最多需要做加法运算的次数是______</p>
|
||
<p>A. n-1</p>
|
||
<p>B. n</p>
|
||
<p>C. n+1</p>
|
||
<p>D. n+2</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-21 18:52:11</p>
|
||
<p>-----每日一题 Day 112------</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是______</p>
|
||
<p>A 设备独立性是指设备驱动程序独立于具体使用的物理设备。</p>
|
||
<p>B 系统为所有设备配置了一张设备控制表,用于记录设备的特性以及 I/O 控制器连接的情</p>
|
||
<p>况。</p>
|
||
<p>C 引入缓冲的主要目的是为了提高 I/O 设备的利用率。</p>
|
||
<p>D 等待设备的进程队列有时不必以先来先服务的顺序排队。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-21 18:51:30</p>
|
||
<p>-----每日一题 Day 112------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 在下面对OSI参考模型的数据链路层的功能特性描述中,不正确的是_____</p>
|
||
<p>A.通过交换与路由,找到数据通过网络的最有效的路径</p>
|
||
<p>B.数据链路层的主要任务是提供一种可靠的通过物理介质传输数据的方法</p>
|
||
<p>C.将数据分解成帧,并按顺序传输帧,并处理接收端发回的确认帧</p>
|
||
<p>D.以太网的数据链路层分为LLC和MAC子层,并在MAC子层使用CSMA/CD协议争用信道</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-21 18:50:43</p>
|
||
<p>-----每日一题 Day 112------</p>
|
||
<p>数据结构</p>
|
||
<p>1 在解决计算机主机与打印机之间速度不匹配问题时通常设置一个打印数据缓冲区,主机将要输出的数据依次写入该缓冲区,而打印机则从该缓冲区中取出数据打印。该缓冲区应该是一个______结构。</p>
|
||
<p>A.堆栈</p>
|
||
<p>B.队列</p>
|
||
<p>C.数组</p>
|
||
<p>D.线性表</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-22 20:03:08</p>
|
||
<p>-----每日一题 Day 113------</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 存储器容量为32K X 16,则_______</p>
|
||
<p>A.地址线为16根,数据线为32根</p>
|
||
<p>B.地址线为32根,数据线为16根</p>
|
||
<p>C.地址线为15根,数据线为16根</p>
|
||
<p>D.地址线为16根,数据线为15根</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-22 20:02:32</p>
|
||
<p>-----每日一题 Day 113------</p>
|
||
<p>操作系统</p>
|
||
<p>3 文件系统采用两级索引分配方式,如果每个物理块的大小为 1KB ,每个物理块号占 4个字节(4B ),则该系统中单个文件允许的最大长度是 _____。</p>
|
||
<p>A 64MB</p>
|
||
<p>B 128MB</p>
|
||
<p>C 32MB</p>
|
||
<p>D 256MB</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-22 20:01:54</p>
|
||
<p>-----每日一题 Day 113------</p>
|
||
<p>计算机网络</p>
|
||
<p>2 设待传送数据总长度为L比特,分组总长度为P比特,其中头部开销长度为H比特,源结点到目的结点之间的线路数为h,每条线路上的延迟时间为D秒,数据传输率为Bb/s,在分组交换方式中每个分组在每个中间结点需要K比特的延迟时间(包括排队延迟时间和转发延迟时间),则传送所有数据,数据报分组交换所需时间为_______秒</p>
|
||
<p>A. ((h-1)K/B+P/B)(L/(P-H))</p>
|
||
<p>B.((h-1)K/B+hD+P/B)(L/(P-H))</p>
|
||
<p>C. P/B(L/(P-H))+hD+(h-1) K/B</p>
|
||
<p>D ((h-1)K/B+hD+P/B)(L/P)</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-22 20:01:05</p>
|
||
<p>-----每日一题 Day 113------</p>
|
||
<p>数据结构</p>
|
||
<p>1 若已知一个栈的入栈序列是1,2,3,…,30,其输出序列是p1,p2,p3,…,pn,若p1=30,则p10为_______</p>
|
||
<p>A.11</p>
|
||
<p>B. 20</p>
|
||
<p>C.30</p>
|
||
<p>D.21</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-23 18:03:02</p>
|
||
<p>-----每日一题 Day 114------</p>
|
||
<p>注意:答案见评论区</p>
|
||
<p>计算机组成原理</p>
|
||
<p>4 设机器字长为32位,一个容量为16MB的存储器,CPU按半字寻址,其可寻址的单元数是_____</p>
|
||
<p>A. 2^24</p>
|
||
<p>B. 2^23</p>
|
||
<p>C. 2^22</p>
|
||
<p>D. 2^21</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-23 18:02:06</p>
|
||
<p>-----每日一题 Day 114------</p>
|
||
<p>注意:答案见评论区</p>
|
||
<p>操作系统</p>
|
||
<p>3 下列说法正确的是_____</p>
|
||
<p>A 可顺序存取的文件不一定能随机存取,但可随机存取的文件都能顺序存取。</p>
|
||
<p>B 文件的索引表全部存放在文件控制块 FCB 中。</p>
|
||
<p>C 在文件系统中,打开文件是指创建一个文件控制块。</p>
|
||
<p>D 在文件较大时,无论是进行顺序存取还是随机存取,都以索引文件方式最快。</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-23 18:01:08</p>
|
||
<p>-----每日一题 Day 114------</p>
|
||
<p>注意:答案见评论区</p>
|
||
<p>计算机网络</p>
|
||
<p>2 采用滑动窗口机制对两个相邻结点A(发送方)和B(接收方)的通信过程进行流量控制。假定帧的序号长度为3比特,发送窗口与接收窗口的大小均为7,当A发送了编号为0、1、2、3这4个帧后,而B接收了这4个帧,但仅应答了0、1两个帧,A继续发送4、5两个帧,且这两个帧已进入B的接收缓冲区,而B仅应答了2、3两个帧,此时接收窗口最多能接收_____帧。</p>
|
||
<p>A 3</p>
|
||
<p>B 4</p>
|
||
<p>C 5</p>
|
||
<p>D 6</p>
|
||
<hr>
|
||
<p>该题更新于:2022-12-23 17:59:48</p>
|
||
<p>-----每日一题 Day 114------</p>
|
||
<p>注意:答案见评论区</p>
|
||
<p>数据结构</p>
|
||
<p>1 设数组data[m]作为循环队列的存储空间,front为队头指针,rear为队尾指针,则执行出队操作后其头指针front值为____</p>
|
||
<p>A. front=front+1</p>
|
||
<p>B. front=(front +1)%(m-1)</p>
|
||
<p>C. front=(front-1) %m</p>
|
||
<p>D. front=(front+1) %m</p>
|
||
<hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/stuff/">stuff\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>《操作系统》操作系统的基本概念</title>
|
||
<link>http://www.inksoul.top/408/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/408/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/</guid>
|
||
<pubDate>Thu, 18 Aug 2022 15:53:40 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h2 id="知识框架">知识框架</h2>
|
||
<ul>
|
||
<li>概论
|
||
<ul>
|
||
<li>特征
|
||
<ul>
|
||
<li>并发(最基本)</li>
|
||
<li>共享(最基本)</li>
|
||
<li>虚拟</li>
|
||
<li>异步</li>
|
||
</ul>
|
||
</li>
|
||
<li>目标和功能
|
||
<ul>
|
||
<li>计算机系统资源管理者</li>
|
||
<li>扩充机器</li>
|
||
<li>用户与计算机系统之间的接口
|
||
<ul>
|
||
<li>命令接口</li>
|
||
<li>程序接口</li>
|
||
<li>GUI</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li>发展
|
||
<ul>
|
||
<li>批处理操作系统$\rightarrow$分时操作系统$\rightarrow$实时操作系统$\rightarrow$网络和分布式操作系统</li>
|
||
</ul>
|
||
</li>
|
||
<li>运行机制
|
||
<ul>
|
||
<li>中断和异常</li>
|
||
<li>系统调用</li>
|
||
</ul>
|
||
</li>
|
||
<li>体系结构
|
||
<ul>
|
||
<li>大内核</li>
|
||
<li>微内核</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h2 id="操作系统的基本概念">操作系统的基本概念</h2>
|
||
<h3 id="操作系统的概念">操作系统的概念</h3>
|
||
<p>操作系统是只控制和管理整个计算机系统的硬件与软件资源,合理地组织、调度计算机的工作与资源的分配,进而为用户和其他软件提供方便接口与环境的程序集合。</p>
|
||
<p>操作系统是计算机系统中最基本的系统软件</p>
|
||
<h3 id="操作系统的特征">操作系统的特征</h3>
|
||
<p>基本特征包括并发、共享、虚拟和异步</p>
|
||
<h4 id="并发">并发</h4>
|
||
<p>并发指两个或多个事件在同一时间间隔内发生</p>
|
||
<p>操作系统的并发性指计算机系统中同时存在多个运行的程序,因而具有处理和调度多个程序同时执行的能力。</p>
|
||
<p>同一时间间隔(并发)和同一时刻(并行)的区别:</p>
|
||
<ol>
|
||
<li>宏观上有多道程序同时进行,微观上这些程序依旧是分时交替执行的,操作系统的并发性正是分时得以实现的</li>
|
||
<li>并行性则是具有同时进行运算或操作的特性,同一时刻能完成两种或两种以上的工作,需要硬件的支持</li>
|
||
</ol>
|
||
<h4 id="共享">共享</h4>
|
||
<p>共享通常指系统中的资源可供内存中多个并发执行的进程共同使用,拥有两种资源共享方式</p>
|
||
<ul>
|
||
<li>互斥共享方式</li>
|
||
</ul>
|
||
<p>互斥式共享:</p>
|
||
<p>当进程A访问某个资源时,必须先提出请求,若此时该资源空闲,则系统将其分配给进程A使用,此后有其他进程也要访问该资源时,就必须等待。仅当进程A访问完并释放该资源后,才允许另一个进程对该资源进行访问。</p>
|
||
<p>临界资源(独占资源):</p>
|
||
<p>一段时间内只允许一个进程访问的资源</p>
|
||
<p>互斥共享要求一种资源在一段时间内(哪怕是很小的时间)只能满足一个请求,否则就会出现严重的问题</p>
|
||
<ul>
|
||
<li>同时访问方式</li>
|
||
</ul>
|
||
<p>宏观上存在一些资源允许多个进程同时访问,微观上这些进程是交替地对该资源进行访问,即分时共享</p>
|
||
<hr>
|
||
<p>并发和共享是操作系统两个最基本的特征,两者互为存在的条件:</p>
|
||
<ol>
|
||
<li>资源共享是以程序的并发为条件的,若系统不允许程序并发执行,则自然不存在资源共享问题</li>
|
||
<li>若系统不能对资源共享实施有效的管理,则必将影响到程序的并发执行,甚至根本无法并发执行</li>
|
||
</ol>
|
||
<h4 id="虚拟">虚拟</h4>
|
||
<p>虚拟是指把一个物理上的实体变为若干逻辑上的对应物。</p>
|
||
<p>操作系统中采用了多种虚拟技术来实现虚拟处理器、虚拟内存和虚拟外部设备等</p>
|
||
<p>虚拟技术可归纳为:</p>
|
||
<ol>
|
||
<li>时分复用技术,如处理器的分时共享</li>
|
||
<li>空分复用技术,如虚拟存储器</li>
|
||
</ol>
|
||
<h4 id="异步">异步</h4>
|
||
<p>程序的异步性:</p>
|
||
<p>多道程序环境允许多个程序并发执行,但由于资源有限,进程执行并非一贯到底,而是走走停停,以不可预知的速度向前推进</p>
|
||
<p>异步性导致的问题:</p>
|
||
<p>异步性会使操作系统运行在一种随机的环境下,可能导致进程产生与时间有关的错误。然而在运行环境相同的情况下,操作系统就需要保证多次运行进程后得到的结果相同</p>
|
||
<h3 id="操作系统的目标和功能">操作系统的目标和功能</h3>
|
||
<p>操作系统应具有以下功能来给多道程序提供良好的运行环境</p>
|
||
<ol>
|
||
<li>处理机管理、存储器管理、设备管理和文件管理</li>
|
||
<li>需向用户提供接口以方便用户使用</li>
|
||
<li>可用于扩充机器来提供更方便的服务、更高的资源利用率</li>
|
||
</ol>
|
||
<h4 id="操作系统作为计算机系统资源的管理者">操作系统作为计算机系统资源的管理者</h4>
|
||
<ul>
|
||
<li>处理机管理</li>
|
||
</ul>
|
||
<p>在多道程序环境下,处理机的分配和运行都以进程(线程)为主要单位</p>
|
||
<p>处理机的管理可归结为对进程的管理,因此进程创建、撤销、管理、避免冲突、合理共享就是进程管理的主要任务</p>
|
||
<p>进程管理的主要功能:</p>
|
||
<ol>
|
||
<li>进程控制</li>
|
||
<li>进程同步</li>
|
||
<li>进程通信</li>
|
||
<li>死锁处理</li>
|
||
<li>处理机调度</li>
|
||
</ol>
|
||
<ul>
|
||
<li>存储器管理</li>
|
||
</ul>
|
||
<p>存储器管理用于给多道程序的运行提供良好环境,便于用户使用及提高内存利用率</p>
|
||
<p>主要功能:</p>
|
||
<ol>
|
||
<li>内存分配与回收</li>
|
||
<li>地址映射</li>
|
||
<li>内存保护与共享</li>
|
||
<li>内存扩充</li>
|
||
</ol>
|
||
<ul>
|
||
<li>文件管理</li>
|
||
</ul>
|
||
<p>负责文件管理的部分称为文件系统</p>
|
||
<p>主要功能:</p>
|
||
<ol>
|
||
<li>文件存储空间的管理</li>
|
||
<li>目录管理</li>
|
||
<li>文件读写管理和保护</li>
|
||
</ol>
|
||
<ul>
|
||
<li>设备管理</li>
|
||
</ul>
|
||
<p>主要任务是完成用户I/O请求,方便用户使用设备,提高设备利用率</p>
|
||
<p>主要功能:</p>
|
||
<ol>
|
||
<li>缓冲管理</li>
|
||
<li>设备分配</li>
|
||
<li>设备处理</li>
|
||
<li>虚拟设备</li>
|
||
</ol>
|
||
<h4 id="操作系统作为用户与计算机硬件系统之间的接口">操作系统作为用户与计算机硬件系统之间的接口</h4>
|
||
<h5 id="命令接口">命令接口</h5>
|
||
<ul>
|
||
<li>联机命令接口</li>
|
||
</ul>
|
||
<p>联机命令接口又称为交互式命令接口,适用于分时或实时系统的接口</p>
|
||
<p>可由用户在控制台或终端输入命令,经命令解释程序解释并执行后,控制权再转交回控制台或终端,这一过程往往强调交互性</p>
|
||
<p>常见为 命令提示符中输入单条指令</p>
|
||
<ul>
|
||
<li>脱机命令接口</li>
|
||
</ul>
|
||
<p>脱机命令接口又称为批处理命令接口,适用于批处理系统</p>
|
||
<p>脱机用户不能干预作业运行,事先使用作业控制命令编写&quot;命令清单&quot;,系统调度到该作业时,命令解释程序逐条解释并执行,从而间接控制作业的进行</p>
|
||
<p>常见为 使用命令编写脚本后运行</p>
|
||
<h5 id="程序接口">程序接口</h5>
|
||
<p>该接口由一组系统调用组成,用户通过在程序中使用这些系统调用来请求操作系统为其提供服务</p>
|
||
<p>常见为用户图形界面(GUI),如linux的KDE桌面</p>
|
||
<h4 id="操作系统用作扩充机器">操作系统用作扩充机器</h4>
|
||
<p>没有任何软件支持的计算称为裸机,它仅是计算机系统的物质基础。操作系统提供的资源管理功能和方便用户的各种服务功能,将裸机改造成功能更强,使用更方便的机器</p>
|
||
<p>通常将覆盖了软件的机器称为扩充机器或虚拟机</p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/408/">408\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>动画</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E5%8A%A8%E7%94%BB/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E5%8A%A8%E7%94%BB/</guid>
|
||
<pubDate>Mon, 01 Aug 2022 16:38:54 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><p>动画:</p>
|
||
<ol>
|
||
<li>交流工具,用于展示会动的东西</li>
|
||
<li>关注美学,早期动画是绘画制作的,不关注物理是否符合现实,只要看起来正确</li>
|
||
<li>建模或几何的拓展:动画即为在不同时间或不同帧有不同几何形状,将3D模型延伸到时间维度</li>
|
||
</ol>
|
||
<p>动画生成:</p>
|
||
<p>将很多图形按一定顺序和速度播放</p>
|
||
<ol>
|
||
<li>电影:一秒播放24帧</li>
|
||
<li>视频:30帧每秒</li>
|
||
<li>游戏:体验好需要60帧甚至144帧每秒</li>
|
||
<li>虚拟现实:防止用户产生眩晕需要两眼画面90帧每秒</li>
|
||
</ol>
|
||
<h2 id="动画发展历史">动画发展历史</h2>
|
||
<ul>
|
||
<li>远古人类壁画</li>
|
||
</ul>
|
||
<p><img src="../../images/animation_part1_1.png" alt=""></p>
|
||
<ul>
|
||
<li>圆盘转动</li>
|
||
</ul>
|
||
<p>人们人为制造的可以看到的动画</p>
|
||
<p>最早起,有类似圆盘的物体,可固定在某处,可以旋转</p>
|
||
<p><img src="../../images/animation_part1_2.png" alt=""></p>
|
||
<ul>
|
||
<li>第一部电影</li>
|
||
</ul>
|
||
<p>早期不用于娱乐,是一种科学研究的设备,如下图拍摄奔跑中的马可用于研究马匹运动时四肢动态</p>
|
||
<p><img src="../../images/animation_part1_3.png" alt=""></p>
|
||
<ul>
|
||
<li>第一部与电影时长相当的动画</li>
|
||
</ul>
|
||
<p>第一部手绘的与电影时长相当的动画,即剧场版:白雪公主和七个小矮人</p>
|
||
<p>每秒播放24帧,制作耗时极长</p>
|
||
<p><img src="../../images/animation_part1_4.png" alt=""></p>
|
||
<ul>
|
||
<li>第一部计算机生成的动画</li>
|
||
</ul>
|
||
<p>可追溯至1963年</p>
|
||
<p><img src="../../images/animation_part1_5.png" alt=""></p>
|
||
<ul>
|
||
<li>早期计算机动画</li>
|
||
</ul>
|
||
<p>如下图为人脸的三维结构网格,已经可以做到人物面部表情</p>
|
||
<p><img src="../../images/animation_part1_6.png" alt=""></p>
|
||
<ul>
|
||
<li>电子(计算机生成)恐龙(Digital Dinosaurs)</li>
|
||
</ul>
|
||
<p>如下图,侏罗纪公园,真正将计算机生成的恐龙放入电影中</p>
|
||
<p><img src="../../images/animation_part1_7.png" alt=""></p>
|
||
<ul>
|
||
<li>第一部计算机生成的电影时长动画</li>
|
||
</ul>
|
||
<p>第一部完全用计算机生成的动画电影:</p>
|
||
<p>皮克斯的《玩具总动员》</p>
|
||
<p>采用光栅化的方式生成阴影效果</p>
|
||
<p><img src="../../images/animation_part1_8.png" alt=""></p>
|
||
<ul>
|
||
<li>十年前的计算机动画</li>
|
||
</ul>
|
||
<p>依旧缺少一些细节</p>
|
||
<p><img src="../../images/animation_part1_9.png" alt=""></p>
|
||
<ul>
|
||
<li>2019-冰雪奇缘2</li>
|
||
</ul>
|
||
<p>充满各种细节</p>
|
||
<p><img src="../../images/animation_part1_10.png" alt=""></p>
|
||
<h2 id="关键帧动画">关键帧动画</h2>
|
||
<p>下图中,上面一行的3个动作是重要位置,对应的帧称为关键帧</p>
|
||
<p>下面一行在2个动作间补充过渡的动作</p>
|
||
<p><img src="../../images/animation_part1_11.png" alt=""></p>
|
||
<h3 id="关键帧插值">关键帧插值</h3>
|
||
<p>给定一系列不同的帧,中间帧采用插值的方式计算得到</p>
|
||
<p>找出每一帧中重要的点在其他帧的位置,所有点一一对应找出后就可以插值计算得到结果</p>
|
||
<p>插值得到的过渡往往需要看着自然、真实,对插值方式有一定要求</p>
|
||
<p>最简单的是线性插值,但下图为非线性插值</p>
|
||
<p><img src="../../images/animation_part1_12.png" alt=""></p>
|
||
<p>线性插值:</p>
|
||
<p>给定任意的连续点,将其连接成线段</p>
|
||
<p>有时需要更好的连续性,就需要用到曲线和样条,这说明几何和动画之间时存在联系的</p>
|
||
<p><img src="../../images/animation_part1_13.png" alt=""></p>
|
||
<hr>
|
||
<h2 id="物理模拟">物理模拟</h2>
|
||
<p>关键字动画是最简单的方式,插值方式生成中间帧,但人们往往更常用物理仿真的方式</p>
|
||
<h3 id="牛顿运动定律">牛顿运动定律</h3>
|
||
<p>$$F = ma$$</p>
|
||
<p>F: 施加在物体上的力</p>
|
||
<p>m:物体的质量</p>
|
||
<p>a:物体的加速度</p>
|
||
<ol>
|
||
<li>小球在重力影响下抛出时会形成抛物线</li>
|
||
<li>衣服可认为由网格形成,任何一个顶点有一定质量,受重力影响,也受其他点作用的力的影响</li>
|
||
</ol>
|
||
<p><img src="../../images/animation_part1_14.png" alt=""></p>
|
||
<h4 id="案例">案例</h4>
|
||
<ul>
|
||
<li>布料模拟</li>
|
||
</ul>
|
||
<p><img src="../../images/animation_part1_15.png" alt=""></p>
|
||
<ul>
|
||
<li>流体仿真</li>
|
||
</ul>
|
||
<ol>
|
||
<li>模拟水的运动和水滴的形成位置</li>
|
||
<li>模拟了位置和形状后进行渲染得到样式</li>
|
||
</ol>
|
||
<p><img src="../../images/animation_part1_16.png" alt=""></p>
|
||
<h3 id="质点弹簧系统">质点弹簧系统</h3>
|
||
<h4 id="案例-1">案例</h4>
|
||
<ul>
|
||
<li>绳子模拟</li>
|
||
</ul>
|
||
<p>将一根绳子模拟成很多小的弹簧,允许其在重力作用下来回摆动</p>
|
||
<p><img src="../../images/animation_part1_17.png" alt=""></p>
|
||
<ul>
|
||
<li>头发</li>
|
||
</ul>
|
||
<p><img src="../../images/animation_part1_18.png" alt=""></p>
|
||
<ul>
|
||
<li>布料</li>
|
||
</ul>
|
||
<p>布料是由网格描述的,可以使用各种不同的质点弹簧系统描述,还可使用一个点进行拖拽</p>
|
||
<p><img src="../../images/animation_part1_19.png" alt=""></p>
|
||
<p>建模足够好的情况下,模拟与仿真可以做到与现实几乎一致</p>
|
||
<p><img src="../../images/animation_part1_20.png" alt=""></p>
|
||
<p>上图受限于PDF,建议结合games101第21课</p>
|
||
<h4 id="简单的质点弹簧系统">简单的质点弹簧系统</h4>
|
||
<ul>
|
||
<li>
|
||
<p>质点弹簧系统:一系列相互连接的质点和弹簧</p>
|
||
</li>
|
||
<li>
|
||
<p>最基础的单元:一个弹簧两侧连着两个质点</p>
|
||
</li>
|
||
</ul>
|
||
<p><img src="../../images/animation_part1_21.png" alt=""></p>
|
||
<ul>
|
||
<li>理想的弹簧(无长度,产生的力与被拉长的长度成比例)</li>
|
||
</ul>
|
||
<p>$$f_{a\rightarrow b} = k_s(b-a)$$</p>
|
||
<p>$$f_{b\rightarrow a} = -f_{a\rightarrow b}$$</p>
|
||
<ol>
|
||
<li>$f_{a\rightarrow b }$为应用到a上,往b方向的作用力,往往取决于a和b之间的距离</li>
|
||
<li>(b-a)为从a指向b的向量,b-a越长,力越大,可以写出a点往b点的力</li>
|
||
<li>$k_s$劲度系数(胡克定律:固体材料受力后,应力与形变量之间存在线性关系)</li>
|
||
<li>因为力的作用的相对性,a受到向右的力,b肯定受到向左的力,两者互为相反</li>
|
||
</ol>
|
||
<ul>
|
||
<li>非0长度弹簧</li>
|
||
</ul>
|
||
<p>弹簧在正常情况下有一定的长度,为Rest length</p>
|
||
<p>弹簧在拉伸后</p>
|
||
<ol>
|
||
<li>b和a的距离为$||b - a||$</li>
|
||
<li>形变量为$||b - a|| - l$</li>
|
||
<li>受力的方向$\frac{(b - a)}{||b - a||}$</li>
|
||
</ol>
|
||
<p>$$f_{a \rightarrow b } = k_s \frac{b - a}{||b - a||}(||b - a|| - l)$$</p>
|
||
<p>因能量守恒,会永远振动下去</p>
|
||
<ul>
|
||
<li>加入摩擦力</li>
|
||
</ul>
|
||
<p>平常我们会用x来表示位置,x的一阶导数(x′)表示速度,x的二阶导数(x′′)表示加速度,在物理模拟中会用x上面加一个点表示速度,加2个点表示加速度</p>
|
||
<p>$$\dot{x} = v$$</p>
|
||
<p>$$\ddot{x} = a$$</p>
|
||
<p>加入摩擦力(damping force)使它能停止</p>
|
||
<p>对于任何一个运动的质点,如果想让它停,那力的方向肯定和速度方向相反</p>
|
||
<p><img src="../../images/animation_part1_22.png" alt=""></p>
|
||
<p>问题:</p>
|
||
<p>会引起所有的运动都停下来,这样描述的摩擦力只能描述外部的力,描述不了弹簧之间内部的力</p>
|
||
<ul>
|
||
<li>加入内部摩擦力</li>
|
||
</ul>
|
||
<p>目的:希望弹簧恢复到正常长度</p>
|
||
<p>方向:$-(b - a)/||b - a||$</p>
|
||
<p>大小:下图红框部分,a和b之间的相对速度投影在ab方向上的速度</p>
|
||
<p><img src="../../images/animation_part1_23.png" alt=""></p>
|
||
<h4 id="弹簧结构">弹簧结构</h4>
|
||
<p>弹簧可以组合成各种形状</p>
|
||
<p>如下图,可以每2根共用一个质量表示一张平面,也可以在三维空间中进行连接</p>
|
||
<p><img src="../../images/animation_part1_24.png" alt=""></p>
|
||
<h5 id="使用各种弹簧模拟一块布">使用各种弹簧模拟一块布</h5>
|
||
<ol>
|
||
<li>问题1:切变会受影响</li>
|
||
<li>问题2:存在一种力让整个形状变得不是一个平面</li>
|
||
</ol>
|
||
<p><img src="../../images/animation_part1_25.png" alt=""></p>
|
||
<ul>
|
||
<li>加入斜的对角线解决切边</li>
|
||
</ul>
|
||
<p>在以上的形状中加入斜的对角线,发生切变时,新加的蓝线会被压缩,那弹簧就会向外抵抗它</p>
|
||
<p><img src="../../images/animation_part1_26.png" alt=""></p>
|
||
<p>存在结构不对称问题,无法使模拟的布在任何一个方向拉它,它的行为保持一致</p>
|
||
<ul>
|
||
<li>加入另外一个方向上的斜对角线</li>
|
||
</ul>
|
||
<p>不能抵抗非平面的弯曲(沿着竖的或横的线折叠)</p>
|
||
<p><img src="../../images/animation_part1_27.png" alt=""></p>
|
||
<ul>
|
||
<li>加上跳过相邻质点的连接线</li>
|
||
</ul>
|
||
<p>如下图的红线,任何一个点都和它隔一个点连一根线</p>
|
||
<p>红线的连接是非常弱的,蓝线非常强</p>
|
||
<p><img src="../../images/animation_part1_28.png" alt=""></p>
|
||
<ul>
|
||
<li>例子</li>
|
||
</ul>
|
||
<p>下图是质点弹簧系统做的裙子</p>
|
||
<p>简化的表示,未表示纤维、股和线等之间的力的关系</p>
|
||
<p><img src="../../images/animation_part1_29.png" alt=""></p>
|
||
<ul>
|
||
<li>拓展</li>
|
||
</ul>
|
||
<p>除了质点弹簧系统,还有其他的方法,比如有限元方法(FEM (Finite Element Method)),这个方法被广泛应用于车辆碰撞,能够表现力之间的传导作用</p>
|
||
<p><img src="../../images/animation_part1_30.png" alt=""></p>
|
||
<h3 id="粒子系统">粒子系统</h3>
|
||
<p>用于描述一些很小很小移动的东西</p>
|
||
<p>建模一堆很微小的东西,定义每一个粒子会受到的力(有重力、风力、粒子和粒子之间的力)</p>
|
||
<p>很容易模仿一些魔法效果、雾、灰尘等等</p>
|
||
<p>粒子越多模拟得越精细,但是越慢;越少,计算速度越快,但效果差一些</p>
|
||
<p><img src="../../images/animation_part1_31.png" alt=""></p>
|
||
<h4 id="存在问题">存在问题</h4>
|
||
<ol>
|
||
<li>粒子系统可以模拟流体,这样可能需要很多粒子</li>
|
||
<li>粒子和粒子之间的作用不只有碰撞,还可能有引力,需要随时更新粒子的位置</li>
|
||
</ol>
|
||
<h4 id="算法">算法</h4>
|
||
<ol>
|
||
<li>动态生成一些新的粒子</li>
|
||
<li>计算每个粒子的作用力</li>
|
||
<li>根据作用力更新粒子的位置和速度</li>
|
||
<li>如果粒子有存活时间,移除消亡的粒子</li>
|
||
<li>渲染粒子</li>
|
||
</ol>
|
||
<h4 id="粒子系统的力">粒子系统的力</h4>
|
||
<ul>
|
||
<li>吸引力和排斥力
|
||
<ul>
|
||
<li>重力、电磁力</li>
|
||
<li>弹力、推力</li>
|
||
</ul>
|
||
</li>
|
||
<li>阻尼力
|
||
<ul>
|
||
<li>摩擦力、空气阻力、粘滞力</li>
|
||
</ul>
|
||
</li>
|
||
<li>碰撞
|
||
<ul>
|
||
<li>墙、容器、固定物体</li>
|
||
<li>动态物体、角色身体碰撞</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h4 id="例子">例子</h4>
|
||
<ul>
|
||
<li>万有引力</li>
|
||
</ul>
|
||
<p>最小的物体都会满足此规律</p>
|
||
<p>$$F_g = G\frac{m_1m_2}{d^2}$$</p>
|
||
<p>$$G = 6.67428 \times 10^{-11}Nm^2kg^{-2}$$</p>
|
||
<p><img src="../../images/animation_part1_32.png" alt=""></p>
|
||
<ul>
|
||
<li>银河模拟</li>
|
||
</ul>
|
||
<p><img src="../../images/animation_part1_33.png" alt=""></p>
|
||
<ul>
|
||
<li>基于粒子的流体模拟</li>
|
||
</ul>
|
||
<p>模拟的是粒子,渲染的是像玻璃、是否带白沫</p>
|
||
<p><img src="../../images/animation_part1_34.png" alt=""></p>
|
||
<h4 id="粒子间相互作用">粒子间相互作用</h4>
|
||
<p>粒子系统不一定只是描述最简单的点,这个粒子也就是在一个很大范围内有很多重复的东西</p>
|
||
<p>个体的运动属性:</p>
|
||
<p>会被中央的相邻点吸引</p>
|
||
<p>粒子间间隔不会太近</p>
|
||
<p>所有粒子会对齐一个方向</p>
|
||
<p>有了以上的属性就可以通过粒子的方法解出来</p>
|
||
<p><img src="../../images/animation_part1_35.png" alt=""></p>
|
||
<ul>
|
||
<li>分子结构</li>
|
||
</ul>
|
||
<p><img src="../../images/animation_part1_36.png" alt=""></p>
|
||
<ul>
|
||
<li>人群</li>
|
||
</ul>
|
||
<p><img src="../../images/animation_part1_37.png" alt=""></p>
|
||
<h2 id="运动学">运动学</h2>
|
||
<p>在图形学中运动学分为正向的和反向的,即正运动学和逆运动学</p>
|
||
<h3 id="正运动学">正运动学</h3>
|
||
<h4 id="骨骼系统">骨骼系统</h4>
|
||
<p>用于描述和人骨骼连接拓扑结构类似的结构,可定义不同的关节</p>
|
||
<p><img src="../../images/animation_part1_38.png" alt=""></p>
|
||
<ul>
|
||
<li>Pin</li>
|
||
</ul>
|
||
<p>钉子钉住后只能在钉住的平面内往一个方向旋转</p>
|
||
<p><img src="../../images/animation_part1_39.png" alt=""></p>
|
||
<ul>
|
||
<li>Ball</li>
|
||
</ul>
|
||
<p>有一个东西可以包住一个球,这个球可以任意的在任意方向旋转</p>
|
||
<ul>
|
||
<li>Prismatic joint</li>
|
||
</ul>
|
||
<p>可以拉长,也就是可以有一些移动</p>
|
||
<p><img src="../../images/animation_part1_40.png" alt=""></p>
|
||
<h4 id="一个简单的关节">一个简单的关节</h4>
|
||
<p>如下图,只能在平面内发生旋转,类似于肩和肘的旋转,假设第一段旋转$\theta_1$度,第二段旋转$\theta_2$度,如何确定尖端位置</p>
|
||
<p><img src="../../images/animation_part1_41.png" alt=""></p>
|
||
<p>先算出上方黑点的位置,因为$\theta_2$是在$\theta_1$的基础上旋转的,可以用$\theta_1$加$\theta_2$计算</p>
|
||
<p><img src="../../images/animation_part1_42.png" alt=""></p>
|
||
<p>因此,正向运动学需要定义好连接方式,定义好它们之间的各种位置,就可以找到各种点的位置</p>
|
||
<ul>
|
||
<li>例子</li>
|
||
</ul>
|
||
<p>人类行走动作模拟</p>
|
||
<p><img src="../../images/animation_part1_43.png" alt=""></p>
|
||
<h5 id="优缺点">优缺点</h5>
|
||
<ul>
|
||
<li>优点</li>
|
||
</ul>
|
||
<p>实现容易</p>
|
||
<ul>
|
||
<li>缺点</li>
|
||
</ul>
|
||
<p>它的定义都很物理</p>
|
||
<p>但是艺术家们更喜欢直观的控制尖端进行动画的创建,而非调整角度</p>
|
||
<h3 id="逆向运动学">逆向运动学</h3>
|
||
<p>逆运动学可以手里捏着尖端到处移动,它会自动的调整它的关节的位置,使得尖端就在你要的位置上</p>
|
||
<p><img src="../../images/animation_part1_44.png" alt=""></p>
|
||
<p>如下图中,给出固定点P,它就会给出$\theta_1$和$\theta_2$,解出这两个角度的过程比较复杂</p>
|
||
<p><img src="../../images/animation_part1_45.png" alt=""></p>
|
||
<h4 id="问题">问题</h4>
|
||
<ul>
|
||
<li>逆向运动学的解有时候不唯一</li>
|
||
</ul>
|
||
<p>如图,尖端位置确定,但存在两个解</p>
|
||
<p><img src="../../images/animation_part1_46.png" alt=""></p>
|
||
<p><img src="../../images/animation_part1_47.png" alt=""></p>
|
||
<ul>
|
||
<li>存在无解的情况</li>
|
||
</ul>
|
||
<p>最上面的关节点只可能出现在下图的虚线上,尖端通过旋转可以在一个圆上,从而尖端只有可能在外层的圈和内层的圈之间,其他位置到不了</p>
|
||
<p><img src="../../images/animation_part1_48.png" alt=""></p>
|
||
<h4 id="问题优化">问题优化</h4>
|
||
<p>一般N维IK问题的数值求解</p>
|
||
<ul>
|
||
<li>选择初始配置</li>
|
||
<li>定义错误度量(例如:目标与当前位置之间距离的平方)</li>
|
||
<li>计算误差梯度作为配置的函数</li>
|
||
<li>应用梯度下降或牛顿方法</li>
|
||
</ul>
|
||
<h2 id="绑骨riging">绑骨(Riging)</h2>
|
||
<p>对于一个形状的控制,其实就是木偶操作,一定程度上就是逆运动学的一个应用</p>
|
||
<p>例子:</p>
|
||
<p><img src="../../images/animation_part1_49.png" alt=""></p>
|
||
<h3 id="形状混合">形状混合</h3>
|
||
<p>人物有2个不同的动作,这2个动作之间可以通过插值的方式做。利用控制点做了2个不同的造型,然后将控制点和控制点之间的位置做插值</p>
|
||
<p>实际为混合控制点及其影响区域</p>
|
||
<p><img src="../../images/animation_part1_50.png" alt=""></p>
|
||
<h3 id="动作捕捉">动作捕捉</h3>
|
||
<p>给真人各个不同的地方加上控制点,让这些控制点的位置直接反应到虚拟的造型上去。要建立虚拟的人物和真实的人物之间的关系,此时只要人在做动作时将它拍下来,就可以知道控制点的不同的位置并反应到对应的人物上面去</p>
|
||
<p><img src="../../images/animation_part1_51.png" alt=""></p>
|
||
<h4 id="优缺点-1">优缺点</h4>
|
||
<ul>
|
||
<li>优点</li>
|
||
</ul>
|
||
<p>可以迅速捕捉大量的真实数据,避免手K的耗时耗力的操作</p>
|
||
<p>真实感非常强</p>
|
||
<ul>
|
||
<li>缺点</li>
|
||
</ul>
|
||
<p>进行动作捕捉需要很多前期的准备</p>
|
||
<p>捕捉出来的动作可能不符合艺术家的需求,需要调整(比如真人去演动画人物,动画人物的表情是很夸张的;或者有时捕捉不到好的数据,比如捕捉条件有限制,人在正面的时候看到的控制点,背面也有但正面看不到,那就要在背后加一个摄像机,这就需要成本,而且正常需要更多的摄像机;人物动作的时候还会遮挡)</p>
|
||
<p><img src="../../images/animation_part1_52.png" alt=""></p>
|
||
<h4 id="其他捕捉方法">其他捕捉方法</h4>
|
||
<p>还有磁力的(不受遮挡影响)、机械的(真正在人身上贴上机械的东西)</p>
|
||
<p><img src="../../images/animation_part1_53.png" alt=""></p>
|
||
<h3 id="光学动作捕捉">光学动作捕捉</h3>
|
||
<p>应用最广泛的还是光学的捕捉方法,贴一些Maker(贴片或小球)贴在人身上,然后用很多很复杂的摄像机,将这些点的位置非常准确的测出来</p>
|
||
<p><img src="../../images/animation_part1_54.png" alt=""></p>
|
||
<p><img src="../../images/animation_part1_55.png" alt=""></p>
|
||
<h4 id="获取的动作数据">获取的动作数据</h4>
|
||
<p>下图曲线就为一个控制点不同时间在三维空间中的位置</p>
|
||
<p><img src="../../images/animation_part1_56.png" alt=""></p>
|
||
<h4 id="面部动画的问题">面部动画的问题</h4>
|
||
<p>非常真实的动画往往会出现恐怖谷效应</p>
|
||
<p>恐怖谷效应:人们会对生成的过于真实的人类感到害怕</p>
|
||
<p><img src="../../images/animation_part1_57.png" alt=""></p>
|
||
<h4 id="面部动作捕捉">面部动作捕捉</h4>
|
||
<p>阿凡达这部电影具有里程碑式的效应,就是因为使用了面部动作捕捉</p>
|
||
<p><img src="../../images/animation_part1_58.png" alt=""></p>
|
||
<h4 id="动画电影的生成过程">动画/电影的生成过程</h4>
|
||
<p>分别为Pre-Production、Production、Post-Production三个部分,具体工作内容和职责可由下图所示</p>
|
||
<p><img src="../../images/animation_part1_59.png" alt=""></p>
|
||
<hr>
|
||
<h2 id="单粒子模拟">单粒子模拟</h2>
|
||
<p>可在已知任何一个物体任何时刻的速度和初始位置的情况下计算某个时间后的位置</p>
|
||
<ol>
|
||
<li>粒子满足匀速直线运动,初始位置加上速度和时间的乘积即可</li>
|
||
<li>一个粒子在一个速度场会沿着类似水流的方向往前走</li>
|
||
</ol>
|
||
<p><img src="../../images/animation_part2_1.png" alt=""></p>
|
||
<p>此时在任何一个位置x和时间t,都有一个速度</p>
|
||
<p>$$v(x,t)$$</p>
|
||
<h3 id="常微分方程ode">常微分方程(ODE)</h3>
|
||
<p>对于一个物体的运动模拟,可以写成一阶常微分方程(Ordinary Differential Equation (ODE)的形式</p>
|
||
<p>$$\frac{dx}{dt} = \dot{x} = v(x,t)$$</p>
|
||
<h3 id="欧拉方法前向欧拉显式欧拉">欧拉方法(前向欧拉,显式欧拉)</h3>
|
||
<p>已知速度和起始位置,求任意时刻位置</p>
|
||
<p><img src="../../images/animation_part2_2.png" alt=""></p>
|
||
<p>将时间细分为很多的小块,不断计算$t+\Delta t$的位置</p>
|
||
<p>$$x^{t+\Delta t} = x^ t+\Delta t \dot{x}^t$$</p>
|
||
<p>$$\dot{x}^{t+\Delta t} = \dot{x}^t + \Delta t \ddot{x}^t$$</p>
|
||
<p>始终使用上一时刻的量来估计下一时刻的量</p>
|
||
<h4 id="问题-1">问题</h4>
|
||
<p>欧拉方法会迅速变得不稳定</p>
|
||
<ul>
|
||
<li>减少$\Delta t$来减少误差</li>
|
||
</ul>
|
||
<p>$\Delta t$分得越细,模拟就会越精确,如果越大,和实际的路线偏离得越多</p>
|
||
<p><img src="../../images/animation_part2_3.png" alt=""></p>
|
||
<ul>
|
||
<li>不稳定性</li>
|
||
</ul>
|
||
<p>不稳定:无论取多大的$\Delta t$,它都会变得和实际结果相差无限远</p>
|
||
<p>如下图,不管取多大的步长,路线都肯定不会沿着螺旋形走,而且一定会离开这个螺旋形的速度场</p>
|
||
<p>事实上,粒子在一个螺旋形的速度场,一定会按照严格的圆周运动</p>
|
||
<p><img src="../../images/animation_part2_4.png" alt=""></p>
|
||
<p>如下图速度场中,粒子运动轨迹与实际按一根曲线慢慢走到水平存在极大差别</p>
|
||
<h4 id="总结数值方法解微分方程都会面临的问题">总结:数值方法解微分方程都会面临的问题</h4>
|
||
<ul>
|
||
<li>误差</li>
|
||
</ul>
|
||
<p>每一步计算都会有误差,累积起来还是有误差</p>
|
||
<p>如果用的步长较小,就可以降低误差</p>
|
||
<p>对于图形学来说,有时候模拟出来的误差问题也不大,因为图形学关注的是模拟看起来的效果,而不是物理上特别的真实</p>
|
||
<ul>
|
||
<li>不稳定</li>
|
||
</ul>
|
||
<p>不管通过怎样的方法模拟得到的结果,最后都和实际的正确的结果差得越来越远</p>
|
||
<p>如下图对应链接的视频,在绝地求生中,车辆撞上摩托后会出现奇怪的翻滚现象,这在许多存在物理引擎的游戏中普遍存在</p>
|
||
<p><img src="../../images/animation_part2_5.png" alt=""></p>
|
||
<h4 id="解决办法">解决办法</h4>
|
||
<ul>
|
||
<li>中点法</li>
|
||
</ul>
|
||
<p>避免欧拉方法在模拟的过程中让结果离得越来越远</p>
|
||
<ol>
|
||
<li>一开始有一个位置和一个方向,可以直接用欧拉方法来模拟某个$\Delta t$,让其先到达a</li>
|
||
<li>取原始点和a点之间的中点b,考虑它所在的速度</li>
|
||
<li>再回到原始的出发点,应用b点的速度来重新再算一遍欧拉方法,到达c点</li>
|
||
</ol>
|
||
<p><img src="../../images/animation_part2_6.png" alt=""></p>
|
||
<p>$$x_{mid} = x(t) + \Delta t/2 \cdot v(x(t),t)$$</p>
|
||
<p>$$x(t+\Delta t) = x(t) +\Delta t \cdot v(x_{mid},t)$$</p>
|
||
<p>依旧使用的欧拉方法只是计算了两次,第一次得到中点速度,第二次代入中点速度计算</p>
|
||
<p>因为多了一个二次项而更加准确</p>
|
||
<p>$$x^{t+\Delta t} = x^t +\frac{\Delta t}{2}(\dot{x}^t+\dot{x}^{t+\Delta t})$$</p>
|
||
<p>$$\dot{x}^{t+\Delta t} = \dot{x}^t + \Delta t \ddot{x}^t$$</p>
|
||
<p>$$\dot{x}^{t+\Delta t} = x^t +\Delta t \dot{x}^t + \frac{(\Delta t)^2}{2}\ddot{x}^t$$</p>
|
||
<p>可以认为中点法作为修正的欧拉方法算出了局部的二次的模型,因而比一次的模型准确</p>
|
||
<ul>
|
||
<li>自适应步长改变</li>
|
||
</ul>
|
||
<p>如图,原始点使用欧拉方法经$\Delta t$在$x_T$上</p>
|
||
<p>将时间减半,得到2个$\Delta t$,计算2次,从原始点先用$\frac{\Delta t}{2}$ 算到一个位置,再使用$\frac{\Delta t}{2}$再算一次,到达$\frac{x_T}{2}$</p>
|
||
<p><img src="../../images/animation_part2_7.png" alt=""></p>
|
||
<p>如果$x_T和\frac{x_T}{2}$这2个点差得挺远,这就意味着将$\Delta t$分成2部分分别考虑这样做会更准确,那就应该考虑$\frac{\Delta t}{2}$;如果差得不远,就没必要再分下去</p>
|
||
<ul>
|
||
<li>隐式欧拉方法</li>
|
||
</ul>
|
||
<p>使用下一个时间的梯度来更新此时</p>
|
||
<p>要解下列方程组,如果速度与加速度之间不是简单的线性关系就不太好解了</p>
|
||
<p>$$x^{t+\Delta t} = x^t +\Delta t \dot{x}^{t+\Delta}t$$</p>
|
||
<p>$$\dot{x}^{t+\Delta t} = \dot{x}^t+\Delta t \ddot{x}^{t+\Delta t}$$</p>
|
||
<p>可以用求根公式,虽然比之前数值的解法要慢很多,但隐式的方法可以提供更好的稳定性</p>
|
||
<ul>
|
||
<li>龙格库塔方法(Runge-Kutta Families)</li>
|
||
</ul>
|
||
<p>龙格库塔是一类解常微分方程(ODE)方法(特别是非线性的情况)</p>
|
||
<p>其中RK4方法是应用最广泛的</p>
|
||
<p>解决的方法和欧拉方法是一样的:</p>
|
||
<p>有一个一阶导数,它和时间和位置有关,并且有一个初始情况</p>
|
||
<p>在更新的时候稍微有点不一样:用上一帧的位置用$\Delta t$乘以某个平均值来更新</p>
|
||
<p>下面的4个值是不同位置和不同时间在速度场中的值</p>
|
||
<p><img src="../../images/animation_part2_8.png" alt=""></p>
|
||
<h4 id="非物理方法">非物理方法</h4>
|
||
<p>通过调整它的不同位置,使得它最后能够满足某种限制</p>
|
||
<p>优点:</p>
|
||
<p>实现起来快、简单</p>
|
||
<p>缺点:</p>
|
||
<p>有时不能保证能量守恒的性质</p>
|
||
<h2 id="刚体模拟">刚体模拟</h2>
|
||
<p>刚体不会发生形变,它会让内部所有的点都按照同一种方式去运动</p>
|
||
<p>如下图,一个刚体的位置、朝向、速度、角速度分别对时间求导后得到速度、角速度、加速度、角加速度</p>
|
||
<p><img src="../../images/animation_part2_13.png" alt=""></p>
|
||
<h2 id="流体模拟">流体模拟</h2>
|
||
<h3 id="简单的非物理方法">简单的非物理方法</h3>
|
||
<p>通过模拟形成水的体积的小球的位置来模拟整个水的运动</p>
|
||
<ol>
|
||
<li>认为整个水体是由很多不可压缩的刚体小球组成的</li>
|
||
<li>水在任何地方都是不可压缩的</li>
|
||
<li>给定任何一个时刻这些小球它们分布,都可以知道任何一个地方的密度。如果有任何一个地方的密度变得和水一开始平静的时候的密度不一样,那就需要通过移动小球的位置把这个密度修正</li>
|
||
<li>需要知道任何一个点它的密度对所有的小球位置的梯度(导数)</li>
|
||
</ol>
|
||
<p><img src="../../images/animation_part2_9.png" alt=""></p>
|
||
<h3 id="欧拉方法和拉格朗日方法">欧拉方法和拉格朗日方法</h3>
|
||
<p>物理模拟中模拟大规模的物质</p>
|
||
<ul>
|
||
<li>拉格朗日方法俗称质点法</li>
|
||
</ul>
|
||
<p>模拟水是认为水是由很多圆形的小水滴组成,挨个模拟小水滴</p>
|
||
<p>如下图,如果模拟一群小鸟的移动,就只关注某一只</p>
|
||
<p><img src="../../images/animation_part2_10.png" alt=""></p>
|
||
<ul>
|
||
<li>欧拉方法俗称网格法</li>
|
||
</ul>
|
||
<p>这里是指如何去看待模拟的一系列大规模的物体,将整个空间分成不同的网格,不管网格中的东西是出去了还是进来了,就考虑这个网格随着不同的时间是如何变化的</p>
|
||
<p>如下划分多个网格就知道时间t为黑色的鸟,t-1应显示蓝色的鸟</p>
|
||
<p><img src="../../images/animation_part2_11.png" alt=""></p>
|
||
<h3 id="物质点方法">物质点方法</h3>
|
||
<p>结合了上述两个方法</p>
|
||
<ol>
|
||
<li>认为这些不同的粒子都具有某些材质属性,存储在点上</li>
|
||
<li>融化的过程在网格中做</li>
|
||
<li>再将格子上的信息写回不同的粒子上去</li>
|
||
</ol>
|
||
<p><img src="../../images/animation_part2_12.png" alt=""></p>
|
||
<hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>光场、颜色和感知</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E5%85%89%E5%9C%BA%E9%A2%9C%E8%89%B2%E5%92%8C%E6%84%9F%E7%9F%A5/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E5%85%89%E5%9C%BA%E9%A2%9C%E8%89%B2%E5%92%8C%E6%84%9F%E7%9F%A5/</guid>
|
||
<pubDate>Sat, 30 Jul 2022 16:49:52 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h2 id="光场light-fieldlumigraph">光场(Light Field/Lumigraph)</h2>
|
||
<p>两个都指光场,来源于该现象由两个不同组各自法线并命名,现在仍然有争论</p>
|
||
<h3 id="我们看到的世界是什么">我们看到的世界是什么</h3>
|
||
<p>坐在房间的一侧往窗户的一侧看,三维和二维的情况是下面这样的</p>
|
||
<p><img src="../../images/color_and_perception_1.png" alt=""></p>
|
||
<p>如果加上一个幕布,显示上图图像,往往人们难以区别于现实世界,即为虚拟现实的原理</p>
|
||
<p><img src="../../images/color_and_perception_2.png" alt=""></p>
|
||
<h3 id="全光函数the-plenoptic-function">全光函数(The Plenoptic Function)</h3>
|
||
<ul>
|
||
<li>函数 Grayscale snapshot</li>
|
||
</ul>
|
||
<p>统计往任意方向上的所见值,可定义一个函数,最后结果为一个数</p>
|
||
<p><img src="../../images/color_and_perception_4.png" alt=""></p>
|
||
<ul>
|
||
<li>改进函数 Color snapshot</li>
|
||
</ul>
|
||
<p>改进后引入波长,即为引入颜色(因光的不同波长而产生颜色)</p>
|
||
<p>记录各个方向看到的不同方向上的光,就可以看到彩色场景</p>
|
||
<p><img src="../../images/color_and_perception_5.png" alt=""></p>
|
||
<ul>
|
||
<li>扩展的全光函数 A movie</li>
|
||
</ul>
|
||
<p>进一步将全光函数扩展一个时间t,那下面这个四维的函数就是电影,因为你可以往各个不同的方向看,看到各个不同方向来的信息都是彩色的,然后在不同时间显示的东西不一样</p>
|
||
<p><img src="../../images/color_and_perception_6.png" alt=""></p>
|
||
<ul>
|
||
<li>进一步扩展 Holographic movie</li>
|
||
</ul>
|
||
<p>现在考虑人/摄像机可以在三维空间中的任何地方移动,三维空间中的任何一个位置可以用x、y、z定义。那这也就是全息电影</p>
|
||
<p><img src="../../images/color_and_perception_7.png" alt=""></p>
|
||
<ul>
|
||
<li>再改进一步 The Plenoptic Function</li>
|
||
</ul>
|
||
<p>将它理解成在任何位置,然后往任何方向看,并且在任何时间看到的都是不同的颜色,即为整个世界是一个7个维度的函数</p>
|
||
<p>将这个7维的函数当做全光函数</p>
|
||
<ul>
|
||
<li>全光函数和光场</li>
|
||
</ul>
|
||
<p>全光函数本身的定义:</p>
|
||
<p>在任何位置,任意方向,我们知道它过来的光是多少,方向也应是连续的,这就是一个简单的二维全光函数的表示</p>
|
||
<p>可以从全光函数中提取一部分信息出来,用来表示更复杂的光,就是说我们平常在一个点我们往任意方向看,那记录的是来自各个方向的光的信息,那光场就记录了更多的信息,光场就是全光函数的一个小部分</p>
|
||
<p><img src="../../images/color_and_perception_9.png" alt=""></p>
|
||
<h2 id="光场">光场</h2>
|
||
<h3 id="定义光线">定义光线</h3>
|
||
<ul>
|
||
<li>通过一个起点和一个方向定义</li>
|
||
</ul>
|
||
<p><img src="../../images/color_and_perception_10.png" alt=""></p>
|
||
<ul>
|
||
<li>取光线上的任意两点定义整条光线(二维位置和方向)</li>
|
||
</ul>
|
||
<p>物体可以放在一个包围盒中,从任何位置和任何方向看向这个物体,根据光路的可逆性,也可以认为要想描述这个物体所能被看到的所有的情况,就去描述这个物体在它的包围盒上在任何位置往任何方向过去的光线</p>
|
||
<p>已知包围盒上的点,观测位置的点,这两点确定一条光线,可以查询记录的函数,该函数记录了物体表面不同位置往各个不同方向的发光情况</p>
|
||
<p><img src="../../images/color_and_perception_11.png" alt=""></p>
|
||
<h3 id="定义光场">定义光场</h3>
|
||
<p>光场:在任何一个位置往任何一个方向去的光的强度</p>
|
||
<p>如果有了一个物体的光场,如下图,任何一个位置往任何一个方向都可以发光。我们在任何一个位置往这个物体某个点看的时候,是可以知道这条光线带的能量是多少的,因为通过这2个点可以知道往这个点看的方向,就可以从4维的光场中查询到之前记录的光场的值,即光场可以给出任意观测方向看到的结果</p>
|
||
<p><img src="../../images/color_and_perception_12.png" alt=""></p>
|
||
<h3 id="记录光场">记录光场</h3>
|
||
<ul>
|
||
<li>记录上述将物体放在包围盒里后,盒子上的任何一个点往任何一个方向的光线</li>
|
||
</ul>
|
||
<p>观测点必须在包围盒外</p>
|
||
<p><img src="../../images/color_and_perception_13.png" alt=""></p>
|
||
<ul>
|
||
<li>取一平面,平面右侧有有物体发出光线打到平面上</li>
|
||
</ul>
|
||
<p>如图已知平面一点,二维只需$\theta$,三维则需两个数$(\theta,\phi)$</p>
|
||
<ul>
|
||
<li>参数化光场</li>
|
||
</ul>
|
||
<p>光线还可以用2个点来确定,那就可以用2个平面来定义一个光场</p>
|
||
<p>定义2个相互平行的平面,2个平面上各自任取一个点,连接两点即可确定光线</p>
|
||
<p>找到所有u、v和s、t的组合,可以描述所有的不同位置和不同方向出来的光线</p>
|
||
<p><img src="../../images/color_and_perception_14.png" alt=""></p>
|
||
<p><img src="../../images/color_and_perception_15.png" alt=""></p>
|
||
<p><img src="../../images/color_and_perception_16.png" alt=""></p>
|
||
<p>光场本质上就是一个4维的函数,不同记录方法即为描述方式不同</p>
|
||
<h3 id="对以上使用两个平面参数化">对以上使用两个平面参数化</h3>
|
||
<ul>
|
||
<li>u、v处取一点看向所有s、t平面</li>
|
||
</ul>
|
||
<p>如下图,在u、v上取一个点,这个视角的右边是我们需要看到的东西,这就好像一个针孔摄像机所能看到的东西,所以能看到一个完整的物体的图。u、v上不同的位置出发,就相当于从不同的角度看向这个世界</p>
|
||
<p><img src="../../images/color_and_perception_17.png" alt=""></p>
|
||
<p>很多摄像机从某一个角度看向世界,拍一张图,然后将所有图都组织到一块,就是整个光场。如下图,斯坦福做了一个摄像机的矩阵,相当于在不同的位置对场景拍不同的图,每个位置对应一个u、v,拍到的照片是s、t,相机本身二维,成像结果二维,综合为四维</p>
|
||
<p><img src="../../images/color_and_perception_18.png" alt=""></p>
|
||
<ul>
|
||
<li>固定s、t平面上一个点,然后往u、v平面上看</li>
|
||
</ul>
|
||
<p>整个世界还是在s、t平面的右边,从u、v上的任何一个点都看向s、t上的同一点。就好像盯着同一个点,从不同的角度去看,会看到很多类似不同高光的东西</p>
|
||
<p>通过这种方式,可以将像素上的Irradiance给展开成Radiance,可以看到打到任何一个像素上不同方向的光</p>
|
||
<p><img src="../../images/color_and_perception_19.png" alt=""></p>
|
||
<p>苍蝇的复眼成像原理就是成像一个光场,盯着原本拍出的一张照片来看,那照片上的任何一个像素记录的是Irradiance(平均各个方向的光)</p>
|
||
<p>如下图,普通相机记录下来的就是蓝色、绿色、红色的平均。如果有办法可以把它分开,比如这个光打到像素点时不立刻记录它,而是把这个像素变成某个小的透镜,把来自于各个方向的光给分到不同的位置上去(分光)。把实际的感光元件放在底下,就可以将它们分别记录到不同位置,此时就可以记录Radiance</p>
|
||
<p>此时看一个像素实际为穿过像素的不同方向的光</p>
|
||
<p><img src="../../images/color_and_perception_20.png" alt=""></p>
|
||
<h2 id="光场相机">光场相机</h2>
|
||
<p>利用光场原理制作的相机</p>
|
||
<h3 id="the-lytro-light-field-camera">The Lytro Light Field Camera</h3>
|
||
<p>Lytro相机有下图这个人创办</p>
|
||
<p><img src="../../images/color_and_perception_21.png" alt=""></p>
|
||
<ul>
|
||
<li>
|
||
<p>原理:Microlens design(上面谈到的微透镜)。将一个像素替换成一个透镜,让这个透镜可以把来自于不同方向的光分开并记录下来</p>
|
||
</li>
|
||
<li>
|
||
<p>功能:支持拍照后的重新聚焦</p>
|
||
</li>
|
||
<li>
|
||
<p>具体效果如下图:</p>
|
||
</li>
|
||
</ul>
|
||
<p><img src="../../images/color_and_perception_22.png" alt=""></p>
|
||
<ul>
|
||
<li>详细原理</li>
|
||
</ul>
|
||
<p>将原本的像素换成了微透镜,这些微透镜可以把来自各方向的光分散到不同的方向上去,在后面再将它记录下来</p>
|
||
<p><img src="../../images/color_and_perception_23.png" alt=""></p>
|
||
<p>光场照相机照出来的最原始的图实际上是原本的一个像素变成了一个圆,任何一个圆内部平均起来就是以前普通的照相机得到的结果,在一个圆的内部各个像素其实就是记录了各个不同的方向</p>
|
||
<p><img src="../../images/color_and_perception_24.png" alt=""></p>
|
||
<ul>
|
||
<li>得到普通相机照片</li>
|
||
</ul>
|
||
<ol>
|
||
<li>
|
||
<p>透镜原本是像素,从透镜中各个不同的光线中选一条,如果都选最下面那条,并将结果记录在对应的一个像素上,现在透镜就对应了一个值</p>
|
||
</li>
|
||
<li>
|
||
<p>每一个透镜都取中间这条光线,那就好像把相机放在正中间往左边去看</p>
|
||
</li>
|
||
<li>
|
||
<p>都取最上面的往左下方打的光线,相当于相机在上面</p>
|
||
</li>
|
||
</ol>
|
||
<p>类似于有光场后,取不同方向的光线就可以虚拟地移动摄像机位置</p>
|
||
<ul>
|
||
<li>动态重新聚焦</li>
|
||
</ul>
|
||
<p>与上述相同原理,在拥有整个光场时,在四维的光场中记录了所有可能的光线的位置和方向信息,那就可以查询更新了之后的光线应该查哪一条,那就对于不同的透镜查的可能并不是同一个位置,你算出来应该查询哪一个方向就去查询哪一个方向</p>
|
||
<ul>
|
||
<li>问题</li>
|
||
</ul>
|
||
<p>分辨率不足</p>
|
||
<p>原本成像平面在透镜的位置,现在成像平面在后面,每一个小块记录的是原本的普通相机对应的一个像素,如果都用相同的胶片,那原本一个像素记录一个像素的信息,现在要用100个像素记录一个像素的信息(假设是10x10的),因为把不同的方向分开了。也就是说胶片的分辨率现在变成了一个空间上的分辨率</p>
|
||
<p>方向上记录得越多,照片本身记录分辨率越低</p>
|
||
<p>高成本</p>
|
||
<ol>
|
||
<li>为了达到原有分辨率,要使用超级的分辨率的实际胶片</li>
|
||
<li>微透镜的设计制造成本高,是一个超级精密的仪器</li>
|
||
</ol>
|
||
<hr>
|
||
<h2 id="颜色">颜色</h2>
|
||
<h3 id="颜色的物理基础">颜色的物理基础</h3>
|
||
<h4 id="光的基本成分">光的基本成分</h4>
|
||
<p>牛顿曾做过将一束白光穿过棱角,其会被分解成各个不同颜色</p>
|
||
<p>不同的颜色可以合成其他的颜色,将所有的颜色合在一起又会形成白色</p>
|
||
<p><img src="../../images/color_and_perception_25.png" alt=""></p>
|
||
<h4 id="可见光谱">可见光谱</h4>
|
||
<p>不同的波长对应不同的折射率,某一种光一定对应某一种光谱</p>
|
||
<p>光谱是光线的能量在不同的波长上的分布。光谱是一个很长的范围,图形学中重要的是可见光的光谱,即分布在波长在400nm到700nm之间</p>
|
||
<p><img src="../../images/color_and_perception_26.png" alt=""></p>
|
||
<h4 id="谱功率密度spd">谱功率密度(SPD)</h4>
|
||
<p>光谱的准确定义名是谱功率密度</p>
|
||
<p>单位:辐射单位/纳米,也可能无单位</p>
|
||
<ul>
|
||
<li>蓝天和太阳光的SPD</li>
|
||
</ul>
|
||
<p>如下图可见:</p>
|
||
<p>蓝天部分更多的能量集中在高频</p>
|
||
<p>阳光则是另一种SPD</p>
|
||
<p><img src="../../images/color_and_perception_27.png" alt=""></p>
|
||
<h4 id="不同光源的spd">不同光源的SPD</h4>
|
||
<p><img src="../../images/color_and_perception_28.png" alt=""></p>
|
||
<ul>
|
||
<li>SPD的线性性质</li>
|
||
</ul>
|
||
<p>用一种光照亮能记录光强度的东西能够得到右边的另一种分布;两种光同时照亮得到的分布就是它们两个对应的SPD之和</p>
|
||
<p><img src="../../images/color_and_perception_29.png" alt=""></p>
|
||
<h3 id="颜色的生物学基础">颜色的生物学基础</h3>
|
||
<p>颜色可以认为是人的感知</p>
|
||
<h3 id="人眼结构">人眼结构</h3>
|
||
<p>相机是人眼的仿生</p>
|
||
<p>人眼的瞳孔可调节大小,对应着光圈;晶状体对应透镜,可通过肌肉的拉扯调节焦距;视网膜进行成像</p>
|
||
<p><img src="../../images/color_and_perception_30.png" alt=""></p>
|
||
<h4 id="视网膜感光细胞">视网膜感光细胞</h4>
|
||
<ul>
|
||
<li>棒状细胞:</li>
|
||
</ul>
|
||
<p>很多(~120 million)感知光的强度,不感知颜色,可得灰度图</p>
|
||
<ul>
|
||
<li>锥形细胞:</li>
|
||
</ul>
|
||
<p>少(~6-7 million),可以用来感知颜色锥形细胞内部分成S、M、L这3种不同的锥形细胞(因为这三种细胞对三种类型的波长的响应各不相同)</p>
|
||
<ol>
|
||
<li>S类型:感知小波长(高频)</li>
|
||
<li>M类型:感知中间波长</li>
|
||
<li>L类型:感知长波长</li>
|
||
</ol>
|
||
<p>三种响应类型的曲线:</p>
|
||
<p><img src="../../images/color_and_perception_31.png" alt=""></p>
|
||
<ul>
|
||
<li>三种细胞的分布和数量有个体差异,下图为12人锥形细胞分布差异</li>
|
||
</ul>
|
||
<p><img src="../../images/color_and_perception_32.png" alt=""></p>
|
||
<h3 id="颜色的三刺激理论">颜色的三刺激理论</h3>
|
||
<h4 id="人体如何利用三种细胞进行感知">人体如何利用三种细胞进行感知</h4>
|
||
<p>已知光在不同波长上的分布(SPD),又知道某一种细胞对于某一个波长的响应是多少。感知的函数就是这2个函数对应的位置相乘积分起来</p>
|
||
<p>三种不同的细胞自然会感应出三种颜色,对应下图的S、M、L</p>
|
||
<p><img src="../../images/color_and_perception_33.png" alt=""></p>
|
||
<p>给定任意类型光线,人眼看到的是上面S、M、L这3个数,而不是光线本身的SPD</p>
|
||
<h4 id="人的视觉系统">人的视觉系统</h4>
|
||
<p>光线的光谱经过人的眼睛,反应到视网膜上,然后被三种不同的细胞感知到形成3个数,这3个数送到人的脑袋中,人就会认为看到了一个什么样的颜色</p>
|
||
<p><img src="../../images/color_and_perception_34.png" alt=""></p>
|
||
<h4 id="同色异谱">同色异谱</h4>
|
||
<ul>
|
||
<li>同色异谱现象</li>
|
||
</ul>
|
||
<p>2种光线具有的光谱不相同,可是被我们看到的结果却是相同的</p>
|
||
<p>不同的信号进来后,通过积分得到3个数是相同的</p>
|
||
<ul>
|
||
<li>颜色匹配</li>
|
||
</ul>
|
||
<p>通过调和不同的光谱,得到某一种颜色,使得这一种颜色和我看到的另外一种颜色一样。并不需要2个光的光谱一样,只需要最后的颜色一样</p>
|
||
<p>下图中光谱的SPD完全不同,但被人感知后可得到三个相同的结果</p>
|
||
<p><img src="../../images/color_and_perception_35.png" alt=""></p>
|
||
<ul>
|
||
<li>应用</li>
|
||
</ul>
|
||
<p>如图,可通过不同调节方式使两个颜色一致来表现显示器上太阳颜色,但混合后光谱可与之前的完全不同</p>
|
||
<p><img src="../../images/color_and_perception_36.png" alt=""></p>
|
||
<h2 id="颜色复制匹配">颜色复制/匹配</h2>
|
||
<h3 id="颜色混合">颜色混合</h3>
|
||
<p>加色系统:</p>
|
||
<p>有几种不同的原色,将各自不同的颜色乘上一个强度,将其混合起来,可以得到一种颜色,用它们各自混合的系数RGB这3个数来表示颜色</p>
|
||
<p>如果RGB的值都调到255会得到白色</p>
|
||
<p>减色系统:</p>
|
||
<p>类似于调和不同颜料会越调越黑</p>
|
||
<p><img src="../../images/color_and_perception_37.png" alt=""></p>
|
||
<h3 id="加色实验">加色实验</h3>
|
||
<ul>
|
||
<li>实验一</li>
|
||
</ul>
|
||
<p>加色系统就可以使用上面的线性组合基本颜色的方式来匹配任何给定的颜色</p>
|
||
<p>如下图,给定任何一个颜色,希望用三种不同颜色混合匹配得到相同颜色</p>
|
||
<p><img src="../../images/color_and_perception_38.png" alt=""></p>
|
||
<p>左侧为给定颜色,右侧为混合颜色,每个颜色存在系数</p>
|
||
<p><img src="../../images/color_and_perception_39.png" alt=""></p>
|
||
<p>即找到三种颜色系数的值混合后得到左边颜色</p>
|
||
<p><img src="../../images/color_and_perception_40.png" alt=""></p>
|
||
<ul>
|
||
<li>实验二</li>
|
||
</ul>
|
||
<p>有时存在左边的颜色右边无法混合得到的情况</p>
|
||
<p><img src="../../images/color_and_perception_41.png" alt=""></p>
|
||
<p>可在左边给定的颜色上加上一个颜色,类似于右边对应减去这个颜色</p>
|
||
<p>多个不同颜色混合得到一个颜色,存在负值可能</p>
|
||
<p><img src="../../images/color_and_perception_42.png" alt=""></p>
|
||
<h4 id="cie-rgb配色实验">CIE RGB配色实验</h4>
|
||
<p>CIE RGB系统开始接近颜色空间的表示</p>
|
||
<p>CIE是一个组织,定义了RGB系统,给定的任何一个颜色是单波长的颜色,光线的SPD是一个单一的函数</p>
|
||
<p>使用三种单色的光</p>
|
||
<p><img src="../../images/color_and_perception_43.png" alt=""></p>
|
||
<h4 id="颜色匹配函数">颜色匹配函数:</h4>
|
||
<ul>
|
||
<li>单波长的目标颜色</li>
|
||
</ul>
|
||
<p>做颜色匹配时,给定一个固定波长,需要将这3个颜色中相同波长的值混合起来</p>
|
||
<p><img src="../../images/color_and_perception_44.png" alt=""></p>
|
||
<ul>
|
||
<li>实际光(多波长)</li>
|
||
</ul>
|
||
<p>给定一个实际光的SPD,要使用积分考虑每一个波长所需要的红、绿、蓝然后混合在一块</p>
|
||
<p>这三个颜色每一个积分出来会得到三个数</p>
|
||
<p><img src="../../images/color_and_perception_45.png" alt=""></p>
|
||
<h3 id="颜色空间">颜色空间</h3>
|
||
<h4 id="standard-color-spaces--standardized-rgb-srgb">Standard Color Spaces : Standardized RGB (sRGB)</h4>
|
||
<p>RGB的标准名为sRGB</p>
|
||
<p>广泛用于各种成像设备</p>
|
||
<p>问题:</p>
|
||
<p>RGB颜色空间的色域有限</p>
|
||
<h4 id="国际颜色空间cie-xyz">国际颜色空间:CIE XYZ</h4>
|
||
<p>CIE XYZ系统人为定义了一个颜色匹配函数,</p>
|
||
<ul>
|
||
<li>绿色曲线分布比较对称,对应的y函数匹配出来的数Y在一定程度上可以表示颜色的亮度</li>
|
||
<li>红色有2个峰值,没有负数,这些函数都分布在可见光的范围内</li>
|
||
</ul>
|
||
<p><img src="../../images/color_and_perception_46.png" alt=""></p>
|
||
<p>二维可视化XYZ</p>
|
||
<p>将X、Y、Z先进行归一化</p>
|
||
<p>$$x = \frac{X}{X+Y+Z}$$</p>
|
||
<p>$$y = \frac{Y}{X+Y+Z}$$</p>
|
||
<p>$$z = \frac{Z}{X+Y+Z}$$</p>
|
||
<p>三个数相加为1,此时只需显示前面2个维度能得到一个什么样的图就可以了</p>
|
||
<p>改变Y即为改变亮度</p>
|
||
<p><img src="../../images/color_and_perception_47.png" alt=""></p>
|
||
<ul>
|
||
<li>色域</li>
|
||
</ul>
|
||
<p>可见图中边界为扇形,这个就是色域,整个颜色空间可以显示的颜色</p>
|
||
<p>色域有一个白色中心,纯色都在边界上</p>
|
||
<p><img src="../../images/color_and_perception_48.png" alt=""></p>
|
||
<p>不同颜色空间表示的颜色范围不一样</p>
|
||
<p>下图sRGB只能表示很小的三角形部分的色域</p>
|
||
<p><img src="../../images/color_and_perception_49.png" alt=""></p>
|
||
<h3 id="perceptually-organized-color-spaces">Perceptually Organized Color Spaces</h3>
|
||
<h4 id="hsv-color-space">HSV Color Space</h4>
|
||
<p>广泛应用于颜色拾取器</p>
|
||
<p>可以选择各种不同的色调(Hue)、饱和度(Saturation)、Brightness(亮度)或Value(值)</p>
|
||
<p>色调:不同类型的颜色</p>
|
||
<p>饱和度:更接近中心白色,还是更接近颜色本身的纯色</p>
|
||
<p>亮度:从黑色一直到某种颜色</p>
|
||
<h4 id="cielab-space">CIELAB Space</h4>
|
||
<p>LAB色彩空间也和感知有关</p>
|
||
<p>L轴表示的是亮度(0为黑,100为白)</p>
|
||
<p>a轴上红和绿分别在两端</p>
|
||
<p>b轴上蓝和黄在两端</p>
|
||
<p>LAB空间认为任何一个轴上两端都是互补色</p>
|
||
<p><img src="../../images/color_and_perception_50.png" alt=""></p>
|
||
<h4 id="互补色理论">互补色理论</h4>
|
||
<p>人脑对互补色存在一个定义</p>
|
||
<ul>
|
||
<li>人眼的视觉暂留来验证互补色</li>
|
||
</ul>
|
||
<p>人眼的视觉暂留就是看一幅图看得时间长了,看到另外一幅图,你会看到第一幅图的互补色</p>
|
||
<h4 id="颜色是相对的">颜色是相对的</h4>
|
||
<p>颜色本身是感知,看到的颜色可能和实际存在出入</p>
|
||
<p>如下图A,你会觉得B比A亮</p>
|
||
<p><img src="../../images/color_and_perception_51.png" alt=""></p>
|
||
<p>挡住A、B以外区域,会发现A和B颜色相同</p>
|
||
<p><img src="../../images/color_and_perception_52.png" alt=""></p>
|
||
<h2 id="减色系统cmyk">减色系统(CMYK)</h2>
|
||
<p>减色系统在生活中应用更广泛</p>
|
||
<p>CMYK:</p>
|
||
<p>Cyan(蓝绿色)、Magenta(品红色)、Yellow(黄色)、Key(黑色)</p>
|
||
<p><img src="../../images/color_and_perception_53.png" alt=""></p>
|
||
<p>C、M、Y可以通过混合得到各种不同的颜色,所以在打印上,可以通过混合各种各样不同墨水调出各种各样不同的颜色</p>
|
||
<p><img src="../../images/color_and_perception_54.png" alt=""></p>
|
||
<p>印刷上要考虑成本,正常情况下打印东西以黑色居多,而且黑色的墨水好制作,便宜,C、M、Y这三种带颜色的墨水不容易制作,那用这三种颜色混合得到黑色,成本就比直接用黑色高,因而需要黑色墨水</p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>相机与透镜</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E7%9B%B8%E6%9C%BA%E4%B8%8E%E9%80%8F%E9%95%9C/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E7%9B%B8%E6%9C%BA%E4%B8%8E%E9%80%8F%E9%95%9C/</guid>
|
||
<pubDate>Fri, 29 Jul 2022 14:39:13 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><p>计算机图形学中有两种成像方法:光栅化成像和光线追踪成像</p>
|
||
<p>这两种方法都是一种合成(Synthesis)的方法,即这个在自然界中不存在,但我们不知可以通过合成方法成像,还可以通过捕捉(capture)方法成像</p>
|
||
<p>$$Image = Synthesis + Capture$$</p>
|
||
<p>当然还有很多种成像方法,最简单的捕捉成像方法是使用相机。当然现在还在研究很多别的更好成像技术(比如:光线的传播其实是有时间的,有一些研究会研究光在极短时间内的传播,就可以看到光线真正在空间中进行传播的过程,这个过程叫Transient image(瞬息图像))</p>
|
||
<p><img src="../../images/image_synthesis_capture.png" alt=""></p>
|
||
<h2 id="相机">相机</h2>
|
||
<p><img src="../../images/inside_the_camera.png" alt=""></p>
|
||
<p>最早的相机起源子小孔成像</p>
|
||
<p>如果中间平面上的一个孔是一个理想的点,那左边所有不同的有反射光的点,通过中间的孔会在另一侧形成和左边的人道理的像,此时在另一侧放一个传感器将其记录在胶片上就可以得到一张相片</p>
|
||
<p>小孔成像对应的相机为针孔相机(pinhole camera)</p>
|
||
<p>生活中常见的则为带透镜的相机</p>
|
||
<p><img src="../../images/lenses_from_image_on_sensor.png" alt=""></p>
|
||
<h3 id="相机部件">相机部件</h3>
|
||
<ul>
|
||
<li>快门(shutter)</li>
|
||
</ul>
|
||
<p>下图为去掉了镜头后的相机快门部分,控制光在多少分之一秒内进入相机</p>
|
||
<p><img src="../../images/Shuntter_exposes_sensor_for_precise_duration.png" alt=""></p>
|
||
<ul>
|
||
<li>传感器</li>
|
||
</ul>
|
||
<p>记录传感器上任何一个点(像素)的Irradiance</p>
|
||
<p><img src="../../images/sensor_accumulates_irradiance_during_exposure.png" alt=""></p>
|
||
<p>如果一个相机没有透镜或针孔是无法拍出照片的,如果将一个感光元件直接放在一个人的面前,任何一个点上都可能收集到来自不同方向的光,而这个点作为传感器无法区分来自各个方向的光线,此时会将各个方向的能量都综合在这个点上,会导致所有东西都是模糊的</p>
|
||
<p><img src="../../images/sensors_without_lenses.png" alt=""></p>
|
||
<p>前沿中存在传感器可通过方向性的光分开记录的研究,但目前依旧认为只能记录Irradiance而非Radianc</p>
|
||
<h3 id="小孔成像过程">小孔成像过程</h3>
|
||
<p>小孔成像现象在公元前就已经被发现和提出</p>
|
||
<p><img src="../../images/pinhole_camera.png" alt=""></p>
|
||
<p>在今天,针孔摄像机拍摄依旧可行,大多数使用的相机都是带有透镜的,</p>
|
||
<p>真正做一个如下图的针孔(硬纸板中间有一个6mm直径能透光的地方),也能用这个小针孔拍摄某个场景,记录在胶片上。但拍出来的东西是没有深度可言的,任何地方都不会是虚的,都一定是清楚的</p>
|
||
<p><img src="../../images/largest_pinhole_photograph.png" alt=""></p>
|
||
<p><img src="../../images/largest_pinhole_photograph1.png" alt=""></p>
|
||
<p>虚化正是来源于透镜。在计算光线追踪是,我们使用的就是针孔摄像机的模型,所以也得不出不同的地方会有不同的模糊</p>
|
||
<h3 id="视场field-of-viewfov">视场(Field of View)(FOV)</h3>
|
||
<p>视场往往意味着能够看到多大的范围,对于广角镜头,通常意味着能够拍到更广的角度,可见的FOV更大,对于手机上的相机,视场就相对比较小</p>
|
||
<p><img src="../../images/effect_of_focal_length_on_fov.png" alt=""></p>
|
||
<h4 id="从小孔成像的针孔摄像机理解视场">从小孔成像的针孔摄像机理解视场</h4>
|
||
<p>通过上图的相似三角形关系,如果分别从传感器的两个边缘和小孔连一条线,那么两条线中的区域都是可视范围</p>
|
||
<ol>
|
||
<li>传感器的高度认为是h</li>
|
||
<li>传感器和小孔之间的距离(焦距,小孔成像中不存在此概念)是f</li>
|
||
<li>通过平分FOV可计算得出</li>
|
||
</ol>
|
||
<p>$$FOV = 2\arctan(\frac{h}{2f})$$</p>
|
||
<p>将传感器放置在离小孔更近的地方会使f变小,FOV变大,这样就可以通过内部设计推断视场有多大</p>
|
||
<h4 id="焦距focal-length和视场">焦距(focal length)和视场</h4>
|
||
<h5 id="通过定义焦距的方式来定义视场">通过定义焦距的方式来定义视场</h5>
|
||
<p>不同视场决定不同拍照结果。视场和传感器大小及焦距相关,所以人们通常定义视场(FOV)以35mm格式的胶片为基准,固定传感器的大小,再通过定义焦距的方式来定义FOV</p>
|
||
<p><img src="../../images/focal_length_vs_filed_of_view1.png" alt=""></p>
|
||
<h5 id="单反镜头的焦距">单反镜头的焦距</h5>
|
||
<p>购买单反镜头时会有不同的焦距参数的原因正是视场不同</p>
|
||
<ul>
|
||
<li>17mm is wide angle 104$^\circ$</li>
|
||
<li>50mm is a &quot;normal&quot; lens 47$^\circ$</li>
|
||
<li>200mm is telephoto lens 12$^\circ$</li>
|
||
</ul>
|
||
<h5 id="手机相机的焦距">手机相机的焦距</h5>
|
||
<p>对于手机相机,其传感器很小,所以对应的焦距也小很多,手机上显示的焦距往往只是一个等效的概念</p>
|
||
<h5 id="不同视场的效果">不同视场的效果</h5>
|
||
<p>当视场越窄,看到的东西越远</p>
|
||
<p><img src="../../images/focle_length_vs_field_of_view2.png" alt=""></p>
|
||
<h4 id="传感器sensor大小和视场fov">传感器(Sensor)大小和视场(FOV)</h4>
|
||
<p>小一点的传感器会对应小一点的视场</p>
|
||
<p><img src="../../images/effect_of_sensor_size_on_fov.png" alt=""></p>
|
||
<h5 id="传感器与胶片">传感器与胶片</h5>
|
||
<p>传感器与胶片这两个概念不一样,平常往往认为是一回事,认为传感器上各个不同的点会对应写到对应的位置上去,存在一个一一对应的关系。我们认为传感器接收到的图像就是最后成像出来的图像。对于渲染器而言,传感器负责记录每个像素最后收到的Irradiance有多大,胶片用于决定应存储的图片格式</p>
|
||
<h5 id="传感器大小">传感器大小</h5>
|
||
<p>大相机有大的传感器也就有大的分辨率,所以不同相机价格各不相同,相机机身越大,镜头越大越长越好,价格也就越高</p>
|
||
<p><img src="../../images/sensor_size.png" alt=""></p>
|
||
<h4 id="曝光">曝光</h4>
|
||
<p>理解:</p>
|
||
<p>如果对明亮场景拍照,得到的结果会亮一些,如果对着一个比较暗的场景,但快门按下的时间长即曝光时间长,也可以得到一个比较亮的照片。因此通过进来多少光和让光进来多长时间,进行累积就可以得到曝光度</p>
|
||
<p>在辐射度量学上,单位时间内有光打到一个表面,单位时间内又辐射出去,就只需要考虑单位时间,但照相是考虑整体时间</p>
|
||
<ol>
|
||
<li>曝光时间(T)由快门控制</li>
|
||
<li>Irradiance(E)指传感器单位面积接收的光能</li>
|
||
<li>H = T $\times$ E</li>
|
||
</ol>
|
||
<p>Irradiance往往由光圈大小(影响镜头接收到多少光)和焦距决定</p>
|
||
<h4 id="影响照片亮度的因素">影响照片亮度的因素</h4>
|
||
<ul>
|
||
<li>光圈的大小</li>
|
||
</ul>
|
||
<p>相机为精密仪器,可控制光圈大小,最大可开到镜头一样大,由f-stop控制。实际上是仿生学设计,模仿人的瞳孔的动态大小调节功能</p>
|
||
<ul>
|
||
<li>快门速度</li>
|
||
</ul>
|
||
<p>快门速度越快,开放时间越短,更少的光进入</p>
|
||
<ul>
|
||
<li>ISO增益/感光度(ISO gain)</li>
|
||
</ul>
|
||
<p>可简单理解为后期处理,当感光元件感知到某个层级的光后利用ISO后期乘上一个数值(可发生在不同的地方,可发生在硬件,调节传感器灵敏度,还可以生成照片的数字信号上进行调节)</p>
|
||
<h4 id="各因素不同的配置">各因素不同的配置</h4>
|
||
<ul>
|
||
<li>下图第一行参数中用F数表示光圈大小,黑色为遮挡物,白色为光圈大小,F数越大,光圈越小(点号写成逗号为欧洲写法)</li>
|
||
<li>第二行参数使用分数表示快门速度(1/1000即为快门开放1/1000秒)</li>
|
||
<li>第三行参数是ISO,不同ISO可简单理解为相乘</li>
|
||
</ul>
|
||
<p><img src="../../images/exposure_aperture_shutter_gain.png" alt=""></p>
|
||
<h4 id="iso简单地放大信号会放大噪声">ISO简单地放大信号会放大噪声</h4>
|
||
<p>任何一个信号肯定会产生噪声,对整个信号去乘以一个很大的数,在放大信号的同时也会放大噪声,这也是在很暗的环境中使用很小的光圈和快门时间会拍出来一张很暗的图</p>
|
||
<p>正常情况下,都不会通过调ISO的方式来得到一个更亮的图,在小范围内调整无误但调得特别大后一定会出现噪声问题</p>
|
||
<p>产生噪声的原因:</p>
|
||
<p>将光认为是光子,如果快门时间不足,那么进入感光元件的光子数就少,光子数少就会造成noisy</p>
|
||
<p><img src="../../images/ISO_gain_vs_noise_in_canon.png" alt=""></p>
|
||
<h4 id="光圈与f数">光圈与F数</h4>
|
||
<ul>
|
||
<li>
|
||
<p>描述光圈大小常用F-Number</p>
|
||
</li>
|
||
<li>
|
||
<p>F数有两种写法:FN(F后接一个数字)或F/N</p>
|
||
</li>
|
||
<li>
|
||
<p>F数的非正式理解:光圈的直径的逆,即$\frac{1}{直径}$</p>
|
||
</li>
|
||
<li>
|
||
<p>如图,调光圈可以直接调出曝光度</p>
|
||
</li>
|
||
</ul>
|
||
<p><img src="../../images/F-Number_exposure_levels.png" alt=""></p>
|
||
<h4 id="快门曝光时间对结果的影响">快门曝光时间对结果的影响</h4>
|
||
<p>快门</p>
|
||
<p><img src="../../images/physical_shutter.png" alt=""></p>
|
||
<ul>
|
||
<li>
|
||
<p>调节曝光度</p>
|
||
</li>
|
||
<li>
|
||
<p>产生运动模糊(motion blur)</p>
|
||
</li>
|
||
</ul>
|
||
<p>常出现在高速运动的物体上,在快门打开的期间物体发生了运动,就意味着在快门开合过程中会记录物体的一段移动,传感器由起到平均作用,所以表现为模糊</p>
|
||
<p>更长的快门时间会造成更严重的运动模糊,对于等长的快门时间,物体运动越快,越容易出现运动模糊</p>
|
||
<p><img src="../../images/side_effect_of_shutter_speed1.png" alt=""></p>
|
||
<p>但是更短的快门时间,曝光度也降低了,所以为了达到相同的亮度,就要调节ISO或光圈的大小</p>
|
||
<p><img src="../../images/side_effect_of_shutter_speed2.png" alt=""></p>
|
||
<p>运动模糊的好处</p>
|
||
<ol>
|
||
<li>没有运动模糊会从人的感知上觉得赛车非常慢</li>
|
||
<li>对于运动的物体,一帧的拍摄相当于在不同的时间对物体所在的位置进行了一个采样,如果有运动模糊,就相当于做了一个反走样</li>
|
||
</ol>
|
||
<p>rolling shutter问题</p>
|
||
<p>电子控制的快门可以认为是任何时刻任何位置同步打开,但机械快门则需要一个过程,如果物体运动比机械快门的速度快就会出现Rolling Shutter问题,因为图像上不同位置可能记录的是不同时间进来的光</p>
|
||
<p><img src="../../images/side_effect_of_shutter_speed.png" alt=""></p>
|
||
<h4 id="均衡快门和光圈">均衡快门和光圈</h4>
|
||
<p>快门的时间打开得短就会暗,那就可以提高光圈的大小,用更小的F数。以下的表格上下对应的参数基本可以达到相同的曝光度。但达到的效果并不会一模一样(因为大光圈会引起前景深的问题,快门时间又会引起运动模糊)</p>
|
||
<p><img src="../../images/f-stop_vs_shutter_speed.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="快速或长曝光摄影">快速或长曝光摄影</h3>
|
||
<h4 id="快速摄影">快速摄影</h4>
|
||
<p>每秒拍摄更多帧数然后按正常帧数播放,每张照片的快门时间非常少又需要保证每张都清晰且有正常的曝光度,可以用更大的光圈和更高ISO</p>
|
||
<p><img src="../../images/hight-speed_photography1.png" alt=""></p>
|
||
<h4 id="超低速长曝光摄影">超低速(长曝光)摄影</h4>
|
||
<p>用非常小的光圈慢慢拍,也就是所谓的延迟摄影,摄影界中称为拉丝,也就是长曝光造成的运动模糊</p>
|
||
<p><img src="../../images/long-exposure_photography1.png" alt=""></p>
|
||
<p><img src="../../images/long-exposure_photography2.png" alt=""></p>
|
||
<p><img src="../../images/long-exposure_photography3.png" alt=""></p>
|
||
<h2 id="镜头">镜头</h2>
|
||
<h3 id="thin-lens-approximation">Thin Lens Approximation</h3>
|
||
<ul>
|
||
<li>真正的镜头设计是高度复杂的</li>
|
||
</ul>
|
||
<p>无论相机还是手机,都不使用单个透镜来成像,往往使用一个透镜组</p>
|
||
<p><img src="../../images/real_lens_dfsigns_are_comples.png" alt=""></p>
|
||
<ul>
|
||
<li>真正的镜头元素是不理想的</li>
|
||
</ul>
|
||
<p>如下图,一面是凸的,一面是平的,这样就不可能将光聚在一起</p>
|
||
<p><img src="../../images/real_lens_elements_are_not_ideal.png" alt=""></p>
|
||
<ul>
|
||
<li>我们研究的是理想的薄透镜(忽略厚度)</li>
|
||
</ul>
|
||
<p>理想透镜:</p>
|
||
<ol>
|
||
<li>对于平行于透镜的光如果打进来会被集中到一个点上(焦点),定义焦距是焦点到透镜中心的距离</li>
|
||
<li>光路有可逆性,如果光线穿过焦点,被透镜折射后会变成平行的一束光</li>
|
||
<li>假设薄透镜可以任意改变焦距(透镜焦距固定,相机能改是因为透镜组)</li>
|
||
</ol>
|
||
<p><img src="../../images/ideal_thin_lens_focal_point.png" alt=""></p>
|
||
<ul>
|
||
<li>透镜满足的物理规律</li>
|
||
</ul>
|
||
<ol>
|
||
<li>平行光会被折射成过焦点,以及过焦点的光会被变成平行光出去</li>
|
||
<li>任何一个透镜可以假设任何一条光穿过透镜中心,它的方向不会发生改变</li>
|
||
<li>对于固定焦距的透镜,如果改变像距,物距一定跟着改变</li>
|
||
</ol>
|
||
<ul>
|
||
<li>薄透镜公式(Gauss's Ray Tracing Construction/Gaussian Thin Lens Equation)</li>
|
||
</ul>
|
||
<p>如下图,左侧物体会经过透镜成像到右侧去,可定义一些参数</p>
|
||
<p>定义物距(物体到透镜的垂直距离):$Z_o$</p>
|
||
<p>定义像距(成的像到透镜的垂直距离):$Z_i$</p>
|
||
<p>透镜的焦距f</p>
|
||
<p>$$\frac{1}{f} = \frac{1}{z_i}+\frac{1}{z_o}$$</p>
|
||
<p>推导过程</p>
|
||
<p>平行光必定过焦点,过焦点的光会变成平行光</p>
|
||
<p><img src="../../images/gauss_ray_diagrams.png" alt=""></p>
|
||
<p>忽略中间过透镜中心的光</p>
|
||
<p><img src="../../images/gauss_ray_tracing_construction.png" alt=""></p>
|
||
<p>可见如下图的几何关系,左侧在光到达透镜前可形成两个相似三角形,右侧也相同</p>
|
||
<p><img src="../../images/gauss_ray_tracing_construction1.png" alt=""></p>
|
||
<p>将两组关系做运算</p>
|
||
<p><img src="../../images/gauss_ray_tracing_construction2.png" alt=""></p>
|
||
<h3 id="散焦模糊defocus-blur景深">散焦模糊(Defocus Blur)(景深)</h3>
|
||
<h4 id="弥散圆circle-of-confusion">弥散圆(Circle of Confusion)</h4>
|
||
<p>出于解释模糊,我们引入CoC的概念</p>
|
||
<p>如图左边远处有一个平面(Focal Plane),所有的光经过透镜后都会被聚焦到右边一个平面上(Image)</p>
|
||
<ul>
|
||
<li>如果物体不在Focal Plane上会出现模糊</li>
|
||
</ul>
|
||
<p><img src="../../images/computing_circle_of_confusion_size.png" alt=""></p>
|
||
<ul>
|
||
<li>模糊原因</li>
|
||
</ul>
|
||
<p>任何地方有一个点,它穿过透镜后,可以根据上面透镜的公式算出像距,但是如果成像平面不在这个地方,而是离得有一段距离,光线就会在原本成像的地方之后继续传播,那被感光元件接收到的时候就不再是一个点了,而是变成了一个圆(CoC)</p>
|
||
<ul>
|
||
<li>CoC大小计算</li>
|
||
</ul>
|
||
<p>与Aperture的大小相关</p>
|
||
<p>CoC的直径/Aperture的直径 = $d'/Z_i$</p>
|
||
<p>$$\frac{C}{A} = \frac{d'}{z_i} = \frac{|z_s - z_i|}{z_i}$$</p>
|
||
<p>可见CoC的大小和透镜本身的大小成正比</p>
|
||
<ul>
|
||
<li>物体是否模糊取决于光圈的大小</li>
|
||
</ul>
|
||
<p>下图光圈f数为1.4,为大光圈,可以看到更模糊的效果</p>
|
||
<p><img src="../../images/coc_vs_aperture_size.png" alt=""></p>
|
||
<h4 id="光圈大小">光圈大小</h4>
|
||
<p>之前的光圈定义实际不准确,F数拥有明确定义</p>
|
||
<ul>
|
||
<li>F数定义</li>
|
||
</ul>
|
||
<p>焦距/光圈直径</p>
|
||
<p>$$N = f/A$$</p>
|
||
<ul>
|
||
<li>常见F数</li>
|
||
</ul>
|
||
<p>1.4,2,2.8,4.0,5.6,8,11,16,22,32</p>
|
||
<ul>
|
||
<li>写法</li>
|
||
</ul>
|
||
<p>常写为f/数字</p>
|
||
<ul>
|
||
<li>例子</li>
|
||
</ul>
|
||
<p><img src="../../images/example_f-stop_caculations.png" alt=""></p>
|
||
<ul>
|
||
<li>CoC的大小和F数成反比</li>
|
||
</ul>
|
||
<p><img src="../../images/size_of_coc_is_inversely_proportional_to_f-stop.png" alt=""></p>
|
||
<p>$$C = A\frac{|z_s - z_i|}{z_i} = \frac{f}{N}\frac{|z_s - z_i|}{z_i}$$</p>
|
||
<h3 id="光线追踪理想的薄透镜ray-tracing-ideal-thin-lenses">光线追踪理想的薄透镜(Ray Tracing Ideal Thin Lenses)</h3>
|
||
<p>之前Ray Tracing和Path Tracing都是从相机往任何一个像素中心连线,默认是小孔成像的针孔摄像机的模型</p>
|
||
<p>但是我们可以模拟薄透镜,给它一个焦距,可以将Sensor放置到离镜头有多远,然后实际去做光线追踪</p>
|
||
<ul>
|
||
<li>实例</li>
|
||
</ul>
|
||
<p><img src="../../images/eg_of_rendering_with_lens_focus.png" alt=""></p>
|
||
<h4 id="具体实现">具体实现</h4>
|
||
<ul>
|
||
<li>定义场景</li>
|
||
</ul>
|
||
<p>确定sensor大小,定义透镜焦距,光圈大小</p>
|
||
<p>定义透镜和某个平面的距离$Z_o$</p>
|
||
<p>根据物距$Z_o$和焦距,可计算像距$Z_i$</p>
|
||
<p><img src="../../images/ray_tracing_for_defocus_blur.png" alt=""></p>
|
||
<ul>
|
||
<li>使用光线追踪算法渲染</li>
|
||
</ul>
|
||
<p>找一些光线能够穿过透镜,打到场景中</p>
|
||
<p>在成像平面(感光元件,胶片)上选一些点X'</p>
|
||
<p>在透镜上另选X&quot;,两点连线便可知道其方向,且感光元件上的X'处会记录这条线上的Radiance</p>
|
||
<p><img src="../../images/ray_tracing_for_defocus_blur1.png" alt=""></p>
|
||
<ul>
|
||
<li>景深(Depth of Field)</li>
|
||
</ul>
|
||
<p>如下两图,一个用大光圈,一个用小光圈</p>
|
||
<p>过大的光圈对应大的CoC,一个点会变成更大的圆,所以就会更模糊,但总归在一些地方是不模糊的,即不同光圈大小会影响模糊范围</p>
|
||
<p><img src="../../images/depth_of_field.png" alt=""></p>
|
||
<p>如下图中,一个光经透镜会打到一个成像平面,该成像平面附近区域都认为CoC足够小</p>
|
||
<p><img src="../../images/circle_of_confusion_for_depth_of_field.png" alt=""></p>
|
||
<p>景深:实际场景中有一段深度,该深度经透镜后会在成像平面附近形成一段区域,区域内认为CoC是足够小的</p>
|
||
<p>因此计算景深就是计算CoC在这个很小的一段范围内,认为对应场景是清晰的</p>
|
||
<p>可简单认为成像平面中的许多像素不是一个点,存在各自的大小,CoC的大小和像素大小差不多或比像素小,都可认为结果是锐利的</p>
|
||
<p>计算DOF</p>
|
||
<p>如下图,考虑景深的最远和最近处,分别让它们穿过透镜,到某一地方可以得到右边的范围</p>
|
||
<p><img src="../../images/depth_of_filed_fyi.png" alt=""></p>
|
||
<p>DOF参数效果</p>
|
||
<p><img src="../../images/DOF_demonstration_fyi.png" alt=""></p>
|
||
<ul>
|
||
<li>修改焦距</li>
|
||
</ul>
|
||
<p>焦距越大,DOF越浅,只有焦点上的成像是清晰的,焦点之前的清晰范围叫前景深,之后的叫后景深</p>
|
||
<ul>
|
||
<li>改变F数</li>
|
||
</ul>
|
||
<p>光圈越小,景深越大,光圈越小意味着越接近小孔,DOF清晰的范围越大</p>
|
||
<ul>
|
||
<li>调CoC</li>
|
||
</ul>
|
||
<p>更大的CoC对应的景深就更深</p>
|
||
<p>F-stop可简单理解为光圈大小又是透镜大小,本质是遮挡透镜,动态改变透镜大小</p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>高级光线传播与复杂外观建模</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E9%AB%98%E7%BA%A7%E5%85%89%E7%BA%BF%E4%BC%A0%E6%92%AD%E4%B8%8E%E5%A4%8D%E6%9D%82%E5%A4%96%E8%A7%82%E5%BB%BA%E6%A8%A1/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E9%AB%98%E7%BA%A7%E5%85%89%E7%BA%BF%E4%BC%A0%E6%92%AD%E4%B8%8E%E5%A4%8D%E6%9D%82%E5%A4%96%E8%A7%82%E5%BB%BA%E6%A8%A1/</guid>
|
||
<pubDate>Wed, 27 Jul 2022 22:55:53 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h2 id="无偏的光线传播方法unbiased-light-transport-methods">无偏的光线传播方法(Unbiased light transport methods)</h2>
|
||
<h3 id="双向路径追踪bidirectional-path-tracing">双向路径追踪(Bidirectional Path Tracing)</h3>
|
||
<p>双向路径追踪是对之前路径追踪的扩展,生成两个子路径</p>
|
||
<p>从光源打出一些sub-path,从摄像机出发也可以生成另外一系列的子路径。双向路径追踪会将这些子路径的端点连接起来形成一条完整的路径</p>
|
||
<p><img src="../../images/bidirectional_path_tracing_theory.png" alt=""></p>
|
||
<h3 id="bdpt适用的场景">BDPT适用的场景</h3>
|
||
<p>图例中,左图为路径追踪,右图为双向路径追踪,适用的都是每个像素32个采样点,但可见双向路径追踪能产生更好的效果</p>
|
||
<p><img src="../../images/eg_bidirectional_path_tracing.png" alt=""></p>
|
||
<p>原因:</p>
|
||
<p>在如图场景中,光线追踪难以找到一条带有大量能量的路径。此场景中光源往上方角落打出,整个场景都是被间接光所照亮的,此时光线从摄像机出发后第一次打到的地方往往是diffuse的,导致其不好控制它打到之后能量集中的区域</p>
|
||
<p>缺点:</p>
|
||
<p>实现较难,相对计算速度慢</p>
|
||
<h3 id="metropolis-light-transportmlt">Metropolis Light Transport(MLT)</h3>
|
||
<p>使用统计学上采样的工具--- 马尔可夫链(当前有一个样本,马尔可夫链可以根据当前样本生成和它靠近的下一个样本,并用这些样本估计函数的值)</p>
|
||
<p>与均匀采样不同,均匀采样时在a和b之间以均等概率选择一个x,且相互独立</p>
|
||
<p>给定足够的时间,马尔可夫链的蒙特卡洛方法可以生成一系列以任意的函数形状为PDF生成的样本</p>
|
||
<h4 id="使用马尔可夫方法的原因">使用马尔可夫方法的原因</h4>
|
||
<p>蒙特卡洛方法实际上在采样的PDF(p(x))和要积分的函数(f(x))形状一致的时候是最合适的,此时variance是最小的</p>
|
||
<p>任何未知的函数都可以通过马尔可夫链的方法生成一系列分布和被积函数形状一致的样本</p>
|
||
<h5 id="马尔可夫方法具有局部性">马尔可夫方法具有局部性</h5>
|
||
<p>马尔可夫方法是一个局部的方法,当给出一个路径时,可以生成它周围跟它相似的路径</p>
|
||
<p>如图中蓝色光路,对该光路做出微笑扰动就可以得到一条新路径</p>
|
||
<p>不断在一个path周围产生更多path就可以找到所有的path</p>
|
||
<p><img src="../../images/MLT_caculate.png" alt=""></p>
|
||
<h4 id="mlt方法与bdpt的效果对比">MLT方法与BDPT的效果对比</h4>
|
||
<ul>
|
||
<li>优点</li>
|
||
</ul>
|
||
<p>在下图中类似的场景下MLT的效果很好,其适合做复杂、困难的光线传播</p>
|
||
<p><img src="../../images/MLT_pros.png" alt=""></p>
|
||
<p>Caustics是光线经过聚焦打在游泳池底,然后被人眼看见。光线要穿过水的表面(凹凸不平,还有浪),会被聚焦到一系列的地方(水面有办法将光线聚焦到一系列的线上)。这种情况渲染起来非常困难,因为假设游泳池底是diffuse的,光线会先经过一个specular的水面,游泳池底被我们看见也要经过一个specular(这种路径简称SDS(specular-diffuse-specular))</p>
|
||
<ul>
|
||
<li>缺点</li>
|
||
</ul>
|
||
<p>MLT难以在理论上预估最后收敛的速度(path tracing中使用的蒙特卡洛积分可以分析variance,从而预估渲染收敛的时间)</p>
|
||
<p>所有操作都是局部的,有些像素收敛快,有的像素收敛慢,使渲染出来的结果图像看上去比较脏</p>
|
||
<p><img src="../../images/MLT_cons.png" alt=""></p>
|
||
<p>不适用于渲染动画,因为不同连续帧的收敛速度不同,画面会产生严重抖动</p>
|
||
<hr>
|
||
<h2 id="有偏的光线传播方法biased-light-transport-methods">有偏的光线传播方法(biased light transport methods)</h2>
|
||
<h3 id="光子映射photon-mapping">光子映射(Photon Mapping)</h3>
|
||
<p>尤其适用于渲染Caustics和Specular-Diffuse-Specular(SDS)</p>
|
||
<p><img src="../../images/photon_mapping_theory.png" alt=""></p>
|
||
<h4 id="实现方法">实现方法</h4>
|
||
<ul>
|
||
<li>从光源出发,光子碰到物体后计算所有反射和折射,直到光子打到diffuse的物体上停止,此时整理所有光子即可得到光子位置信息</li>
|
||
</ul>
|
||
<p><img src="../../images/photon_mapping_approach.png" alt=""></p>
|
||
<ul>
|
||
<li>
|
||
<p>从眼睛或相机开始,往各个不同方向打出各种各样的子路径,计算反射和折射直到打在diffuse的物体上</p>
|
||
</li>
|
||
<li>
|
||
<p>结合上述两步结果计算局部密度估计</p>
|
||
</li>
|
||
</ul>
|
||
<p>局部密度估计是建立在上面的观察上的,一开始打了很多光子,光子分布在物体表面了,从相机出发的一堆光线也打到物体表面上了,那我们看到的物体表面,光子分布越集中的地方就越亮,越不集中就越不亮,当第二趟打到各种不同的物体表面的时候就要做一个局部的密度估计</p>
|
||
<p>具体解法:</p>
|
||
<ul>
|
||
<li>将所有的光子组织成自上而下的加速结构模式,然后可以迅速定位到一个着色点周围有多少个光子,找它最近的一些</li>
|
||
<li>计算N个光子所占的面的面积</li>
|
||
<li>计算密度:用光子的数量N除以它们占的面积</li>
|
||
</ul>
|
||
<p><img src="../../images/photon_mapping_cacul.png" alt=""></p>
|
||
<h4 id="n的取值">N的取值</h4>
|
||
<p>如果用很少的光子的数量,就会得到一个很有噪声的图,如果用更多的光子,结果虽然会好一些,但是得到的结果会糊</p>
|
||
<p><img src="../../images/photon_mapping_biased.png" alt=""></p>
|
||
<h5 id="产生取值问题的原因有偏的原因">产生取值问题的原因(有偏的原因)</h5>
|
||
<ul>
|
||
<li>计算密度时,我们认为密度时当前这个点的周围取一个微小的面积dA,它里面有多少个光子</li>
|
||
</ul>
|
||
<p>$$dN/dA$$</p>
|
||
<ul>
|
||
<li>实际计算密度为给定光子数计算实际面积</li>
|
||
</ul>
|
||
<p>$$\delta N/\delta A$$</p>
|
||
<ul>
|
||
<li>正常情况下两者接近但不同(光子数量和周围覆盖面积都是有限的)</li>
|
||
</ul>
|
||
<p>$$dN/dA != \delta N/\delta A $$</p>
|
||
<p>因此密度的估计并不正确,dA无限小时才是正确的计算</p>
|
||
<p>当实际的面积足够小(打出的光子数量足够多),结果就越接近于正确</p>
|
||
<p>所以该方法是有偏(biased)但一致(consistent)的</p>
|
||
<p>有偏(biased):得到的结果相比正确的结果只要有任何一点的模糊(blurry),就是有偏的</p>
|
||
<p>一致(consistent):虽然有模糊,但是只要样本足够多,就会最后让它收敛到不模糊的结果</p>
|
||
<h3 id="vertex-connection-and-mergingvcm">Vertex Connection and Merging(VCM)</h3>
|
||
<p>双向路径追踪和光子映射的结合</p>
|
||
<p>BDPT中,生成两个sub-path再将端点连起来,如果有的path满足下述性质就用光子映射将虚线圆内的两个sub-path的贡献结合在一起</p>
|
||
<p>性质:左边path和右边path的端点在同一个面上,此时可认为其中一半是光子</p>
|
||
<p>往往用于电影行业渲染</p>
|
||
<p><img src="../../images/vertex_connection_and_merging.png" alt=""></p>
|
||
<h3 id="实时辐射度算法instant-radiosityir">实时辐射度算法(Instant Radiosity(IR))</h3>
|
||
<p>有时又称为多光源算法(many-light approaches)</p>
|
||
<p>之前的光线传播往往不区分光的来源(反射或自己发出),实时辐射度算法中就将已经被照亮的区域认为是光源,用于照亮其他区域</p>
|
||
<h4 id="计算方法">计算方法</h4>
|
||
<ul>
|
||
<li>
|
||
<p>从光源打出很多光线子路径(light sub-path),这些光会停在某些地方,认为停的位置就变成了新的光源(VPL)</p>
|
||
</li>
|
||
<li>
|
||
<p>看到如下图中的着色点后就用新的光源来照亮(相当于实际考虑光线弹射两次)</p>
|
||
</li>
|
||
</ul>
|
||
<p><img src="../../images/instant_radiosity.png" alt=""></p>
|
||
<h4 id="优缺点">优缺点</h4>
|
||
<ul>
|
||
<li>优点(下图左)</li>
|
||
</ul>
|
||
<p>快速,往往会在漫反射场景中有良好的效果</p>
|
||
<ul>
|
||
<li>缺点(下图右)</li>
|
||
</ul>
|
||
<p>在窄的缝隙或接缝处会出现发光</p>
|
||
<p>VPL不能做glossy的物体</p>
|
||
<p>窄缝发光问题与距离平方向有关,在计算light sampling时,更改立体角的采样为对面积的采样,所以产生了面积乘以cos除以两个点之间的距离的值,当两个点距离极近时就会得到一个非常大的结果</p>
|
||
<p><img src="../../images/instant_radiosity_eg.png" alt=""></p>
|
||
<h2 id="高级外观建模">高级外观建模</h2>
|
||
<h3 id="散射介质参与介质participating-media">散射介质/参与介质(participating media)</h3>
|
||
<p>定义在空间中而非简单的表面上,如:</p>
|
||
<p>雾</p>
|
||
<p><img src="../../images/participating_media_fog.png" alt=""></p>
|
||
<p>云</p>
|
||
<p><img src="../../images/participating_media_cloud.png" alt=""></p>
|
||
<hr>
|
||
<p>光在前进的路径上如果穿进了散射介质则会发生散射和吸收</p>
|
||
<ol>
|
||
<li>如云中间有光源则其本身会发光</li>
|
||
<li>光线路径上如果有很多小的晶体则会把光线随机反射到其他方向上去</li>
|
||
<li>传播的过程中也可能会接收到从其他方向反射过来的光</li>
|
||
</ol>
|
||
<p><img src="../../images/participating_media1.png" alt=""></p>
|
||
<h4 id="散射计算">散射计算</h4>
|
||
<p>类比与物体表面,物体为diffuse的才会认为光线被均匀地反射到各个不同的方向上去,散射介质也是相同,任何一点都会发生散射,使用Phase Function(相位函数)定义散射计算</p>
|
||
<p>下图相位函数决定了散射的方式和方向(与BRDF类似,BRDF决定如何反射,相位函数决定如何散射)</p>
|
||
<p><img src="../../images/participating_media2.png" alt=""></p>
|
||
<h4 id="散射介质渲染">散射介质渲染</h4>
|
||
<p>光线在散射介质内部能传播多远是有这个介质的吸收能力决定,当传播停止后再考虑光线的反射方向,与光在物体表面的弹射类似,只是中间的任何一个点都有可能会发生方向的改变。但始终会找到一个path,在将弹射点和光源相连,计算整个路径的贡献(不考虑Rendering equation,因为渲染方程描述物体表面与物体的作用而非体积间的相互作用)</p>
|
||
<h4 id="应用">应用</h4>
|
||
<p>超能特工队</p>
|
||
<p><img src="../../images/participating_media_application1.png" alt=""></p>
|
||
<p>游戏:刺客信条</p>
|
||
<p><img src="../../images/participating_media_application2.png" alt=""></p>
|
||
<p>巧克力(流体模拟)</p>
|
||
<p><img src="../../images/participating_media_demo.png" alt=""></p>
|
||
<h3 id="毛发建模hairfurfiber缩写bcsdf">毛发建模(Hair/fur/fiber)缩写:BCSDF</h3>
|
||
<p>如下图中所示,头发往往是一根一根的,若梳理平整还可暂且视为表面,但大多数情况下,头发都是飘散的</p>
|
||
<p>可见头发会有两种高光,一种无色发白,一种有色</p>
|
||
<p><img src="../../images/hair_appearance.png" alt=""></p>
|
||
<h4 id="高光计算">高光计算</h4>
|
||
<p>如下图中的模型,一根光线打到圆柱上(毛发模型)会散射出一个圆柱,且同时有光线散射到各个方向上</p>
|
||
<ul>
|
||
<li>kajiya-Kay Model</li>
|
||
</ul>
|
||
<p><img src="../../images/kajiya-kay_model.png" alt=""></p>
|
||
<p>但表现却不太符合现实,与Blinn-Phong类似</p>
|
||
<p><img src="../../images/eg_kajiya-kay_model.png" alt=""></p>
|
||
<ul>
|
||
<li>Marschner Model</li>
|
||
</ul>
|
||
<p>该模型广泛使用,考虑了光线打到圆柱上的情形</p>
|
||
<ol>
|
||
<li>有部分光被反射,记为R</li>
|
||
<li>一部分会穿透到头发里发生折射,可记为T,一根光线要穿透一根头发需要穿透两次,因而产生TT的光线传播方式</li>
|
||
<li>光线发生一次穿透进入头发内部,在头发内壁上发生一次反射后返回,返回时再发生一次穿透,记为TRT</li>
|
||
</ol>
|
||
<p><img src="../../images/marschner_model1.png" alt=""></p>
|
||
<p>在这一模型中(下图左),我们会将头发认为是一个玻璃的圆柱(总体可认为是扭曲,但局部必定是直的),包含两种结构,外层cuticle(表层),内层cortex(皮层)</p>
|
||
<p>头发内部存在有色素,光线穿透后会有部分被吸收再向外传播</p>
|
||
<p><img src="../../images/marschner_model2.png" alt=""></p>
|
||
<p>该模型也考虑了三种光线和模型之间的相互作用(上图右)</p>
|
||
<p>将计算结果综合后可得到一个十分拟真的效果</p>
|
||
<p><img src="../../images/eg_marschner_model.png" alt=""></p>
|
||
<p>当然上述过程只定义了单根头发与光线的相互作用,与多根头发作用时需要额外计算多次散射</p>
|
||
<p>多次散射:光线打到一根头发穿透两次再和第二根,第三根$\dotsb$直到光线进入摄像机(被看见),计算量庞大</p>
|
||
<p>应用:</p>
|
||
<p>最终幻想15(ff15)</p>
|
||
<p><img src="../../images/hair_appearance_model_application1.png" alt=""></p>
|
||
<p>疯狂动物城</p>
|
||
<p><img src="../../images/hair_appearance_model_application2.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="动物毛发的计算">动物毛发的计算</h3>
|
||
<p>人的毛发计算模型往往不能用于动物毛发计算,如下图,左侧为人的毛发模型计算结果,可见其不足以描述光线与动物毛发的相互作用</p>
|
||
<p><img src="../../images/fur_appearance_as_human_fur.png" alt=""></p>
|
||
<ul>
|
||
<li>生物结构</li>
|
||
</ul>
|
||
<p>人的毛发与动物毛发的共同点:</p>
|
||
<p>都有三个结构,cuticle(表皮)、cotex(皮层)、Medulla(髓质,复杂内部结构,光线进入后会反射到各个方向)</p>
|
||
<p>不同点:</p>
|
||
<p>动物毛发中的髓质更大,光线进入后更容易发生反射</p>
|
||
<p><img src="../../images/human_fur_vs_animal_fur.png" alt=""></p>
|
||
<p>由此可见,Marschner Model中忽略髓质在动物毛发计算中并不适用</p>
|
||
<p><img src="../../images/importance_of_medulla.png" alt=""></p>
|
||
<p>有无髓质的对比</p>
|
||
<p><img src="../../images/importance_of_medulla2.png" alt=""></p>
|
||
<h4 id="双层圆柱模型double-cylinder-model">双层圆柱模型(Double Cylinder Model)</h4>
|
||
<p>该模型中加入了对髓质的精确描述</p>
|
||
<p><img src="../../images/double_cylinder_model.png" alt=""></p>
|
||
<p>光线在打到表面后依旧会发生反射,穿过结构后也可能无法到达髓质或是到达后没有发生反射,与Marschner Model中一样,存在R、TT、TRT</p>
|
||
<p>同样会有部分光穿过髓质的时候发散到各个方向上去(TTs),TRT也相同,在穿过髓质的过程中,两次都有可能被散射,形成TRTs</p>
|
||
<p><img src="../../images/double_cylinder_model_lobes.png" alt=""></p>
|
||
<p>可以使用5个不同的分量,在原来的3个模型上加上2个散射的结果</p>
|
||
<p><img src="../../images/double_cylinder_model_lobes2.png" alt=""></p>
|
||
<h5 id="应用-1">应用</h5>
|
||
<p>下图中的仓鼠,由60万根毛发组成,在每像素中有1024个采样点的采样率下,每帧需要渲染36.9分钟</p>
|
||
<p><img src="../../images/60000_fur_fibers_hamster.png" alt=""></p>
|
||
<p>猩球崛起</p>
|
||
<p><img src="../../images/double_cylinder_model_application1.png" alt=""></p>
|
||
<p>狮子王</p>
|
||
<p><img src="../../images/double_cylinder_model_application2.png" alt=""></p>
|
||
<h4 id="颗粒材质granular-material">颗粒材质(Granular Material)</h4>
|
||
<p>如香料、盐、糖等等</p>
|
||
<p><img src="../../images/granular_material.png" alt=""></p>
|
||
<p>计算量很大,但可以做些简化</p>
|
||
<p>比如一个沙子城堡,每一单元上由不同石子构成,各自成分占比也可得出,渲染结果在离得近的时候可以看到一粒一粒的,离得远的情况下就会是一个沙丘</p>
|
||
<p><img src="../../images/granular_material_1.png" alt=""></p>
|
||
<p><img src="../../images/granular_material_application1.png" alt=""></p>
|
||
<p><img src="../../images/granular_material_application2.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="表面模型surface-models">表面模型(Surface Models)</h3>
|
||
<h4 id="半透明材质translucent-material">半透明材质(Translucent Material)</h4>
|
||
<p>翻译有些许错误,Translucent不应为半透明,semitransparent才是半透明,两者存在些许差别</p>
|
||
<p>光线在穿过透明介质时会涉及到吸收,本身还涉及到散射,说明光线可以从某一个地方进入这一个表面再从另一个地方出这个表面</p>
|
||
<p>即并非沿着一个方向传播并被吸收,可以被传导到其他方向上去</p>
|
||
<p><img src="../../images/translucent_material_jade.png" alt=""></p>
|
||
<p><img src="../../images/translucent_material_jellyfish.png" alt=""></p>
|
||
<p>在物理上,常常认为光线在某一个点进入某一个表面,在里面发生了大量散射,从另一个点钻出</p>
|
||
<p><img src="../../images/subsurface_scattering.png" alt=""></p>
|
||
<h4 id="次表面散射subsurface-scattering">次表面散射(Subsurface Scattering)</h4>
|
||
<p>出于描述上述反射过程的目的,将其定义为次表面散射</p>
|
||
<h5 id="次表面散射可理解为对brdf概念的延伸">次表面散射可理解为对BRDF概念的延伸</h5>
|
||
<p>BRDF: 光线打到这个点,并从这个点出来,所有作用都发生在一个点上</p>
|
||
<p>BSSRDF:可理解为吧BRDF的概念延伸到从一个点以任意方向进来再从任意一个其他的地方以任意方向出去</p>
|
||
<p><img src="../../images/BRDF_vs_BSSRDF.png" alt=""></p>
|
||
<ul>
|
||
<li>定义</li>
|
||
</ul>
|
||
<p>和BRDF概念一致,只是在中间加入了一个Subsurface Scattering,次表面反射对应的BSSRDF规定了光线从哪个点和方向进,从哪个点和方向出</p>
|
||
<p>$$S(x_i,\omega_i,x_o,\omega_o)$$</p>
|
||
<ul>
|
||
<li>渲染方程</li>
|
||
</ul>
|
||
<p>需要额外考虑从各个方向进入其他点的光,因此需要对方向和面积进行积分</p>
|
||
<p>$$L(x_o,\omega_o) = \int_A\int_{H^2} {S(x_i,\omega_i,x_o,\omega_o)L_i(x_i,\omega_i)\cos\theta_id\omega_idA}$$</p>
|
||
<ul>
|
||
<li>Dipole Approximation</li>
|
||
</ul>
|
||
<p>以上算法稍显复杂,我们可以采用一下方式进行简化</p>
|
||
<p>光线打到物体上与物体底部出现光源类似,会从底部照亮着色点周围的一片,为了物理上的真实,推出一个光源不够,还要对应上方有一个光源,还要对应上方存在一个光源,相当于有两个光源照亮周围着色点的一块</p>
|
||
<p><img src="../../images/dipole_approximation.png" alt=""></p>
|
||
<ul>
|
||
<li>效果</li>
|
||
</ul>
|
||
<p>BRDF,类石膏材质效果</p>
|
||
<p><img src="../../images/eg_BRDF_caarve.png" alt=""></p>
|
||
<p>BSSRDF,类大理石</p>
|
||
<p><img src="../../images/eg_BSSRDF_carve.png" alt=""></p>
|
||
<p>如图,BRDF渲染的皮肤效果显得干燥,BSSRDF则能有很好的效果</p>
|
||
<p><img src="../../images/BRDF_vs_BSSRDF.png" alt=""></p>
|
||
<ul>
|
||
<li>应用</li>
|
||
</ul>
|
||
<p>人脸渲染</p>
|
||
<p><img src="../../images/BSSRDF_application.png" alt=""></p>
|
||
<h3 id="布料cloth">布料(cloth)</h3>
|
||
<ul>
|
||
<li>布料组成</li>
|
||
</ul>
|
||
<p>由一系列缠绕的纤维构成,有几个不同的层级</p>
|
||
<p>纤维(fiber)是最基础的,纤维可以缠绕成不同的股(ply),不同的股再经过不同的缠绕形成线(yarn)</p>
|
||
<p><img src="../../images/cloth_yarn_and_ply.png" alt=""></p>
|
||
<p>Woven or Knitted(编织或针织)</p>
|
||
<p>一种是机器织的,一根压一根的,像桌布之类的做法</p>
|
||
<p>一种是手工织的,像打毛衣一样</p>
|
||
<p>对于布来说,它是纤维缠绕而成的,所以算它的表面模型就非常麻烦,因为与针织或纺织的方向有关</p>
|
||
<p>可以通过编织图案计算BRDF模型</p>
|
||
<ul>
|
||
<li>问题</li>
|
||
</ul>
|
||
<p>布料模型大多数并非在一个表面上,难以使用BRDF来表示</p>
|
||
<p><img src="../../images/render_as_surface_limitation.png" alt=""></p>
|
||
<ul>
|
||
<li>解决方案1</li>
|
||
</ul>
|
||
<p>所以将织物认为是在空间中分布的体积,然后可以将其划分成超级细小的格子,每一个格子里面大概知道纤维的朝向、分布、复杂程度等等,那就可以将这些性质转化成光线的吸收和散射。将这些性质转换成对云烟雾这种反射介质的渲染,不再将布料当成一个面,而是当成一个体积,体积中任何一个微小的块都知道它的性质</p>
|
||
<p>计算量庞大,计算时间长</p>
|
||
<p><img src="../../images/cloth_render_as_participating_media.png" alt=""></p>
|
||
<ul>
|
||
<li>解决方案2</li>
|
||
</ul>
|
||
<p>布料本身是纤维,渲染每一根纤维也能产生很好的效果,计算量同样惊人</p>
|
||
<p><img src="../../images/cloth_render_as_actual_fibers.png" alt=""></p>
|
||
<ul>
|
||
<li>应用</li>
|
||
</ul>
|
||
<p><img src="../../images/cloth_application.png" alt=""></p>
|
||
<h4 id="有细节的材质detailed-appearance">有细节的材质(Detailed Appearance)</h4>
|
||
<p>如下图,渲染结果不错但并不真实,因为结果过于完美</p>
|
||
<p><img src="../../images/detailed_appearance_motivation.png" alt=""></p>
|
||
<p>真实情况下车上会有高光,高光周围会有类似于蜘蛛网结构的划痕。鼠标上则会有由很多小的凸起形成的高光</p>
|
||
<p><img src="../../images/detailed_appearance_motivation1.png" alt=""></p>
|
||
<p>下图由微表面模型渲染得出,结果完美但不真实</p>
|
||
<p><img src="../../images/detailer_appearance1.png" alt=""></p>
|
||
<p>加入了实际可能产生不完美的地方</p>
|
||
<p><img src="../../images/detailer_appearance2.png" alt=""></p>
|
||
<p>模拟被同方向刷出的各项异性材质</p>
|
||
<p><img src="../../images/detailer_appearance3.png" alt=""></p>
|
||
<ul>
|
||
<li>微表面模型中的法线分布</li>
|
||
</ul>
|
||
<p>微表面模型中重要的是微表面的法线分布,描述分布时,往往使用非常简单的模型(正态分布、高斯),得到的自然是没有什么细节的结果(法线分布没有体现各种各样的变化和细节)</p>
|
||
<p><img src="../../images/distribution_of_normals.png" alt=""></p>
|
||
<p>在蜗牛壳上贴了一个大的法线贴图,每个面都可以产生高光,所有高光形成一起就可以变成一个大高光</p>
|
||
<p><img src="../../images/define_detail1.png" alt=""></p>
|
||
<p>Metallic flakes:可替换别的模型,例如很多人在车漆中添加的亮片,亮片会形成很多不同的方向,不同方向会形成不同的反光</p>
|
||
<p><img src="../../images/different_details2.png" alt=""></p>
|
||
<p>虽然能够定义各种细节,但渲染十分困难,需要渲染接近一个月才能得到这个结果</p>
|
||
<p><img src="../../images/details_apperance_3.png" alt=""></p>
|
||
<ul>
|
||
<li>渲染困难的原因:</li>
|
||
</ul>
|
||
<p>认为每一个微表面是一个镜面,如下图场景中有一个针孔摄像机和一个点光源,那从摄像机打根光线过去,打到哪个表面,就可以知道它的法线,也就可以知道它的镜面反射方向,所以也就很难通过反射的方式让光线打到光源上。从光源打过来也是同理,打到一个微表面,并且知道如何反射,但就是反射不到摄像机上去</p>
|
||
<p><img src="../../images/difficult_path_sampling_problem.png" alt=""></p>
|
||
<p>解决:
|
||
由于一个像素会覆盖很多的微表面,如果将一个小的范围内的微表面的法线分布计算出来便可代替原本光滑的分布并用在微表面模型里</p>
|
||
<p><img src="../../images/BRDF_over_a_pixel.png" alt=""></p>
|
||
<ul>
|
||
<li>P-NDF的形状:</li>
|
||
</ul>
|
||
<p>如果考虑像素覆盖的范围,就可以得到各种各样神奇的法线分布(NDF)。可以想象一个像素覆盖了非常多的微表面,那这些微表面自然会显示出一些统计学的规律,那如果覆盖的范围小,就会显示出一些很独特的性质,法线分布就会看上去很有特点</p>
|
||
<p><img src="../../images/p-NDFs_have_sharp_features.png" alt=""></p>
|
||
<p>不同类型的法线贴图会引起不同的法线分布</p>
|
||
<p><img src="../../images/p-NDF_sharps.png" alt=""></p>
|
||
<ul>
|
||
<li>例子和应用</li>
|
||
</ul>
|
||
<p><img src="../../images/blender_detail.png" alt=""></p>
|
||
<p><img src="../../images/ocean_wave_detail.png" alt=""></p>
|
||
<p>游戏中的应用-古墓丽影中的雪地</p>
|
||
<p><img src="../../images/detailed_material_application.png" alt=""></p>
|
||
<h4 id="波动光学">波动光学</h4>
|
||
<p>引入细节后,还用几何光学解释就不对,物理上当物体非常小,小到和光的波长相当时,就不能假设光线是沿直线传播的,而必须假设这个光是一个波,这就会涉及到衍射和干涉现象的发生</p>
|
||
<p><img src="../../images/wave_optics_application.png" alt=""></p>
|
||
<p>比如在黑屋里,用点光源照亮一个金属片,会在本身只有一个颜色的金属片上看到各种各样的颜色</p>
|
||
<p><img src="../../images/Observations_1.png" alt=""></p>
|
||
<p><img src="../../images/Observations_2.png" alt=""></p>
|
||
<p>白光照射后反射出来的便为白光,如果不是白的就一定有波动光学(Wave Optics)</p>
|
||
<p>波动光学得出的BRDF与几何光学的BRDF很像但具有不连续的特点(光会发生干涉,会引起部分区域加强或减弱)</p>
|
||
<p><img src="../../images/detailed_material_under_wave_optics.png" alt=""></p>
|
||
<p>以下为波动关系渲染的结果</p>
|
||
<p><img src="../../images/wave_optics_application.png" alt=""></p>
|
||
<p><img src="../../images/wave_optics_application%202.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="程序化材质生成procedural-appearance">程序化材质生成(Procedural Appearance)</h3>
|
||
<p>用一定的方式指导生成,无需真正地生成,可以动态查询</p>
|
||
<p>如下图可定义各种各样的花纹,花瓶打碎后可见花瓶内部纹理,可定义一个三维纹理</p>
|
||
<p><img src="../../images/procedural_appearance1.png" alt=""></p>
|
||
<p>存储量在三维下会变得很大,可利用noise函数(x,y,z),给定任何x,y,z可得到对应的值,这样可以实现什么时候用就什么时候去查</p>
|
||
<p><img src="../../images/procedural_appearance2.png" alt=""></p>
|
||
<p>procedural更多意味着不生成,需要时再查询</p>
|
||
<ul>
|
||
<li>车上的锈</li>
|
||
</ul>
|
||
<p>可生成一系列噪声,可对噪声做出一系列操作(二值化(binary noise));铁锈往往是不同区域有不同分布,这个噪声如果为0到1,当函数值大于0.8时认为是1,小于0.8就认为是0</p>
|
||
<p><img src="../../images/procedural_appearance3.png" alt=""></p>
|
||
<p>应用最广泛的是柏林(Perlin)噪声</p>
|
||
<ul>
|
||
<li>生成地形</li>
|
||
</ul>
|
||
<p><img src="../../images/procedural_appearance4.png" alt=""></p>
|
||
<ul>
|
||
<li>生成海浪</li>
|
||
</ul>
|
||
<p><img src="../../images/procedural_appearance5.png" alt=""></p>
|
||
<ul>
|
||
<li>生成木头纹理</li>
|
||
</ul>
|
||
<p><img src="../../images/procedural_appearance6.png" alt=""></p>
|
||
<p>常用Houdini来做程序化材质,且是先程序化生成再拿去使用</p>
|
||
<hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>材质与外观</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E6%9D%90%E8%B4%A8%E4%B8%8E%E5%A4%96%E8%A7%82/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E6%9D%90%E8%B4%A8%E4%B8%8E%E5%A4%96%E8%A7%82/</guid>
|
||
<pubDate>Mon, 25 Jul 2022 15:23:18 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="图形学中的材质">图形学中的材质</h3>
|
||
<p>用于描述光线和不同材质间的作用关系</p>
|
||
<p><img src="../../images/eg_material_in_cg.png" alt=""></p>
|
||
<p>上图从左至右分别为三维空间中的网格模型,渲染出的两种不同结果</p>
|
||
<h4 id="材质material--brdf">材质(Material) == BRDF</h4>
|
||
<p>渲染方程由物理量推出,因而渲染方程本身严格正确,BRDF描述了某一种材质,因此BRDF决定了光如何被反射</p>
|
||
<h6 id="漫反射材质">漫反射材质</h6>
|
||
<p>漫反射:任何一根光线打到漫反射位置的点上会被均匀地分散到各个不同的方向上去</p>
|
||
<p><img src="../../images/diffuse_lambertian_material.png" alt=""></p>
|
||
<ul>
|
||
<li>漫反射材质可定义任何一个不同的点上不同的漫反射系数</li>
|
||
</ul>
|
||
<p>经验定义:</p>
|
||
<p>在Blinn-phong模型中,我们定义过漫反射系数,有多少Intensity到达,然后用一个0到1的颜色控制能被吸收多少(RGB三个通道各不相同,那就引入了颜色)</p>
|
||
<p>正确定义:</p>
|
||
<p>空间中从任何一个方向进来的光的Radiacne是一样的,反射出来的光因为漫反射所以也是同样的</p>
|
||
<p>因此如果如果这个点不发光也不吸收光(白的),那就意味着所有的光进来多少就发射出去多少。也就是进来多少Irradiance,就会出去多少Irradiance,因为Radiance是一致的的,所以入射和出射的Radiance也要是一样的</p>
|
||
<p><img src="../../images/caculate_diffuse_material.png" alt=""></p>
|
||
<p>要使Li等于Lo,所以BRDF为$1/\pi$,此时是完全不吸收能量的</p>
|
||
<p>可定义一个反射率(albedo)在0到1之间,那就可以引入不同颜色的BRDF,值为$albedo/\pi$。这个BRDF的范围是$(0,1/\pi)$</p>
|
||
<p>$$f_r = \rho/\pi$$</p>
|
||
<h6 id="glossy材质">Glossy材质</h6>
|
||
<p>类似于镜面反射又有些粗糙</p>
|
||
<p><img src="../../images/glossy_material.png" alt=""></p>
|
||
<h6 id="类玻璃水的通透材质">类玻璃/水的通透材质</h6>
|
||
<p><img src="../../images/Ideal_feflective_material.png" alt=""></p>
|
||
<p>左图为玻璃球(水的性质),右图有颜色且来自于玻璃球壳内,说明折射光在玻璃里传播时会被部分吸收</p>
|
||
<h4 id="反射">反射</h4>
|
||
<h5 id="物理上的反射定律">物理上的反射定律</h5>
|
||
<p>镜面反射:入射角等于反射角</p>
|
||
<p><img src="../../images/perfect_specular_reflection_in_physic1.png" alt=""></p>
|
||
<h5 id="计算公式">计算公式</h5>
|
||
<p>方式一:</p>
|
||
<p>根据反射定律,入射光的方向和出射方向的正中间一定是法线方向,再利用平行四边形法则,将$\omega o$和$\omega i$加起来,一定会沿着n方向,其长度为$2\cos \theta $</p>
|
||
<p>方式二:</p>
|
||
<p>将入射和反射角投影到局部坐标系上,可以认为任何一个方向和法线的夹角为0,意味着其方向沿着法线方向,为坐标系的水平方向</p>
|
||
<p>再定义一个$\phi$角度:规定$\omega i$、$\omega o$、n在某一个平面上,$\phi$等于0,如果这个平面绕着n在转,所形成的角度叫方位角</p>
|
||
<p>通过这种方式可以将任何的角度拆成$\theta$和$\phi$,对于左图从上往下看,得到右图,入射角和出射角的朝向在方位角上正好相反(也就是在一个角度上加上一个$\pi$),然后所有的角度都是按$2\pi$循环的</p>
|
||
<p>所以已知$\theta和\phi$,就可以计算出射方向</p>
|
||
<p><img src="../../images/perfect_specular_reflection_in_physic2.png" alt=""></p>
|
||
<p>镜面反射:</p>
|
||
<p>对于一个全镜面反射来说,只需要考虑菲涅尔系数</p>
|
||
<p>$$L_o(\omega_o) = F_r(\omega_r)L_i(\omega_r) = \int_{\Omega}f_r(\omega_o,\omega_i)L_i(\omega_i)\cos \theta_i d\omega_i$$</p>
|
||
<p>$\omega_r和\omega_o$关于表面法线对称</p>
|
||
<p>此处描述$f_r$BRDF项使用狄拉克函数$\delta$</p>
|
||
<p>$\delta$函数满足:</p>
|
||
<p>$$\delta(x) = \begin{cases}
|
||
\infty &amp; \text{x = 0} \\
|
||
0 &amp; {x \neq 0 }
|
||
\end{cases}$$</p>
|
||
<p>$$\int_{-\infty}^{+\infty} {\delta(x)} =1$$</p>
|
||
<p>$$\int_{-\infty}^{+\infty} {f(x)\delta(x-x_0)dx} = f(x_0)$$</p>
|
||
<p>此时将狄拉克函数代入方程中可得到</p>
|
||
<p>$$L_0 = \int_{\Omega} {\frac{\delta(\omega_i - \omega_r )}{\cos\theta_i}F_r(\omega_i)\cos\theta_i d\omega_i} = F_r(\omega_r)L_i(\omega_r)$$</p>
|
||
<p>得到镜面反射的BRDF表达式:</p>
|
||
<p>$$f_r(p,\omega_0,\omega_i) = F_r(\omega_r)\frac{\delta(\omega_i - \omega_r)}{\cos\theta_i}$$</p>
|
||
<h3 id="折射">折射</h3>
|
||
<ul>
|
||
<li>色散:一束平行光经过棱镜后,因为不同的波长有不同的折射率,会被分解成不同的光线</li>
|
||
<li>Caustics(不准确翻译为焦散)</li>
|
||
</ul>
|
||
<p>产生Caustics的原因永远不是散射,而是聚焦</p>
|
||
<p>形成原因:光线打到的海水表面时,光线会往不同的方向去折射,对于海底的某一个点来说,有几率接收到来自不同方向打过来的光</p>
|
||
<p><img src="../../images/eg_specular_refraction.png" alt=""></p>
|
||
<h4 id="斯内尔定律snells-law">斯内尔定律(Snell's Law)</h4>
|
||
<p>不同材质拥有不同的额折射率,如真空认为是1,水为1.333,折射率越高说明光在穿过这个材质时会被折射得非常厉害,折射角会非常小,体现出不同波长的光被折射得不同程度</p>
|
||
<p><img src="../../images/medium_eg_snell_law.png" alt=""></p>
|
||
<p>方位角的朝向中,入射光和折射光也是正好相反的</p>
|
||
<p>入射角的正弦和折射角的正弦满足折射率相乘相等</p>
|
||
<p>$$\eta_i \sin\theta_i = \eta_t \sin\theta_t$$</p>
|
||
<p><img src="../../images/snell_law_caculation.png" alt=""></p>
|
||
<p>由斯内尔定律可计算折射角的余弦</p>
|
||
<p>$$\eta_i \sin\theta_i = \eta_t \sin\theta_t$$</p>
|
||
<p>$$\cos\theta_t = \sqrt{1-\sin^2\theta_t} $$</p>
|
||
<p>$$= \sqrt{1-(\frac{\eta_i}{\eta_t})^2 sin^2\theta_i}$$</p>
|
||
<p>$$\sqrt{1-(\frac{\eta_i}{\eta_t})^2(1-\cos^2 \theta_i)}$$</p>
|
||
<h4 id="全反射现象">全反射现象</h4>
|
||
<p>当满足下列条件时,折射角的余弦的计算没有实数意义,即折射不可能发生</p>
|
||
<p>$$1-(\frac{\eta_i}{\eta_t})^2(1-\cos^2\theta_i) &lt; 0$$</p>
|
||
<p>要使上式成立则</p>
|
||
<p>$$\frac{\eta_i}{\eta_t} &gt; 1$$</p>
|
||
<p>即入射介质的折射率大于折射介质的折射率,此时可能会发生没有折射的现象,名为全反射现象</p>
|
||
<p>如:Snell's Window/Circle</p>
|
||
<p>人在水底,往各个不同的方向看,只能看到一个锥形的区域(97.2度)。如下图,最左边的一根光线的折射角就已经达到90度了,如果角度再大一点,所有能量都会反射到池子底部</p>
|
||
<p><img src="../../images/eg_snell_window.png" alt=""></p>
|
||
<h4 id="bsdf--brdf--btdf">BSDF = BRDF + BTDF</h4>
|
||
<p>BRDF中的R表示反射,折射是BTDF,其中的T是transmit。BRDF和BTDF加起来可以统称BSDF,其中的S表示散射</p>
|
||
<h4 id="菲涅尔项fresnel-reflectionterm">菲涅尔项(Fresnel Reflection/Term)</h4>
|
||
<p>反射率取决于入射角(和光的偏振)的现象</p>
|
||
<p><img src="../../images/eg_fresnel_reflection.png" alt=""></p>
|
||
<p>如上图中,反射现象随着视角变化而明显</p>
|
||
<h5 id="绝缘体">绝缘体</h5>
|
||
<p>图中红线所示,如果一根光几乎和物体表面完全持平,那它就会被完全反射掉;如果光和物体是垂直的,更多的能量会发生折射,反射的能量会非常少</p>
|
||
<p>下图的另外两根线表示的是极化现象,和光线的波动性有关,其实光线是沿着各个不同方向有振动的,极化就是只沿着某一个方向振动(S和P是两个方向的极化)</p>
|
||
<p><img src="../../images/fresnel_term_dielectric.png" alt=""></p>
|
||
<h5 id="导体">导体</h5>
|
||
<p>导体的菲涅尔项和绝缘体的不一样,即使在垂直看过去的情况下,也是反射很多能量</p>
|
||
<p>导体的折射率是复数,需要一个N和一个K</p>
|
||
<p><img src="../../images/fresnel_term_conductor.png" alt=""></p>
|
||
<h5 id="菲涅尔项的公式">菲涅尔项的公式</h5>
|
||
<p>一个0到1之间的数,有多少能量会被反射,2个不同的极化(polarization:S和P)会告诉你不同的反射率,如果考虑不极化的光,就将2项平均</p>
|
||
<p><img src="../../images/fresnel_term_formule.png" alt=""></p>
|
||
<h5 id="菲涅尔近似式">菲涅尔近似式</h5>
|
||
<p>可认为该曲线在视角为0度时为某一个值,到达90度值就为1,和绝缘体类似,对导体而言,不考虑其下降再上升的过程</p>
|
||
<p>基准反射率与折射率存在数学关系</p>
|
||
<p>$$R_0 = (\frac{n_1-n_2}{n_1+n_2})^2$$</p>
|
||
<p>曲线上升到90度时为1,0度时等于$R_0$</p>
|
||
<p>$$R(\theta) = R_0 + (1 - R_0)(1 - \cos\theta)^5$$</p>
|
||
<p>可近乎完美地近似绝缘体或导体</p>
|
||
<h4 id="微表面材质模型">微表面材质/模型</h4>
|
||
<p>如下图在空间站拍摄的照片,有相对完美的高光,但看不到地球表面的山、树、和建筑物</p>
|
||
<p>与微表面理论不谋而和,只要离得足够远,看向一个物体时,很多微小的东西看不到,看到的是它们最终形成的对表面的作用(对光形成的总体的效应)</p>
|
||
<h5 id="微表面理论microfacet-theory">微表面理论(Microfacet Theory)</h5>
|
||
<p>假设物体表面是粗糙的,从远处看看到的是材质(外观),从近处看看到的是几何</p>
|
||
<ul>
|
||
<li>
|
||
<p>Macroscale层级:(flat &amp; rough)从远处看,看到的是一个平面,并且是粗糙(材质看上去是粗糙的)的;</p>
|
||
</li>
|
||
<li>
|
||
<p>Microscale层级:(bumpy &amp; specular)从近处看,可以看到很多凹凸不平的表面,并且每一个小的表面的微元都认为是完全镜面反射的物体</p>
|
||
</li>
|
||
</ul>
|
||
<p>漫反射将光反射到各个方向上就是认为所有的微表面都像一个很小的镜子,分布又各不规则,最后形成的分布就会把光打到各个不同的方向上去</p>
|
||
<p><img src="../../images/microfacet_theory.png" alt=""></p>
|
||
<h5 id="微表面法线分布">微表面法线分布</h5>
|
||
<ul>
|
||
<li>可使用微表面模型将表面的粗糙程度用微表面的法线分布表示</li>
|
||
</ul>
|
||
<p>glossy材质:</p>
|
||
<p>如下图的表面,看起来很平,它们的分布法线差的不太远,基本都是朝上的。所以如果将它们的分布画出来,它们的法线会集中在宏观的表面法线的周围</p>
|
||
<p><img src="../../images/microfacet_BRDF_glossy.png" alt=""></p>
|
||
<p>diffuse材质:</p>
|
||
<p>如下图,如果表面粗糙(意味着所有的微表面会沿着不同的方向),如果将法线画出来,那它的分布就会离中心离的特别远都会有分布的值</p>
|
||
<p><img src="../../images/microfacet_BRDF_diffuse.png" alt=""></p>
|
||
<ul>
|
||
<li>微表面模型的BRDF公式</li>
|
||
</ul>
|
||
<p>菲涅尔项(Fresnel)- F(i,h):</p>
|
||
<p>表示总共有多少能量被反射。根据不同的入射方向有不同程度的反射(也就是说如果入射方向几乎是平的,那么就会有大量能量被反射)</p>
|
||
<p>法线分布(distribution of normals)- D(h):</p>
|
||
<p>这个分布表示在任何一个给定方向上分布的值(可能是集中在中间的,可能是均匀分散开的)</p>
|
||
<p>只有当微表面的法线方向和half vector完全一致的时候,才能吧入射方向的光反射到出射方向上去</p>
|
||
<p>阴影遮掩(shadowing-masking)(几何项) - G(i,o,h):</p>
|
||
<p>这些微表面间有可能会发生互相遮挡。对入射的光线,有可能会出现自己给自己的阴影;对于观察方向也是一样的,有部分也有可能因为遮挡会看不到</p>
|
||
<p>光线近似平行于表面时更易发生自遮挡,这种入射方向为掠射角(Grazing Angle),阴影遮掩的提出正是用于修正掠影角</p>
|
||
<p><img src="../../images/microfacet_BRDF_caculate.png" alt=""></p>
|
||
<hr>
|
||
<p>使用微表面材质渲染得到的图像质量很高,且微表面模型可描述的物体种类较多,金属、皮质、木头</p>
|
||
<p><img src="../../images/microfacet_BRDF_example.png" alt=""></p>
|
||
<h4 id="各向同性各向异性材质">各向同性/各向异性材质</h4>
|
||
<p>如下图在电梯间的内部,电梯间的六面几乎都是金属,金属是平面的,如果说头顶上有一些小灯打到金属的表面上去会形成高光,高光一般都是圆和椭圆,但这里出现了一条一条的现象</p>
|
||
<p>当金属为拉丝金属,就会产生如图现象</p>
|
||
<p><img src="../../images/isotropic_inside_an_elevator.png" alt=""></p>
|
||
<ul>
|
||
<li>各向同性:认为其微表面不存在一定的方向性,或方向性微弱</li>
|
||
</ul>
|
||
<p>下图可见法线在各个方向上的分布是均匀的</p>
|
||
<p><img src="../../images/isotropic_materials_theory.png" alt=""></p>
|
||
<ul>
|
||
<li>各向异性:认为其法线分布具有明确的方向性</li>
|
||
</ul>
|
||
<p><img src="../../images/anisotropic_materials_theory.png" alt=""></p>
|
||
<ul>
|
||
<li>Anisotropic BRDFs</li>
|
||
</ul>
|
||
<p>如果出射方向和入射方向在方位角上旋转,得到的还是相同的BRDF,那就是各向同性的材质。如果不只和相对的方位角有关,还和绝对的方位角有关,那这个BRDF就是各向异性的</p>
|
||
<p>$$f_r(\theta_i,\phi_i;\theta_r,\phi_r) \neq f_r(\theta_i,\phi_i;\theta_r, - \phi_r)$$</p>
|
||
<ul>
|
||
<li>尼龙</li>
|
||
</ul>
|
||
<p>正常尼龙做法为水平方向和竖直方向的一根压一根,其各向异性在对角线上有不同的表现</p>
|
||
<p><img src="../../images/anisotropic_BRDF_nylon.png" alt=""></p>
|
||
<ul>
|
||
<li>天鹅绒</li>
|
||
</ul>
|
||
<p>底层有很多伸出去的纤维,如果这些纤维往各个不同方向上分布是均匀的,就可认为是各向异性。但我们可将纤维拨到一边去,认为造出各向异性效果</p>
|
||
<p><img src="../../images/anistotropic_BRDF_velvet.png" alt=""></p>
|
||
<h4 id="brdf属性">BRDF属性</h4>
|
||
<ul>
|
||
<li>非负性</li>
|
||
</ul>
|
||
<p>$$f_r(\omega_i - \omega_r) \geq 0 $$</p>
|
||
<ul>
|
||
<li>线性</li>
|
||
</ul>
|
||
<p>BRDF可拆分为多块,分别做光线传播,再累加各块,得到结果与未拆分相同</p>
|
||
<p>$$L_r(p,\omega_r) = \int_{H^2} f_r(p,\omega_i \rightarrow \omega_r)L_i(p,\omega_i)\cos\theta_id\omega_i$$</p>
|
||
<ul>
|
||
<li>可逆性</li>
|
||
</ul>
|
||
<p>交换入射方向和出射方向,得到的BRDF值相同</p>
|
||
<p>$$f_r(\omega_r \rightarrow \omega_i) = f_r(\omega_i \rightarrow \omega_r)$$</p>
|
||
<ul>
|
||
<li>能量守恒</li>
|
||
</ul>
|
||
<p>BRDF不会让能量变多</p>
|
||
<p>$$\forall \omega_r \int_{H^2} f_r(\omega_i \rightarrow \omega_r)\cos \theta_i d\omega_i \leq 1 $$</p>
|
||
<p>path tracing 中光线在无限次弹射后会收敛正是因为能量守恒</p>
|
||
<ul>
|
||
<li>各向同性和各向异性</li>
|
||
</ul>
|
||
<p>各向同性说明BRDF的值只与相对的方位角相关,可改写为下式</p>
|
||
<p>$$f_r(\theta_i,\phi_i;\theta_r,\phi_r) f_r(\theta_i,\phi_i;\theta_r, - \phi_r)$$</p>
|
||
<p>原本四维的BRDF会变成三维</p>
|
||
<ul>
|
||
<li>由于BRDF的可逆性,所以对于各向同性来说,相对的方位角无需考虑正负</li>
|
||
</ul>
|
||
<p>$$f_r(\theta_i,\theta_r,\phi_r - \phi_i) = f_r(\theta_r,\theta_i,\phi_i - \phi_r) = f_r(\theta_i,\theta_r,|\phi_r - \phi_i|)$$</p>
|
||
<h4 id="测量brdf">测量BRDF</h4>
|
||
<p>BRDF可以用各种各样不同的模型去描述,但这些模型都是基于物理的描述或者近似,但只有测量出来的BRDF才是对的BRDF</p>
|
||
<ul>
|
||
<li>测量原因</li>
|
||
</ul>
|
||
<p>以前的模型不够准确</p>
|
||
<p>可以通过某些物理方法测出菲涅尔项(绿线、红线),发现和理论上的曲线(蓝线)看起来完全不一样。也就是说实际上菲涅尔项非常复杂,不是简单公式可以描述的,所以之前的模型是不太准确的</p>
|
||
<p>物理上得出的很多结论大多经过简化,与实际不同,在多数情况下需要测量</p>
|
||
<p>测量后可以不用推出一些模型,可以直接用测的数据</p>
|
||
<p><img src="../../images/measuring_BRDF_motivation.png" alt=""></p>
|
||
<h5 id="怎么测量">怎么测量</h5>
|
||
<ul>
|
||
<li>理论</li>
|
||
</ul>
|
||
<p>BRDF是2个方向(一个入射方向,一个出射方向)的一个函数,如果盯着一个着色点看,并改变它的入射方向(比如拿一个灯从四面八方照它),相机从四面八方去拍它,这样就可以覆盖BRDF所有可能的输入方向和可能的输出方向对,这样就可以做测量</p>
|
||
<p><img src="../../images/image-based_BRDF_measurement.png" alt=""></p>
|
||
<ul>
|
||
<li>实践仪器</li>
|
||
</ul>
|
||
<p>这个器械有2个爪子,一个抓相机,一个抓光源,将样本放在正中间(球心),这2个爪子可以在球面上任意的旋转</p>
|
||
<p><img src="../../images/gonioreflectometer.png" alt=""></p>
|
||
<ul>
|
||
<li>算法</li>
|
||
</ul>
|
||
<p>枚举所有出射方向,放置光源</p>
|
||
<p>枚举所有入射方向,放置相机</p>
|
||
<p>测量Radiance</p>
|
||
<pre tabindex="0"><code>foreach outgoing direction wo
|
||
move light to illuminate surface with a thin beam from wo
|
||
for each incoming direction wi
|
||
move sensor to be at direction wi from surface
|
||
measure incident radiance
|
||
</code></pre><p>测得BRDF是四维的,测量十分耗时</p>
|
||
<p>固定了摄像机之后,光源要整个走一遍球面,才能覆盖所有的光源方向,如果下次换一下相机的方向,就又要把光源在整个球面走一遍,这就叫curse of dimentionality</p>
|
||
<ul>
|
||
<li>提升算法效率</li>
|
||
</ul>
|
||
<p>如果测量的BRDF是各向同性的,实际上只有三维的</p>
|
||
<p>用BRDF的可逆性,只考虑相对方位角的话,又可以减少一半的测量</p>
|
||
<ul>
|
||
<li>BRDFs存在的问题</li>
|
||
</ul>
|
||
<ol>
|
||
<li>需要精确测量掠影角</li>
|
||
<li>需要足够高密度的采样频率来测量,以捕获高频的镜面反射</li>
|
||
<li>逆向反射</li>
|
||
<li>空间反射率会发生变化</li>
|
||
</ol>
|
||
<ul>
|
||
<li>BRDFs的存储</li>
|
||
</ul>
|
||
<p>需要的存储要求</p>
|
||
<ol>
|
||
<li>紧凑的表现形式</li>
|
||
<li>准确表示测量的数据</li>
|
||
<li>能正确表现任意方向</li>
|
||
<li>需要可用于重要性采样的良好分布</li>
|
||
</ol>
|
||
<ul>
|
||
<li>BRDF库</li>
|
||
</ul>
|
||
<p>BRDF库存储了很多不同的材质,大多数是假设各向同性的</p>
|
||
<p>对每一个材质做了90<em>90</em>180次测量,并存储结果至一个三维数组</p>
|
||
<p>存储数据量大(未压缩)</p>
|
||
<p><img src="../../images/tabular_representation.png" alt=""></p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>路径追踪</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E8%B7%AF%E5%BE%84%E8%BF%BD%E8%B8%AA/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E8%B7%AF%E5%BE%84%E8%BF%BD%E8%B8%AA/</guid>
|
||
<pubDate>Sun, 24 Jul 2022 15:01:07 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="概率论基础复习">概率论基础复习</h3>
|
||
<p>在路径追踪的计算中需要引入部分概率论内容,在此进行部分复习</p>
|
||
<h4 id="随机变量">随机变量</h4>
|
||
<ul>
|
||
<li>
|
||
<p>随机变量:一个值,表示某些事件发生</p>
|
||
</li>
|
||
<li>
|
||
<p>$x \backsim p(x)$ :随机变量的分布,随机变量取到某个值的可能性</p>
|
||
</li>
|
||
</ul>
|
||
<p>例如:对于一个骰子,共有6个面,每个面在上面的概率相等,都为1/6</p>
|
||
<h4 id="概率">概率</h4>
|
||
<ul>
|
||
<li>概率必定为非负</li>
|
||
<li>所有事件的发生概率和为1</li>
|
||
</ul>
|
||
<p>$$p_i \geq 0$$</p>
|
||
<p>$$\sum_{i = 1}^n p_i = 1$$</p>
|
||
<p>例如:对于上述的骰子,概率为$p_i = \frac{1}{6}$</p>
|
||
<h4 id="随机变量的期望">随机变量的期望</h4>
|
||
<p>如图,对于这四个可供选择的长方形,每一个选择有一个值为$X_i$,每一个选择都对应一个概率为$p_i$,那么期望则为将所有值乘以其对应的概率后累加得到的数值</p>
|
||
<p><img src="../../images/eg_expected_value.png" alt=""></p>
|
||
<p>可见上图的期望值为</p>
|
||
<p>$$E[X] = \sum_{i = 1} ^ n x_ip_i$$</p>
|
||
<p>例如:一个骰子可以取值1、2、3、4、5、6,每一个取值的概率都是1/6,期望为</p>
|
||
<p>$$E[X] = \sum_{i=1}^n \frac{i}{6} = (1+2+3+4+5+6)/6 = 3.5$$</p>
|
||
<h4 id="概率密度函数">概率密度函数</h4>
|
||
<p>随机变量的取值可以是一些固定的值(离散型),也可以是下图所示一些连续的值(连续型)</p>
|
||
<p><img src="../../images/probability_distribution_function.png" alt=""></p>
|
||
<p>某一位置的概率为其周围一小段微元与曲线相连线形成的梯形面积</p>
|
||
<p>上面这条曲线P(x)即为概率密度函数(简称PDF)</p>
|
||
<p>概率密度在所有值上的积分等于1,与概率和为1类似</p>
|
||
<p>期望的计算则是用任意一个取值乘以概率密度,并加以积分</p>
|
||
<p>对于满足下列条件的P(x)
|
||
$$p(x) \geq 0 \ \ and \int p(x)dx = 1$$</p>
|
||
<p>期望值为</p>
|
||
<p>$$E[X] = \int x P(x)dx$$</p>
|
||
<p>当一个函数本身是随机变量时:</p>
|
||
<p>例如一个随机变量满足一定的PDF
|
||
$$X \backsim p(x)$$</p>
|
||
<p>另外一个函数为</p>
|
||
<p>$$Y = f(X)$$</p>
|
||
<p>此时Y的期望为</p>
|
||
<p>$$E[Y] = E[f(X)] = \int f(x)p(x)dx$$</p>
|
||
<hr>
|
||
<h3 id="蒙特卡洛积分monte-carlo-integration">蒙特卡洛积分(Monte Carlo Integration)</h3>
|
||
<h4 id="使用理由">使用理由</h4>
|
||
<p>计算给定函数的定积分时,如果$f(x) = x^2$,就可以计算出不定积分为$\frac{1}{3}X^3 + 常数$,之后利用不定积分即可求出它在a和b的值,两者相减即得积分</p>
|
||
<p>若函数较为复杂,如下图所示,不便于使用解析方法,就要使用数值的方法计算(蒙特卡洛积分)</p>
|
||
<p><img src="../../images/reason_for_monte_carlo_integration.png" alt=""></p>
|
||
<h4 id="大致流程">大致流程</h4>
|
||
<p>黎曼积分:</p>
|
||
<p>将上图a和b之间均匀拆分为100份,取每一份的中间位置,找到对应的Y(即将整个曲线下方面积分解为各个小长方形面积之和)</p>
|
||
<p>蒙特卡洛积分:</p>
|
||
<ul>
|
||
<li>在a和b之间随便取一个数,找到这个数对应的f(x)</li>
|
||
<li>假设整个曲线为一个长方形,长方形高度为刚才去的值的对应位置高度,长方形宽度视为a到b的长度,利用长方形面积近似曲线下围面积</li>
|
||
<li>将第二步重复多次,在a到b区间采样多次,将得到的长方形面积平均求值,就可以得到相对准确的结果</li>
|
||
</ul>
|
||
<h4 id="定义">定义</h4>
|
||
<p>定积分f(x),即从a到b的值:</p>
|
||
<p>$$\int_a^b f(x)dx$$</p>
|
||
<p>x的积分域在ab区间,对概率密度函数随机采样一个变量,得到Xi</p>
|
||
<p>$$随机变量 \ \ \ X_i \backsim p(x)$$</p>
|
||
<p>蒙特卡洛积分可近似为下列式子,即$f(Xi)/p(xi)$的平均</p>
|
||
<p>$$F_N = \frac{1}{N} \sum_{i = 1}^N {\frac{f(X_i)}{p(X_i)}}$$</p>
|
||
<h4 id="特殊情况">特殊情况</h4>
|
||
<ul>
|
||
<li>在a到b之间均匀采样时,我们使用的概率密度函数(PDF)在各处的值相等,即为一个常数,又已知PDF在积分域上的积分值为1,此PDF可解出值为$\frac{1}{(b-a)}$</li>
|
||
</ul>
|
||
<p><img src="../../images/uniform_monte_carlo_estimator.png" alt=""></p>
|
||
<ul>
|
||
<li>采用蒙特卡洛积分计算时,需要知道f(Xi)和p(Xi),随机采样得到的值为Xi,蒙特卡洛积分只需计算f(Xi)除以p(Xi)的平均值,p(Xi)的值始终为$\frac{1}{(b-a)}$</li>
|
||
</ul>
|
||
<p>$$F_N = \frac{b-a}{N}\sum_{i=1}^Nf(X_i)$$</p>
|
||
<h4 id="总结">总结</h4>
|
||
<p>蒙特卡洛积分:</p>
|
||
<p>只需积分域内使用一个PDF采样,得到该样本的f(Xi)和概率密度P(Xi)的值,两者相除后取平均值</p>
|
||
<p>注意:</p>
|
||
<ol>
|
||
<li>N越大(采样次数越多),得到的结果越精准</li>
|
||
<li>积分域是定义在X上的积分,所以采样目标一定是X</li>
|
||
</ol>
|
||
<h3 id="路径追踪path-tracing">路径追踪(path tracing)</h3>
|
||
<h4 id="whitted-style-ray-tracing-存在的问题">Whitted-Style Ray Tracing 存在的问题</h4>
|
||
<ul>
|
||
<li>Whitted-style Ray Tracing 对Specular(镜面)材质的表现效果是正确的,而glossy(磨砂)材质的效果则表现不正确</li>
|
||
</ul>
|
||
<p>Specular材质:光线在物体表面能发生镜面反射则称为此材质,光线在打在表面时,会沿着镜面反射方向离去,也是镜面能够映出周围环境光的原因</p>
|
||
<p>Glossy材质:有镜面反射的样子,但又有些许模糊,类似毛玻璃效果,有一定粗糙度但能产生高光</p>
|
||
<p><img src="../../images/mirror_and_glossy_reflection.png" alt=""></p>
|
||
<ul>
|
||
<li>whitted-style ray tracing 在遇到漫反射时会停止光线弹射直接做相应的shading</li>
|
||
</ul>
|
||
<p>这种情况会忽视漫反射物体和漫反射物体之间的光线都不被渲染,也不符合漫反射将光线均匀地反射到各个不同方向上的物理定义</p>
|
||
<p>两个示例中左侧为直接光照,右侧为全局光照,都采用路径追踪的方式计算得到</p>
|
||
<p><img src="../../images/path_traced_direct_global_illumination.png" alt=""></p>
|
||
<p>可见在场景中只有上面一个光源的情况下,在直接光照里,天花板为黑色,但实际上光线会发生多次弹射,天花板应是亮的,右侧才是我们想要的效果</p>
|
||
<p>Color bleeding: 左侧全局光照图中高立方体左侧是红,光线在弹射到墙面后再反射到这个面,之后到达摄像头(眼睛),z这种现象就为Color bleeding</p>
|
||
<p>Cornell box真实存在,3D模型也是存在的,广泛用于测试各种全局光照效果</p>
|
||
<hr>
|
||
<p>两中表现效果错误来自于Whitted-style ray tracing的光线弹射计算</p>
|
||
<ol>
|
||
<li>光线打到specular的物体上,会沿着镜面方向反射或沿着折射方向折射</li>
|
||
<li>光线打到diffuse(漫反射)的物体上,这条光线就停止了</li>
|
||
</ol>
|
||
<p>虽然存在错误,但完全按照物理量推算的渲染方程是完全正确的,为了正确计算,我们要解出这个渲染方程</p>
|
||
<p>$$L_o(p,w_o) = L_e(p,w_o) + \int_{\Omega+} {L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)dw_i}$$</p>
|
||
<h4 id="蒙特卡洛积分分解渲染方程">蒙特卡洛积分分解渲染方程</h4>
|
||
<h5 id="直接光照">直接光照</h5>
|
||
<p>假设存在下图场景,我们认为各个方向进来的光$\omega i$ 均匀分布在球面上</p>
|
||
<p><img src="../../images/suppose_scene_1.png" alt=""></p>
|
||
<ul>
|
||
<li>假设该点不发光,因而直接光照强度结果来自于四面八方入射来的光照强度</li>
|
||
</ul>
|
||
<p>忽略渲染方程发光项后的形式</p>
|
||
<p>$$L_o(p,w_o) =\int_{\Omega+} {L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)dw_i}$$</p>
|
||
<h6 id="使用蒙特卡洛积分求解">使用蒙特卡洛积分求解</h6>
|
||
<ul>
|
||
<li>通过蒙特卡洛求解我们需要在不同方向上采样,考虑对应的f(x)和PDF的值</li>
|
||
</ul>
|
||
<p>着色点为p点时,从P点反射到摄像头的辐射为</p>
|
||
<p>$$L_o(p,w_o) =\int_{\Omega+} {L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)dw_i}$$</p>
|
||
<p>蒙特卡洛为了算积分会在积分域上进行采样获得样本X,计算f(x)/p(x),再求平均</p>
|
||
<p>$$\int_a^b f(x)dx \approx \frac{1}{N}\sum_{k=1}^N \frac{f(X_k)}{p(X_k)}$$</p>
|
||
<p>$$X_k \backsim p(x)$$</p>
|
||
<ul>
|
||
<li>求出f(x)</li>
|
||
</ul>
|
||
<p>将蒙特卡洛积分的方法迁移到解渲染方程上,则f(x)就是渲染方程中积分的所有计算式</p>
|
||
<p>$$L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)$$</p>
|
||
<ul>
|
||
<li>PDF的值</li>
|
||
</ul>
|
||
<p>PDF涉及对积分域进行采样,这里为对半球进行采样</p>
|
||
<p>使用最简单的均匀采样,认为半球上采样到任何一个方向上的概率密度是相同,PDF为一个常数</p>
|
||
<p>$$p(\omega_i) = \frac{1}{2\pi}$$</p>
|
||
<p>球面面积为$4\pi$,半球面面积为$2\pi$,半球对应立体角为$2\pi$,均匀采样使PDF的所在角度积分为1,因此PDF为$\frac{1}{2\pi}$</p>
|
||
<ul>
|
||
<li>将渲染方程改写成蒙特卡洛形式</li>
|
||
</ul>
|
||
<p>每次均匀地在半球上采样,取一个入射方向$\omega_i$,将上值代入可得下列式子</p>
|
||
<p>$$L_o(p,w_o) =\int_{\Omega+} {L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)dw_i}$$</p>
|
||
<p>$$\approx \frac{1}{N}\sum_{i=1}^N \frac{L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)}{p(\omega_i)}$$</p>
|
||
<p>由此可写出以下着色算法</p>
|
||
<pre tabindex="0"><code>着色点p,方向为w0
|
||
随机选择PDF采样得到的N个方向wi
|
||
初始化结果Lo
|
||
对于选中的wi
|
||
从p点连出一条光线
|
||
如果光线打到了光源
|
||
Lo+=(1/N) * Li * fr * cosine/pdf(wi)
|
||
返回Lo
|
||
</code></pre><hr>
|
||
<pre tabindex="0"><code>shade(p, wo)
|
||
Randomly choose N directions wi~pdf
|
||
Lo = 0.0
|
||
For each wi
|
||
Trace a ray r(p, wi)
|
||
If ray r hit the light
|
||
Lo += (1 / N) * L_i * f_r * cosine / pdf(wi)
|
||
Return Lo
|
||
</code></pre><h5 id="全局光照">全局光照</h5>
|
||
<p>全局光照下,我们需要考虑反射面反射过来的光,计算从Q反射到P点反射了多少辐射能</p>
|
||
<p><img src="../../images/introducing_global_illumination.png" alt=""></p>
|
||
<p>只需在直接光照的算法中添加分支便可支持全局光照</p>
|
||
<pre tabindex="0"><code>着色点p,方向为w0
|
||
随机选择PDF采样得到的N个方向wi
|
||
初始化结果Lo
|
||
对于选中的wi
|
||
从p点连出一条光线
|
||
如果光线打到了光源
|
||
Lo+=(1/N) * Li * fr * cosine/pdf(wi)
|
||
如果光线打到了q点的物体
|
||
Lo +=(1/N) * shade(q,-wi) * fr * cosine/pdf(wi)
|
||
返回Lo
|
||
</code></pre><hr>
|
||
<pre tabindex="0"><code>shade(p, wo)
|
||
Randomly choose N directions wi~pdf
|
||
Lo = 0.0
|
||
For each wi
|
||
Trace a ray r(p, wi)
|
||
If ray r hit the light
|
||
Lo += (1 / N) * L_i * f_r * cosine / pdf(wi)
|
||
Else If ray r hit an object at q
|
||
Lo += (1 / N) * shade(q, -wi) * f_r * cosine / pdf(wi)
|
||
|
||
Return Lo
|
||
</code></pre><p>打到物体上是需要考虑q点反射过来的能量,即在q点-wi方向看过去的直接光照</p>
|
||
<hr>
|
||
<h5 id="上述算法存在的问题">上述算法存在的问题</h5>
|
||
<ul>
|
||
<li>这种方式打出不同光线再以递归的方式计算,会使光线的数量呈指数爆炸增长</li>
|
||
</ul>
|
||
<p>如下图,打到第一个物体上后反射出N根光线,打到第二个物体后会再发出N个光线,即变成$N^2$条光线,会超出处理能力</p>
|
||
<p><img src="../../images/explosion_of_ray_as_ray_go_up.png" alt=""></p>
|
||
<p>解决方法:</p>
|
||
<ol>
|
||
<li>取N等于1,但是会产生较大噪声</li>
|
||
<li>采用N=1来做蒙特卡洛积分,即为路径追踪,(N!=1时为分布式光线追踪,会产生指数爆炸)</li>
|
||
<li>N=1的情况下会产生噪声,但需要得到的只是一个像素的Radiance,所以只需计算穿过一个像素的多个path再求平均即可得到目标Radiance</li>
|
||
</ol>
|
||
<p>path:一条完整连接视点和光源的路径</p>
|
||
<p>算法:</p>
|
||
<pre tabindex="0"><code>ray_generation(camPos, pixel)
|
||
Uniformly choose N sample positions within the pixel
|
||
pixel_radiance = 0.0
|
||
For each sample in the pixel
|
||
Shoot a ray r(camPos, cam_to_sample)
|
||
If ray r hit the scene at p
|
||
pixel_radiance += 1 / N * shade(p, sample_to_cam)
|
||
Return pixel_radiance
|
||
</code></pre><ul>
|
||
<li>递归算法永远不停</li>
|
||
</ul>
|
||
<p>真实世界中光线本身弹射次数也是不停的,但计算机不能无限模拟,也不能提前限制弹射次数,这样会损失多次弹射的能量</p>
|
||
<p>解决方案:</p>
|
||
<p>用Russian Roulette(俄罗斯轮盘赌)的方法来决定以一定概率去停止光线继续弹射</p>
|
||
<p>俄罗斯轮盘思想:</p>
|
||
<ol>
|
||
<li>某一着色点出射的Radiance是$L_o$</li>
|
||
<li>自定一个概率p(0&lt; p &lt; 1)</li>
|
||
<li>以一定的概率p往某一方向打一条光线</li>
|
||
<li>得到一定结果后取$L_o/p$为返回值</li>
|
||
<li>在1-p的概率内就不打光线,返回值为0</li>
|
||
</ol>
|
||
<p>可视为取两个值的离散型随机变量,可以通过概率乘以值并加起来计算期望</p>
|
||
<p>$$E = P*(L_o/p) + (1-p)*0 = L_o$$</p>
|
||
<p>对应修改后的着色算法</p>
|
||
<p>指定概率$P_RR$</p>
|
||
<p>随意在0到1中取一个数ksi</p>
|
||
<p>如果$ksi&gt;P_RR$,意味着不该往外把一根光线</p>
|
||
<p>其他情况下正常打出光线,最后结果需除以$P_RR$</p>
|
||
<pre tabindex="0"><code>shade(p, wo)
|
||
Manually specify a probability P_RR
|
||
Randomly select ksi in a uniform dist. in [0, 1]
|
||
If (ksi &gt; P_RR) return 0.0;
|
||
Randomly choose ONE direction wi~pdf(w)
|
||
Trace a ray r(p, wi)
|
||
If ray r hit the light
|
||
Return L_i * f_r * cosine / pdf(wi) / P_RR
|
||
Else If ray r hit an object at q
|
||
Return shade(q, -wi) * f_r * cosine / pdf(wi) / P_RR
|
||
</code></pre><p>至此得出不太高效的正确path tracing算法</p>
|
||
<hr>
|
||
<p>Samples(采样率)可认为是path,SPP(samples per pixel)就是一个像素打出多少path</p>
|
||
<p>low SPP下,计算速度快,图片噪声多</p>
|
||
<p>High SPP下,计算速度慢,图片噪声少</p>
|
||
<p><img src="../../images/High_and_low_spp_result.png" alt=""></p>
|
||
<h5 id="算法依旧不高效的原因">算法依旧不高效的原因</h5>
|
||
<p><img src="../../images/reason_of_being_inefficient.png" alt=""></p>
|
||
<p>光线能否打到光源上取决于运气,当光源小时往往会浪费过多光线,需要改用更好的PDF用来采样,而非简单的均匀采样</p>
|
||
<h5 id="光源上采样">光源上采样</h5>
|
||
<p>蒙特卡洛允许许多采样方法,我们可以直接在光源上采样</p>
|
||
<p><img src="../../images/sample_the_light.png" alt=""></p>
|
||
<p>n'为光源本身朝向,在与着色点连线后可得$\theta$(连线和着色点法线的夹角) $\theta$'(连线和光源法线的夹角),此时若在视为二维平面的光源上均匀采样,则PDF为$\frac{1}{A}$</p>
|
||
<p>此时得到一个定义在光源上的积分,需要将渲染方程改写</p>
|
||
<ul>
|
||
<li>将对$d\omega$的积分改为对$dA$的积分</li>
|
||
</ul>
|
||
<p>dA: 光源上的一个小平面</p>
|
||
<p>$d\omega$:是上面小的表面投影到单位球上形成的面积(单位球半径为1,立体角为dA投影到单位球上的面积除以1的平方)</p>
|
||
<p>$d\omega$和dA的关系:dA的朝向不一定朝向着色点,则需要计算$dAcos\theta'$,将光源所在平面垂直地和着色点连线,除以距离绝对值的平方,得出$d\omega$</p>
|
||
<p>$$d\omega = \frac{dAcos\theta'}{||x' - x||^2}$$</p>
|
||
<p>重写后的渲染方程为:</p>
|
||
<p>$$L_o(x,\omega_o) = \int_{\Omega+} L_i(x,\omega_i)f_r(x,\omega_i,\omega_o)\cos \theta d\omega_i$$</p>
|
||
<p>$$\int_A L_i(x,\omega_i)f_r(x,\omega_i,\omega_o)\frac{dAcos\theta'}{||x' - x||^2} dA$$</p>
|
||
<p>即可使用蒙特卡洛积分进行计算,此时的PDF为1/A</p>
|
||
<h5 id="改进后的算法">改进后的算法</h5>
|
||
<p>着色点的着色结果来源于两个部分:</p>
|
||
<ul>
|
||
<li>光源的贡献(直接光源,无需进行俄罗斯轮盘赌剔除)</li>
|
||
</ul>
|
||
<p>均匀地在光源上采样后对改写后的渲染方程使用蒙特卡洛积分计算</p>
|
||
<ul>
|
||
<li>非光源贡献(间接光源,需要进行俄罗斯轮盘赌剔除)</li>
|
||
</ul>
|
||
<p>如果通过了俄罗斯轮盘赌测试,就发出一条射线,打到了一个非光源的点q时将其贡献加入</p>
|
||
<p>算法:</p>
|
||
<pre tabindex="0"><code>shade(p, wo)
|
||
# Contribution from the light source.
|
||
Uniformly sample the light at x’ (pdf_light = 1 / A)
|
||
L_dir = L_i * f_r * cos θ * cos θ’ / |x’ - p|^2 / pdf_light
|
||
|
||
|
||
# Contribution from other reflectors.
|
||
L_indir = 0.0
|
||
Test Russian Roulette with probability P_RR
|
||
Uniformly sample the hemisphere toward wi (pdf_hemi = 1 / 2pi)
|
||
Trace a ray r(p, wi)
|
||
If ray r hit a non-emitting object at q
|
||
L_indir = shade(q, -wi) * f_r * cos θ / pdf_hemi / P_RR
|
||
Return L_dir + L_indir
|
||
</code></pre><h5 id="处理光源遮挡">处理光源遮挡</h5>
|
||
<p>上述算法中,光源采样并未考虑光源遮挡问题</p>
|
||
<p>发生下图蓝色物体遮挡在光源和着色点之间时,需要判断光源能否贡献到着色点</p>
|
||
<p><img src="../../images/light_source_blocked_judge.png" alt=""></p>
|
||
<p>判断方式:</p>
|
||
<p>着色点到光源上的采样点取一根连线,从着色点往这根连线的方向打出一根光线,判断是否会打到某个物体,自然可以直接判断直接光照是否被遮挡,不被遮挡时,直接光照可直接计算,被遮挡时,自然为0</p>
|
||
<p>改进后算法:</p>
|
||
<pre tabindex="0"><code>shade(p, wo)
|
||
# Contribution from the light source.
|
||
Uniformly sample the light at x&#39; (pdf_light = 1 / A)
|
||
Shoot a ray from p to x’
|
||
If the ray is not blocked in the middle
|
||
L_dir = L_i * f_r * cos θ * cos θ’ / |x&#39; - p|^2 / pdf_light
|
||
|
||
|
||
# Contribution from other reflectors.
|
||
L_indir = 0.0
|
||
Test Russian Roulette with probability P_RR
|
||
Uniformly sample the hemisphere toward wi (pdf_hemi = 1 / 2pi)
|
||
Trace a ray r(p, wi)
|
||
If ray r hit a non-emitting object at q
|
||
L_indir = shade(q, -wi) * f_r * cos θ / pdf_hemi / P_RR
|
||
Return L_dir + L_indir
|
||
</code></pre><p>最终path tracing的出的效果</p>
|
||
<p><img src="../../images/is_path_tracing_correct.png" alt=""></p>
|
||
<p>可见,path tracing 与照片相比能够做到几乎百分百相似</p>
|
||
<h5 id="光线追踪新旧计算算法">光线追踪新旧计算算法</h5>
|
||
<p>早期多是Whitted-style Ray Tracing</p>
|
||
<p>现代:</p>
|
||
<p>可理解为所有光线传播方式的集合</p>
|
||
<ul>
|
||
<li>(Unidirectional &amp; bidirectional) path tracing</li>
|
||
<li>Photon mapping</li>
|
||
<li>Metropolis light transport</li>
|
||
<li>VCM / UPBP…</li>
|
||
</ul>
|
||
<p>当然,现在还做不到完美的实时光线追踪,也是现在探讨前沿</p>
|
||
<hr>
|
||
<h5 id="补充问题">补充问题</h5>
|
||
<ul>
|
||
<li>蒙特卡洛积分应该选择什么样的PDF?</li>
|
||
</ul>
|
||
<p>重要性采样理论</p>
|
||
<ul>
|
||
<li>随机数是否有质量之分?</li>
|
||
</ul>
|
||
<p>存在质量之分,不同的随机数有各自特点,如low discrepancy sequences、TAA中使用的Halton sequence</p>
|
||
<ul>
|
||
<li>是否可以将采样半球和采样光源这两种采样方法结合起来,使其效果更好?</li>
|
||
</ul>
|
||
<p>存在,称为multiple imp Sampling,简称MIS</p>
|
||
<ul>
|
||
<li>我们算出了一个像素的Radiance,可是我们最后看到的是颜色,这个Radiance是不是颜色?</li>
|
||
</ul>
|
||
<p>颜色与Radiance并非一一对应关系,将Radiance换算为颜色需要经过gamma校正</p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>双向反射分布函数(BRDF)</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E5%8F%8C%E5%90%91%E5%8F%8D%E5%B0%84%E5%88%86%E5%B8%83%E5%87%BD%E6%95%B0/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E5%8F%8C%E5%90%91%E5%8F%8D%E5%B0%84%E5%88%86%E5%B8%83%E5%87%BD%E6%95%B0/</guid>
|
||
<pubDate>Sat, 23 Jul 2022 15:05:33 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="光的反射">光的反射</h3>
|
||
<p>对于在某一点上发生的反射,我们通常认为:</p>
|
||
<ul>
|
||
<li>光进来打到了一个物体,被弹走后,改变了方向</li>
|
||
<li>光线打到了某个物体表面后被吸收,再从物体表面将吸收的能量辐射出去</li>
|
||
</ul>
|
||
<h4 id="通过radiance-和-irradiance-来解释">通过Radiance 和 Irradiance 来解释</h4>
|
||
<p>从某个立体角($\omega$)来的Radiance会打在dA上,在dA上转换成能量,并以光的形式辐射到另一个方向上去(dLr),即表现为出去的Radiance</p>
|
||
<p><img src="../../images/reflaction_radiance_irradiance.png" alt=""></p>
|
||
<p>对于dA来说,其接收到的能量只考虑某一方向下立体角的Radiance,在投影后就可以计算dA接收到的Irradiance,Irradiance又会转换成Radiance反射出去</p>
|
||
<p>出于描述dA从某个方向接收到能量后向某一方向辐射的能量值的目的,我们定义了双向反射分布函数(BRDF)</p>
|
||
<h3 id="bidirectional-reflectance-distribution-function-brdf">Bidirectional Reflectance Distribution Function (BRDF)</h3>
|
||
<p>BRDF描述了dA表面是如何把一个方向收集到的能量反射到另一个方向去(定义收集到的能量如何如何往各个方向去分配(漫反射还是镜面反射))</p>
|
||
<p><img src="../../images/BRDF_define.png" alt=""></p>
|
||
<p>镜面反射下,反射出去的方向上分布了所有能量</p>
|
||
<p>漫反射下,吸收的能量会被均等的分配到各个不同的出射方向上去</p>
|
||
<p>BRDF本质上描述了光线和物体是如何作用的,因而BRDF项也定义了物体的不同材质</p>
|
||
<h3 id="反射方程the-reflection-equation">反射方程(The Reflection Equation)</h3>
|
||
<p>反射方程定义的是任意着色点,在不同的光照下,我们考虑任意一个输入的光照的入射方向对出射方向的贡献,并累加所有入射方向的贡献</p>
|
||
<p><img src="../../images/the_reflection_equation.png" alt=""></p>
|
||
<p>公式解释:</p>
|
||
<p>考虑任一不同方向的Radiance到图示的点,再通过BRDF的计算,可以得到出射的Radiance</p>
|
||
<p>存在问题:</p>
|
||
<p>从某个方向观察着色点意味着需要考虑所有到达这个着色点的光线,在光线弹射次数大于一次的情况下,能到达着色点的光线并非只有光源,还可能有其他面反射过来的光线(一个面接收光源照射后反射的Radiance还能够照亮其他面,产生递归问题)</p>
|
||
<h3 id="渲染方程the-rendering-equation">渲染方程(The Rendering Equation)</h3>
|
||
<p>渲染方程在反射方程上考虑了物体自发光的情况,提高了通用性,几乎所有物体表面的光线传播都可以使用下列公式来总结</p>
|
||
<p>$$L_o(p,w_o) = L_e(p,w_o) + \int_{\Omega+} {L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)dw_i}$$</p>
|
||
<ul>
|
||
<li>渲染方程与Blinn-Phong模型都假设所有方向向外(考虑所有入射来的方向为球心向整个半球的各个方向)</li>
|
||
<li>$\Omega +$和反射方程中的$H^2$都表示半球</li>
|
||
</ul>
|
||
<h4 id="帮助理解渲染方程">帮助理解渲染方程</h4>
|
||
<p>反射方程:</p>
|
||
<ul>
|
||
<li>对于一个点光源,反射方程描述Li进来经过BRDF反射到观察方向上去的能量</li>
|
||
</ul>
|
||
<p><img src="../../images/understanding_flection_equation1.png" alt=""></p>
|
||
<ul>
|
||
<li>如果有多个光源,就累加计算每个点光源光线到这个点反射到观测方向上的能量值</li>
|
||
</ul>
|
||
<p><img src="../../images/understanding_reflection_equation2.png" alt=""></p>
|
||
<ul>
|
||
<li>如果有一个面光源(一堆点光源的集合),则将面光源上任意一个点的贡献积分起来</li>
|
||
</ul>
|
||
<p><img src="../../images/understanding_reflection_equation3.png" alt=""></p>
|
||
<p>渲染方程:</p>
|
||
<ul>
|
||
<li>在考虑其他物体反射过来的光时,可以将反射面视为光源,由于渲染方程假设所有方向都是向外的,所以从x点指向反射面就要变成负的</li>
|
||
</ul>
|
||
<p><img src="../../images/understanding_rendering_equation1.png" alt=""></p>
|
||
<p>该点向某一观察方向辐射出去的Radiance是依赖于其他点辐射出去的Radiance,即为递归过程</p>
|
||
<p>递归的另一用处:简化方程</p>
|
||
<p>在某个方向看向一点时,我们不知道看到的能量(Lr)、从其他反射到这一点的Radiance,但其他项都已知,可定义物体的不同材质(diffuse、gloss、specular)</p>
|
||
<p><img src="../../images/rendering_equation_simplify.png" alt=""></p>
|
||
<p>可利用数学上的一些简单表达式进行简化</p>
|
||
<p>$$I(u) = e(u) + \int {I(v) k(u,v)dv}$$</p>
|
||
<p>I: 从两个不同位置(u,v表示)辐射出去的Radiance,</p>
|
||
<p>e:着色点自己发出的能量在加上从其他物体表面反射来的Radiance反射到该着色点后有多少能量辐射到观察方向</p>
|
||
<p>$k(u,v)dv$ : 方程核心</p>
|
||
<p>进一步简化:</p>
|
||
<p>将BRDF和积分写成某种操作符(算子)后简化为下列式子,</p>
|
||
<p>$$L = E +KL$$</p>
|
||
<p>所有物体辐射出的所有能量 = 所有光源辐射出来的能量加上辐射出来的能量被反射后的能量</p>
|
||
<p>解渲染方程 :</p>
|
||
<ul>
|
||
<li>将KL移至方程左侧,L写成单位矩阵*L的形式</li>
|
||
<li>将(I-k)移至右侧</li>
|
||
<li>计算(1-K)的逆即可解出L的值</li>
|
||
</ul>
|
||
<p>$$L = E + KL$$
|
||
$$IL - KL = E$$
|
||
$$(I - K)L = E$$
|
||
$$L = (I - K )^{-1}E$$</p>
|
||
<p>算子本身具有类似泰勒展开的性质</p>
|
||
<p>$$L = (I + K + K^2 + K^3 + \ldots)E$$
|
||
$$ L = E +KE+ K^2E +K^3E + \ldots $$</p>
|
||
<p>可看做:</p>
|
||
<p>光源直接辐射(E),加上经过一次反射后的辐射(KE),加上经过两次反射后的辐射(k^2E)</p>
|
||
<p>即分解了光线传播过程的弹射次数</p>
|
||
<h3 id="全局光照global-illumination">全局光照(global illumination)</h3>
|
||
<p>光线弹射一次得到为直接光照,弹射两次及以上为间接光照,所有光线弹射次数的项加起来的结果为全局光照(直接光照+间接光照)</p>
|
||
<h4 id="实例-光栅化">实例-光栅化</h4>
|
||
<p>光栅化在已知着色点与光源位置的情况下便可以做着色,着色实际为直接光照</p>
|
||
<p>因此光栅化能表现的光线传播内容实际上只有零次和一次弹射(光源自己+直接光照)</p>
|
||
<ul>
|
||
<li>直接光照(光源能直接照射的地方有颜色,其余位置为黑的)</li>
|
||
</ul>
|
||
<p><img src="../../images/Direct_illumination_eg.png" alt=""></p>
|
||
<ul>
|
||
<li>一次间接光照(光弹射两次)</li>
|
||
</ul>
|
||
<p><img src="../../images/one-bounce_global_illumination_eg.png" alt=""></p>
|
||
<ul>
|
||
<li>两次间接光照(光弹射一次,两次,三次累积后的全局光照效果)</li>
|
||
</ul>
|
||
<p><img src="../../images/two-bounce_global_illumination_eg.png" alt=""></p>
|
||
<ul>
|
||
<li>四次间接光照(玻璃灯内部变亮,在弹射三次时,仅足够进入物体,不足以离开物体)(双层玻璃需要两次弹射进入,两次弹射离开)</li>
|
||
</ul>
|
||
<p><img src="../../images/four-bounce_global_illumination_eg.png" alt=""></p>
|
||
<p>8次弹射和16次弹射只会提高暗处亮度,难以感知到</p>
|
||
<p>在无限次数弹射下,亮度会收敛到某一个值上,不会有剧烈变化,也不会产生过曝</p>
|
||
<p>在相机的情况下,保持快门打开则会产生过曝现象,与辐射度量学中单位时间的条件相应,快门打开使积累能量的时间变长,亮度变亮</p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>辐射度量学基础(Basic radiometry)</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E8%BE%90%E5%B0%84%E5%BA%A6%E9%87%8F%E5%AD%A6/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E8%BE%90%E5%B0%84%E5%BA%A6%E9%87%8F%E5%AD%A6/</guid>
|
||
<pubDate>Fri, 22 Jul 2022 15:33:53 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><p>本文建议与以下链接结合观看,便于理解</p>
|
||
<p><a href="https://ciechanow.ski/lights-and-shadows/">光照与阴影</a></p>
|
||
<h3 id="辐射度量学">辐射度量学</h3>
|
||
<ol>
|
||
<li>辐射度量学是一个物理上准确定义光照的方法,定义了一系列单位和方法描述光照</li>
|
||
<li>给光照定义了不同空间中的属性:辐射通量(Radiant flux)、强度(intensity)、辐照度(irradiance)、辐射度(radiance)</li>
|
||
<li>基于几何光学,认为光沿直线传播,没有波动性</li>
|
||
</ol>
|
||
<h4 id="引入辐射度量学的目的">引入辐射度量学的目的</h4>
|
||
<ul>
|
||
<li>Whitted-style的光线追踪实际上不符合真实物理</li>
|
||
</ul>
|
||
<p>Whitted-style采用的Blinn-Phong模型实际假设了反射为完美的镜面反射,忽略光线在反射后的能量损失</p>
|
||
<ul>
|
||
<li>辐射度量学是一个精准的给我们一系列物理量的方法</li>
|
||
</ul>
|
||
<p>辐射度量学精准地定义出物体表面与光的作用、光源、材质、光线传播,确保得到正确的结果</p>
|
||
<h4 id="辐射量和辐射通量radiant-energy-and-flux">辐射量和辐射通量(Radiant Energy and Flux)</h4>
|
||
<p>辐射量(Radiant Energy):电磁辐射的能量,单位为焦耳</p>
|
||
<p>$$Q[J = Joule]$$</p>
|
||
<p>辐射通量(Radiant Flux):每单位时间的能量,在物理上为功率,单位为瓦特,光学上单位为流明(lumen)</p>
|
||
<p>$$\Phi \equiv \frac{d_Q}{d_t} [W = Watt] [lm = lumen]$$</p>
|
||
<p>辐射通量同时可以表示为在单位时间内通过一个感光平面的光子数量</p>
|
||
<p><img src="../../images/another_defination_of_flux.png" alt=""></p>
|
||
<h4 id="辐射强度radiant-intensity">辐射强度(Radiant Intensity)</h4>
|
||
<p>定义:单位时间内,单位立体角辐射的能量</p>
|
||
<p><img src="../../images/Radiant_Intensity_define.png" alt=""></p>
|
||
<p>坎德拉(Candela): 发光强度的SI单位。一坎德拉是光源在给定方向上的发光强度,该光源发出540 $\times $1012Hz的单色辐射,并且在该方向上的辐射强度为1/683瓦/球面度</p>
|
||
<p>角度:圆上圆弧长度与半径的比值</p>
|
||
<ul>
|
||
<li>$\theta = \frac{l}{r}$</li>
|
||
<li>圆的最大角度为$2\pi$</li>
|
||
</ul>
|
||
<p>立体角:球面对向面积与半径平方的比值</p>
|
||
<ul>
|
||
<li>$\Omega = \frac{A}{r^2}$</li>
|
||
<li>球体的最大角度为$4\pi$</li>
|
||
</ul>
|
||
<p>微分立体角:球面上当立体角的方向与Z轴的夹角($\theta$)、绕着Z轴旋转的角($\phi$)发生改变时,会在对应方向的球面上框出一片区域,该区域对应的立体角即为微分立体角</p>
|
||
<p><img src="../../images/differential_solid_angles1.png" alt=""></p>
|
||
<p>对于球体$S^2$:
|
||
$$\Omega = \int_{S^2} {d\omega} = \int_0^{2\pi} \int_0^{\pi} {\sin\theta d{\theta} d{\phi}} = 4\pi$$</p>
|
||
<p>在辐射度量中,我们也会用$\omega$表示三维空间中的一个方向,可以使用$\theta和\phi$的方式来定义其位置,并利用$\sin \theta d_{\theta} d_{\phi}$来计算微分立体角</p>
|
||
<p><img src="../../images/differential_solid_angles_w.png" alt=""></p>
|
||
<h4 id="光强intensity">光强(Intensity)</h4>
|
||
<p>定义一个点光源的亮度可以定义其Flux,所以光强即为这个光源在任何一个方向上的亮度</p>
|
||
<p>对所有方向上单位立体角的光强进行积分就可以得到Flux(poweer)</p>
|
||
<p>$$\Phi = \int_{S^2} {Id\omega} = 4\pi I$$</p>
|
||
<p>对于各向同性光源(点光源向各个方向均匀地辐射出能量)</p>
|
||
<p>$$I = \frac{\Phi}{4\pi}$$</p>
|
||
<p><img src="../../images/Isotropic_Point_source.png" alt=""></p>
|
||
<h4 id="现代led灯实例">现代LED灯实例</h4>
|
||
<p>对于下图中的LED灯,可见:</p>
|
||
<p>标注输出815流明,11瓦功率相当于白炽灯60瓦功率</p>
|
||
<p>假设其为各向同性光源</p>
|
||
<p>Itensity = 815 lumens / 4pi sr = 65 candelas</p>
|
||
<p><img src="../../images/modern_LED.png" alt=""></p>
|
||
<h4 id="辐照度irradiance">辐照度(Irradiance)</h4>
|
||
<p>定义:单位面积内的能量</p>
|
||
<p><img src="../../images/Irradiance_define.png" alt=""></p>
|
||
<p>单位面积需与入射光线垂直才算是接收到的范围,否则要将其投影到垂直的方向</p>
|
||
<p>例如Lambert's Cosine Law中平行光打到单位面上如果垂直则可以接收到6根光线,平面若倾斜则只能接收到三个光线,接收到的能量要乘以$\cos \theta$</p>
|
||
<p><img src="../../images/Lambert_cosine_law_irradiance.png" alt=""></p>
|
||
<hr>
|
||
<p>基于辐照度来理解光照衰减</p>
|
||
<p>定义光源的power为$\phi$,认为其往各个方向都是均等地辐射出能量</p>
|
||
<p>之前普遍理解为能量分布在球壳上,壳越大则每个地方分布的能量越少</p>
|
||
<p>采用辐照度则认为对于最中间的球壳来说,其半径为1,则下图中该点出的辐照度为$E = \phi / (4\pi 1^2 )$,球壳半径为r时,辐照度为$\phi / (4 \pi r^2)$,也就等于$E/r^2$</p>
|
||
<p><img src="../../images/Irradiance_Fallof.png" alt=""></p>
|
||
<p>由此可得出并非Idensity在衰减,而是Irradiance在衰减</p>
|
||
<h4 id="辐射radiance">辐射(Radiance)</h4>
|
||
<p>定义:单位立体角下每单位面积下的power</p>
|
||
<p><img src="../../images/radiance_define.png" alt=""></p>
|
||
<p>由此可知power需要进行两次微分,一次立体角,一次投影后单位面积</p>
|
||
<p>intensity、radiance和irradiance的联系</p>
|
||
<p>Intensity:每单位角power</p>
|
||
<p>Irradiance:每单位投影面积的power</p>
|
||
<p>Radiance:每单位投影面积的Intensity</p>
|
||
<p>Radiance: 每单位角的Irradiance</p>
|
||
<h4 id="入射辐射incident-radiance">入射辐射(Incident Radiance)</h4>
|
||
<p>从一个方向打到一个很小的面上的能量,即为入射辐射</p>
|
||
<p><img src="../../images/Incident_radiance_define.png" alt=""></p>
|
||
<p>是沿着给定光线到达表面的光(给定表面上的点和入射方向)</p>
|
||
<h4 id="出射辐射exiting-radiance">出射辐射(Exiting Radiance)</h4>
|
||
<p>王某一个方向(立体角)辐射的能量即为出射辐射</p>
|
||
<p><img src="../../images/Exiting_radiance_define.png" alt=""></p>
|
||
<p>是沿着给定光线到达表面的光(给定表面上的点和出射方向)</p>
|
||
<h4 id="irradiance-和-radiance-的区别">irradiance 和 Radiance 的区别</h4>
|
||
<p>irradiance: dA收到的所有能量</p>
|
||
<p>radiance: dA从某一个方向收到的能量</p>
|
||
<p>E(p)即为irradiance,等于所有方向上的Radiance的和</p>
|
||
<p><img src="../../images/Irradiance_vs_radiance.png" alt=""></p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>光线追踪加速结构/算法</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E5%85%89%E7%BA%BF%E8%BF%BD%E8%B8%AA%E5%8A%A0%E9%80%9F%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E5%85%89%E7%BA%BF%E8%BF%BD%E8%B8%AA%E5%8A%A0%E9%80%9F%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/</guid>
|
||
<pubDate>Wed, 20 Jul 2022 17:56:31 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="包围盒bounding-volumes">包围盒(Bounding Volumes)</h3>
|
||
<p>将复杂的物体用简单的包围盒包裹是一个减少无用射线相交计算的好方式</p>
|
||
<ol>
|
||
<li>物体完整地包含在包围盒里</li>
|
||
<li>如果射线不与包围盒相交则不与物体相交</li>
|
||
<li>因而优先检测包围盒是否相交再检测是否与物体相交</li>
|
||
</ol>
|
||
<h4 id="射线与包围盒相交ray-intersection-with-box">射线与包围盒相交(Ray-Intersection With Box)</h4>
|
||
<p>注意理解:盒子是三对平面的交汇处,这三个平面即为包围盒边界</p>
|
||
<p>特别的我们通常使用轴对齐包围盒(Axis-Aligned Bounding Box),简称 AABB</p>
|
||
<p>Bounding Box(BB)的任意一侧沿着X,Y,或Z轴</p>
|
||
<p><img src="../../images/Ray-Intersection_With_Box.png" alt=""></p>
|
||
<h4 id="射线与轴对称包围盒相交ray-intersection-with-axis-aligned-box">射线与轴对称包围盒相交(Ray Intersection with Axis-Aligned Box)</h4>
|
||
<p>以下2D例子在3D场景中同样适用</p>
|
||
<p><img src="../../images/Ray_Intersection_With_AABB.png" alt=""></p>
|
||
<p>如上图所示,我们分别计算射线与包围盒两个边界的相交时间点,求取到$t_{min}/t_{max}$的交集</p>
|
||
<ol>
|
||
<li>射线只有同时进入所有对平面才算进入包围盒,离开包围盒同理</li>
|
||
<li>对于每一对平面,计算$t_{min}和t_{max}$,允许出现负值</li>
|
||
</ol>
|
||
<p>对于3D包围盒,$t_{enter} = \max{t_{min}},t_{exit} = \min{t_{max}}$</p>
|
||
<p>如果$t_{enter}&lt;t_{exit}$,我们便可得知射线在盒子内停留了一段时间(必定发生了相交)</p>
|
||
<p>注意点:</p>
|
||
<ol>
|
||
<li>光线并非一条线,应当检查是否为负值或是否符合物理</li>
|
||
<li>$t_{exit}&lt;0$的时候,包围盒在射线之外,没有相交</li>
|
||
<li>$t_{exit}&gt;=0和t_{enter}$时,光线的起始点在包围盒内,相交</li>
|
||
</ol>
|
||
<p>选择轴对称的原因:计算量少</p>
|
||
<p><img src="../../images/Why_Axis-Aligned.png" alt=""></p>
|
||
<h3 id="统一空间分区网格uniform-spatial-partitionsgrids">统一空间分区\网格(Uniform Spatial Partitions/Grids)</h3>
|
||
<h4 id="划分过程">划分过程</h4>
|
||
<p>找到包围盒</p>
|
||
<p><img src="../../images/grid_build_progress_step1.png" alt=""></p>
|
||
<p>创建网格</p>
|
||
<p><img src="../../images/grid_build_progress_step2.png" alt=""></p>
|
||
<p>在与相应物体重叠的网格中存储对应的物体</p>
|
||
<p><img src="../../images/grid_build_progress_step3.png" alt=""></p>
|
||
<p>根据射线穿过的网格顺序来遍历网格</p>
|
||
<p>对于每一个被遍历的网格,需要检测其中存储的物体是否与射线相交</p>
|
||
<p><img src="../../images/Ray_Scene_intersection_grid.png" alt=""></p>
|
||
<hr>
|
||
<h4 id="网格数量">网格数量</h4>
|
||
<p>网格仅有一个时无法起到加速算法的效果</p>
|
||
<p><img src="../../images/grid_resolution_one_cell.png" alt=""></p>
|
||
<p>网格过多时,因需要遍历过多无关网格而低效</p>
|
||
<p><img src="../../images/grid_resolution_too_many.jpg" alt=""></p>
|
||
<p>最佳的网格数量为:
|
||
$$cells = C * objs$$
|
||
$$C \approx 27 \ \ in \ \ 3D$$</p>
|
||
<hr>
|
||
<p>划分空间网格的方式往往在大小和空间均匀分布的大型对象集合的情况下有良好的效果</p>
|
||
<p>在失效的情况下会产生&quot; Teapot in a stadium &quot;问题,即在一个大运动场中间放了一个茶壶,此时需要走很多格子才能找到场景中茶壶的交点,在场景分布不均匀的情况下不适用网格方法</p>
|
||
<h3 id="空间划分spatial-partitions">空间划分(Spatial Partitions)</h3>
|
||
<h4 id="八叉树oct-tree">八叉树(Oct-Tree)</h4>
|
||
<p>将整个场景包围在盒中,再将包围盒切分为8份(三维情况下,每面四块),下图展示的是二维下的情况,将整个盒子分为四块,再将每块都分成四块,直到每个格子中无物体或物体数量足够少</p>
|
||
<p><img src="../../images/Oct-Tree.png" alt=""></p>
|
||
<p>通过这种方式将空间切成了分块并组织成了树状结构(一维下为二叉树,二维下为四叉树,三维下为八叉树,$n维下为2^n叉树$)</p>
|
||
<hr>
|
||
<h4 id="bsp-tree">BSP-Tree</h4>
|
||
<p>该方法是对空间进行二分的方法,即每次都选择一个方向将节点划分开,与KD-Tree不同在于其并非横平竖直地划分,且计算难度随维度升高而增加</p>
|
||
<p><img src="../../images/BSP-Tree.png" alt=""></p>
|
||
<p>二维下用一条线划分,三维下用一个平面划分,四维用‘超平面’划分,依次类推</p>
|
||
<hr>
|
||
<h4 id="kd-tree">KD-Tree</h4>
|
||
<p>与八叉树几乎相同,但每找到一个格子后总是沿着某一个轴分开使整个空间被划分成类似二叉树的结构,如下图所示,划分是水平竖直交替进行的</p>
|
||
<p><img src="../../images/KD-Tree.png" alt=""></p>
|
||
<p>三维下,划分轴在X,Y,Z轴间轮替就可以在保持二叉树性质的情况下进行划分</p>
|
||
<h5 id="kd-tree建立">KD-Tree建立</h5>
|
||
<p>将整个场景包围在盒子A中,先沿着竖直方向划分,再将这两个部分横向划分开,之后一直交替向下划分,形成一棵树</p>
|
||
<p><img src="../../images/KD-Tree_Pre-Processing.png" alt=""></p>
|
||
<p>如果一个空间已经被划分成了KD-Tree结构,则中间节点(A,B,C,D)只需要记录被划分成的各自格子,叶子节点则存储和格子相交的几何形体</p>
|
||
<h5 id="kd-tree的数据结构">KD-Tree的数据结构</h5>
|
||
<p>内部节点存储:</p>
|
||
<ol>
|
||
<li>划分的轴:X,Y,Z轴</li>
|
||
<li>划分的点:沿轴的平面分割坐标</li>
|
||
<li>子内部节点:指向子节点的坐标</li>
|
||
<li>在根节点不存储物体</li>
|
||
</ol>
|
||
<p>叶子节点存储:</p>
|
||
<ol>
|
||
<li>物体的列表(list of objects)</li>
|
||
</ol>
|
||
<h5 id="kd-tree的遍历">KD-Tree的遍历</h5>
|
||
<p>假设有一根光线,从左上到右下,穿过一个包围盒A</p>
|
||
<p><img src="../../images/Traversing_a_KD-Tree_step1.png" alt=""></p>
|
||
<p>第一次判断是否与A存在交点,光线有交点则可能与左右子节点产生交集</p>
|
||
<p><img src="../../images/Traversing_a_KD-Tree_step2.png" alt=""></p>
|
||
<p>检测是否与子节点存在交点,发现与左边蓝色区域存在交点,按图中划分,1不再划分的情况下则认为光线与该叶子节点(蓝色区域内)所有物体求交</p>
|
||
<p><img src="../../images/Traversing_a_KD-Tree_step3.png" alt=""></p>
|
||
<p>检查右子节点,发现与右边区域也有交点,则光线可能和B的子节点(2和C)相交</p>
|
||
<p><img src="../../images/Traversing_a_KD-Tree_step4.png" alt=""></p>
|
||
<p>再判定光线与2和C区域相交情况,发现与2存在交点,此处假设2不再细分,2即为一个叶子节点,光线需要和2中所有物体求交</p>
|
||
<p><img src="../../images/Traversing_a_KD-Tree_step5.png" alt=""></p>
|
||
<p>发现与C区域存在交点,那便要判断光线和C的子节点(D、3)是否有交点,发现和3存在交点,且3为叶子节点,则光线要和3中的所有物体求交,D同理,一直求到叶子节点(区域5与光线无交点,无需求交)</p>
|
||
<p><img src="../../images/Traversing_a_KD-Tree_step6.png" alt=""></p>
|
||
<p>在C中光线和所有物体求交就找到了交点</p>
|
||
<p><img src="../../images/Traversing_a_KD-Tree_step7.png" alt=""></p>
|
||
<h5 id="kd-tree的问题">KD-Tree的问题</h5>
|
||
<ul>
|
||
<li>难以判定包围盒和物体的交集</li>
|
||
</ul>
|
||
<p>虽然三角形只要有一个顶点在盒子内,就可以判定相交,但存在三个顶点都不在包围盒内但依旧相交的情况(包围盒在三角形内部)</p>
|
||
<ul>
|
||
<li>一个物体可能出现在多个不同的叶子节点里</li>
|
||
</ul>
|
||
<p>如案例中右下角的圆与3、4、5都存在交点,会在叶子节点3、4、5中存储这个物体,这会造成性能浪费</p>
|
||
<hr>
|
||
<h4 id="bvhbounding-volume-hierarchy">BVH(Bounding Volume Hierarchy)</h4>
|
||
<p>BVH无论在实时的光线追踪还是离线的结构都解决了KD-Tree的问题,在图形学里有广泛地运用</p>
|
||
<h5 id="bvh结构创建">BVH结构创建</h5>
|
||
<p>同样将场景用一个盒子包围,与KD-Tree不同在于后者将物体划分为2个部分</p>
|
||
<p><img src="../../images/BVH_build_step1.png" alt=""></p>
|
||
<p>将上图方框中所有三角形分割成两个部分再重新求它们的包围盒</p>
|
||
<p><img src="../../images/BVH_build_step2.png" alt=""></p>
|
||
<p>同样再继续划分,将上图蓝色节点划分为两堆三角形再重新求它们的包围盒,对应下图蓝绿节点</p>
|
||
<p><img src="../../images/BVH_build_step3.png" alt=""></p>
|
||
<p>划分终止条件自定义:如一个节点中只有5个三角形存在</p>
|
||
<p>总结:</p>
|
||
<ol>
|
||
<li>找到一个包围盒</li>
|
||
<li>基于包围盒中的物体,递归地拆分包围盒为两个部份</li>
|
||
<li>两个部份各自重新计算包围盒</li>
|
||
<li>叶子节点中三角形数量满足终止条件时停止划分,记录实际的物体至叶子节点里,其余结构用于判断加速结构</li>
|
||
</ol>
|
||
<h5 id="bvh性质">BVH性质</h5>
|
||
<ul>
|
||
<li>
|
||
<p>一个叶子节点里只可能出现在一个几何结构里</p>
|
||
</li>
|
||
<li>
|
||
<p>可以不采用求三角形和包围盒的交</p>
|
||
</li>
|
||
</ul>
|
||
<p>按物体划分使得包围盒求取简易,避免了空间划分中求包围盒和物体的交集</p>
|
||
<p>问题:</p>
|
||
<p>未严格划分空间,不同的Bounding box间可以相交</p>
|
||
<h5 id="bvh节点划分方式">BVH节点划分方式</h5>
|
||
<ul>
|
||
<li>
|
||
<p>与KD-Tree一样选择一个维度来划分</p>
|
||
</li>
|
||
<li>
|
||
<p>方法一:只沿着最长的轴将其分成两半</p>
|
||
</li>
|
||
<li>
|
||
<p>方法二:取中间的物体进行划分</p>
|
||
</li>
|
||
</ul>
|
||
<p>例如:</p>
|
||
<p>一行三角形从左到右依次排列寻找中位数,第n/2个三角形</p>
|
||
<p>中位数可确保两部分数量相似即生成的树接近平衡(通过保证两边深度相似可减少平均搜索次数)</p>
|
||
<p>排序上可假设沿着X轴去考虑三角形,则所有三角形取重心后沿X轴排序便可得知中间的三角形位置(快速选择算法)</p>
|
||
<hr>
|
||
<p>以上步骤可得到一个预计算的BVH,如果场景发生改动则需要重新计算</p>
|
||
<hr>
|
||
<h5 id="bvh的数据结构">BVH的数据结构</h5>
|
||
<ul>
|
||
<li>
|
||
<p>内部节点存储</p>
|
||
<ul>
|
||
<li>包围盒</li>
|
||
<li>指向子节点的指针</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<p>叶子节点存储</p>
|
||
<ul>
|
||
<li>包围盒</li>
|
||
<li>实际的物体</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<p>节点表示场景中分割框的子集</p>
|
||
<ul>
|
||
<li>子树中的所有物体</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h5 id="bvh与光线求交">BVH与光线求交</h5>
|
||
<p>与KD-Tree类似,光线和根节点求交,找到内部物体最近的交点</p>
|
||
<p>光线与BVH节点相交后存在两种可能:</p>
|
||
<ol>
|
||
<li>节点本身为叶子节点,此时光线与叶子节点里所有物体求交,放回最近交点</li>
|
||
<li>节点本身不是叶子节点,此时光线可能与该节点的两个子节点都有交点,递归地求出它们的交点再返回最近的点</li>
|
||
</ol>
|
||
<p><img src="../../images/BVH_Traversal.png" alt=""></p>
|
||
<h5 id="空间物体划分区别">空间/物体划分区别</h5>
|
||
<ul>
|
||
<li>空间划分(Spatial partition)
|
||
<ol>
|
||
<li>划分空间,任何一个节点在空间和时间之间不会有交集</li>
|
||
<li>有些物体存在横跨边界的可能</li>
|
||
</ol>
|
||
</li>
|
||
</ul>
|
||
<p><img src="../../images/eg_spatial_partition.png" alt=""></p>
|
||
<ul>
|
||
<li>物体划分(Object partition)
|
||
<ol>
|
||
<li>划分物体,物体分为两部分后分别计算包围盒</li>
|
||
<li>包围盒存在交集的可能,但不产生影响且无需计算包围盒相交方式</li>
|
||
</ol>
|
||
</li>
|
||
</ul>
|
||
<p><img src="../../images/eg_object_partition.png" alt=""></p>
|
||
<hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>Whitted-style光线追踪(Whitted-style Ray Tracing)</title>
|
||
<link>http://www.inksoul.top/computergraphic/whitted-style%E5%85%89%E7%BA%BF%E8%BF%BD%E8%B8%AA/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/whitted-style%E5%85%89%E7%BA%BF%E8%BF%BD%E8%B8%AA/</guid>
|
||
<pubDate>Tue, 19 Jul 2022 16:04:37 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="使用光线追踪的原因">使用光线追踪的原因</h3>
|
||
<ol>
|
||
<li>
|
||
<p>光栅化无法很好地处理全局效果</p>
|
||
<ol>
|
||
<li>软阴影</li>
|
||
<li>光线产生多次反弹</li>
|
||
</ol>
|
||
</li>
|
||
<li>
|
||
<p>光栅化处理速度快但质量相对较低</p>
|
||
</li>
|
||
<li>
|
||
<p>光线追踪处理精准,但速度较低</p>
|
||
<ol>
|
||
<li>光栅化:实时渲染,光线追踪:离线渲染</li>
|
||
<li>在生产环境中渲染一帧往往需要~10kCPU核心时</li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
<h3 id="光线">光线</h3>
|
||
<ol>
|
||
<li>光线沿直线传播(虽然是错误的)</li>
|
||
<li>光线在相交时互不影响(虽然也是错的)</li>
|
||
<li>光线从光源传播到眼睛(且光路是可逆的)</li>
|
||
</ol>
|
||
<h3 id="ray-casting">Ray Casting</h3>
|
||
<p>1968年由Appel提出</p>
|
||
<ol>
|
||
<li>通过每个像素投射一条光线的方式来生成图像</li>
|
||
<li>通过向光源发送光线的方式来生成阴影</li>
|
||
</ol>
|
||
<p><img src="../../images/Ray_Casting_theory.png" alt=""></p>
|
||
<h4 id="生成视角射线generating-eye-rays">生成视角射线(Generating Eye Rays)</h4>
|
||
<p>Pinhole Camera Model</p>
|
||
<p><img src="../../images/Ray_Casting_Generate_Eye_Ray.png" alt=""></p>
|
||
<h4 id="着色像素shading-pixel">着色像素(shading pixel)</h4>
|
||
<p><img src="../../images/Ray_Casting_shading_pixel.png" alt=""></p>
|
||
<h3 id="递归式光线追踪recursive-ray-tracing">递归式光线追踪(Recursive Ray Tracing)</h3>
|
||
<p>Recursiv Ray Tracing 又名 Whitted-Style Ray Tracing 由T.Whitted在1980年提出</p>
|
||
<p>&quot;An improved Illumination model for shaded display&quot;</p>
|
||
<p><img src="../../images/eg_Recursive_Ray_Tracing.png" alt=""></p>
|
||
<p>总体计算流程</p>
|
||
<p><img src="../../images/Recursive_Ray_Tracing_progress.png" alt=""></p>
|
||
<hr>
|
||
<h4 id="射线表面相交计算ray-surface-intersection">射线表面相交计算(Ray-Surface Intersection)</h4>
|
||
<p>在进行射线表面相交计算前我们需要了解射线方程(Ray Equation)</p>
|
||
<h5 id="ray-equation-and-plane-equation">Ray Equation and Plane Equation</h5>
|
||
<p>射线:由一个起点和一个方向向量定义</p>
|
||
<p>对应的射线方程(Ray Equation)为:
|
||
$$r(t) = o +td , \ \ \ \ 0\leq t &lt; 100 $$</p>
|
||
<p>r:沿射线的点</p>
|
||
<p>t:&quot;时间&quot;</p>
|
||
<p>o:起始点</p>
|
||
<p>d:归一化后的方向向量</p>
|
||
<hr>
|
||
<p>平面:由一个法线向量和在平面上的点定义</p>
|
||
<p>对应的平面方程(Plane Equation)为:
|
||
$$P:(p - p') * N = 0,\ \ \ ax+by+cz+d = 0$$</p>
|
||
<p>p:所有在平面上的点</p>
|
||
<p>p':在平面上的一个点</p>
|
||
<p>N:法线向量</p>
|
||
<h5 id="射线与球体相交ray-intersection-with-sphere">射线与球体相交(Ray Intersection With Sphere)</h5>
|
||
<p>射线:$r(t) = o +td , \ \ \ \ 0\leq t &lt; 100 $</p>
|
||
<p>球体:$p:(p-c)^2 - R^2 = 0 $</p>
|
||
<p>当射线与球体相交时,交点$p$必须同时满足射线和球体的方程</p>
|
||
<p>此时的解为:</p>
|
||
<p>$$(o + td - c )^2 - R^2 = 0$$</p>
|
||
<h5 id="射线与隐式曲面相交ray-intersection-with-implict-surface">射线与隐式曲面相交(Ray Intersection With Implict Surface)</h5>
|
||
<p>射线:$r(t) = o +td , \ \ \ \ 0\leq t &lt; 100 $</p>
|
||
<p>一般隐式曲面:$p:f(p) = 0$</p>
|
||
<p>代入后的替代射线方程:$f(o + td) = 0$</p>
|
||
<p>!解必须为正根</p>
|
||
<h5 id="射线与三角形网格相交ray-intersection-with-triangle-mesh">射线与三角形网格相交(Ray Intersection With Triangle Mesh)</h5>
|
||
<p>原因:</p>
|
||
<ol>
|
||
<li>渲染上:计算可见性,阴影,光照</li>
|
||
<li>几何上:判断内外关系</li>
|
||
</ol>
|
||
<p>计算:拆分</p>
|
||
<ol>
|
||
<li>最简单的方式:对每个三角形进行一次相交判断</li>
|
||
<li>最简单但速度最慢</li>
|
||
<li>可以出现0次相交或一次相交</li>
|
||
</ol>
|
||
<h5 id="射线与三角形相交ray-intersection-with-triangle">射线与三角形相交(Ray Intersection With Triangle)</h5>
|
||
<p>三角形可以视为在一个平面中</p>
|
||
<ol>
|
||
<li>可视为射线与平面相交</li>
|
||
<li>判断相交点是否位于三角形内部即可</li>
|
||
</ol>
|
||
<h5 id="射线与平面相交ray-intersection-with-plane">射线与平面相交(Ray Intersection With Plane)</h5>
|
||
<p>射线方程:$r(t) = o +td , \ \ \ \ 0\leq t &lt; 100 $</p>
|
||
<p>平面方程:$P:(p - p') * N = 0,\ \ \ ax+by+cz+d = 0$</p>
|
||
<p>相交的解为:</p>
|
||
<p>设$p = r(t)$求解$t(0\leq t &lt; \infty)$</p>
|
||
<p>$(p-p') * N = (o + td - p') * N = 0$</p>
|
||
<p>$t = \frac{(p'-o) * N }{d * N}$</p>
|
||
<p><img src="../../images/Ray_Intersection_With_Plane.png" alt=""></p>
|
||
<h5 id="möller-trumbore-algorithm">Möller Trumbore Algorithm</h5>
|
||
<p>一种更快地得出重心坐标的算法</p>
|
||
<p><img src="../../images/M%C3%B6ller_Trumbore_Algorithm.png" alt=""></p>
|
||
<h3 id="光线追踪的性能瓶颈">光线追踪的性能瓶颈</h3>
|
||
<p>通过简单地计算光线与场景的相交的方式:</p>
|
||
<ol>
|
||
<li>需要对场景中每一个三角形判断光线是否相交</li>
|
||
<li>找到最接近的交点(即最小的t值)</li>
|
||
</ol>
|
||
<p>带来的问题:</p>
|
||
<ol>
|
||
<li>算法复杂度 = $pixels \times triangles (\times bounces)$</li>
|
||
<li>计算耗时极高</li>
|
||
</ol>
|
||
<p>解决办法:</p>
|
||
<ol>
|
||
<li>采取遍历物体而非三角形的方式进行计算</li>
|
||
<li>采用相关加速结构/算法</li>
|
||
</ol>
|
||
<hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>几何(geometry)</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E5%87%A0%E4%BD%95geometry/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E5%87%A0%E4%BD%95geometry/</guid>
|
||
<pubDate>Fri, 15 Jul 2022 14:40:43 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="几何">几何</h3>
|
||
<h4 id="几何物体的表现形式">几何物体的表现形式</h4>
|
||
<h5 id="隐式implicit">隐式(Implicit)</h5>
|
||
<ol>
|
||
<li>代数平面(algebraic surface)</li>
|
||
<li>水平集(level sets)</li>
|
||
<li>距离函数(distance functions)</li>
|
||
<li>...</li>
|
||
</ol>
|
||
<h6 id="优缺点">优缺点</h6>
|
||
<p>优点:</p>
|
||
<ol>
|
||
<li>描述简洁(如,一个函数)</li>
|
||
<li>便于某些查询(判定物体内部,或内部点到表面的距离)</li>
|
||
<li>便于计算光线到表面的交集</li>
|
||
<li>对于简单的形状能够做到准确描述无抽样误差</li>
|
||
<li>易于处理拓扑变化(如,流体)</li>
|
||
</ol>
|
||
<p>缺点:</p>
|
||
<ol>
|
||
<li>难以模拟复杂的形状</li>
|
||
</ol>
|
||
<h6 id="基于一系列满足特定关系的点">基于一系列满足特定关系的点</h6>
|
||
<p>例如:</p>
|
||
<p>球体:所有的点在三维坐标系里满足$$x^2 + y^2 + z^2 = 1$$或$$f(x,y,z) = 0 $$</p>
|
||
<h6 id="难以采样">难以采样</h6>
|
||
<p>例如:</p>
|
||
<p>在一系列符合下列条件的点中,难以采样到符合$f(x,y,z) = 0$的点</p>
|
||
<p>$$f(x,y,z) = (2 - \sqrt{x^2 + y^2})^2 + z^2 - 1$$</p>
|
||
<p>对应的几何形状如下图</p>
|
||
<p><img src="../../images/eg_sample_can_be_hard.png" alt=""></p>
|
||
<h6 id="易于判断内外关系">易于判断内外关系</h6>
|
||
<p>例如:</p>
|
||
<p>在一系列符合下述条件的点中</p>
|
||
<p>$$f(x,y,z) = x^2 + y^2 + z^2 - 1$$</p>
|
||
<p><img src="../../images/eg_in_outside_test_easy.png" alt=""></p>
|
||
<p>对于点$(\frac{3}{4},\frac{1}{2},\frac{1}{4})$ 若要判定其是否在该几何体内部则只需计算$$f(x,y,z) = - \frac{1}{8} &lt; 0$$ 即可判定其位于几何体内部</p>
|
||
<hr>
|
||
<h6 id="代数平面algebraic-surfaces">代数平面(Algebraic Surfaces)</h6>
|
||
<p>表面是x,y,z中多项式的零集</p>
|
||
<p><img src="../../images/Algebraic_Surfaces.png" alt=""></p>
|
||
<h6 id="构造实体几何constructive-solid-geometry">构造实体几何(Constructive Solid Geometry)</h6>
|
||
<p>通过布尔计算组合构造隐式几何</p>
|
||
<p><img src="../../images/Constructive_Solid_Geometry.png" alt=""></p>
|
||
<h6 id="距离函数distance-functions">距离函数(Distance Functions)</h6>
|
||
<p>距离函数:从任意位置到目标物体给出最小距离(符号距离)</p>
|
||
<p>使用距离函数将两个曲面混合在一起</p>
|
||
<p><img src="../../images/eg_Distance_Functions.png" alt=""></p>
|
||
<h6 id="水平集level-set-method">水平集(Level Set Method)</h6>
|
||
<p>封闭式的方程难以描述复杂的形状</p>
|
||
<p>解决方案:存储值相似的函数网格</p>
|
||
<p><img src="../../images/Level_Set_grid.png" alt=""></p>
|
||
<p>插值为零的值的位置即为表面</p>
|
||
<p>优势:能够提供对形状更明确的控制(如纹理)</p>
|
||
<p>在流体仿真中也存在应用:计算到气液边界的距离</p>
|
||
<h6 id="分形factals">分形(Factals)</h6>
|
||
<p>该几何形状表现为所有尺度的细节都存在自相似性(一种描述自然现象的说法),往往难以控制形状</p>
|
||
<p><img src="../../images/eg_Factals.png" alt=""></p>
|
||
<hr>
|
||
<h5 id="显式explicit">显式(Explicit)</h5>
|
||
<ol>
|
||
<li>点云(point cloud)</li>
|
||
<li>多边形网格(polygon mesh)</li>
|
||
<li>细分曲面和曲线(subdivision, NURBS)</li>
|
||
<li>...</li>
|
||
</ol>
|
||
<h6 id="点直接或参数映射给出">点直接或参数映射给出</h6>
|
||
<p>例如:</p>
|
||
<p>$$f:R^2 \rightarrow R^3;(u,v) \rightarrow (x,y,z)$$</p>
|
||
<p><img src="../../images/eg_explict_mapping.png" alt=""></p>
|
||
<h6 id="易于采样">易于采样</h6>
|
||
<p>例如:</p>
|
||
<p>对于$$ f(u,v) = ((2 + \cos u)\cos v,(2 + \cos u)\sin v,\sin u) $$</p>
|
||
<p>若要判定点$f(u,v)$是否位于表面,则只需将$(u,v)$的值相加</p>
|
||
<p><img src="../../images/eg_sample_can_be_hard.png" alt=""></p>
|
||
<h6 id="难以判断内外关系">难以判断内外关系</h6>
|
||
<p>例如:
|
||
对于$$f(u,v) = (\cos u \sin v ,\sin u \sin v,\cos v)$$</p>
|
||
<p>难以判定点$(\frac{3}{4},\frac{1}{2},\frac{1}{4})$</p>
|
||
<hr>
|
||
<h6 id="点云-point-cloud">点云 (Point Cloud)</h6>
|
||
<ol>
|
||
<li>最简单的表示:点列表(x,y,z)</li>
|
||
<li>轻松表现任何类型的几何图形</li>
|
||
<li>适用于大型数据集(&gt;&gt; 1 点/像素)</li>
|
||
<li>通常转换为多边形网格</li>
|
||
<li>难以用于采样不足的区域</li>
|
||
</ol>
|
||
<p><img src="../../images/eg_point_cloud.png" alt=""></p>
|
||
<h6 id="多边形网格polygon-mesh">多边形网格(Polygon Mesh)</h6>
|
||
<ol>
|
||
<li>存储顶点和多边形(通常是三角形或四边形)</li>
|
||
<li>更易于进行处理/模拟,自适应采样</li>
|
||
<li>更复杂的数据结构</li>
|
||
<li>图形中最常见的表示形式</li>
|
||
</ol>
|
||
<p><img src="../../images/eg_polygon_mesh.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="表现形式应根据目标几何模型选择最合适的类型没有最好的表现形式">表现形式应根据目标几何模型选择最合适的类型,没有最好的表现形式</h3>
|
||
<p><img src="../../images/David_Baraff.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="贝塞尔曲线bézier-curves">贝塞尔曲线(Bézier Curves)</h3>
|
||
<h4 id="定义">定义</h4>
|
||
<p>贝塞尔曲线完全由其控制点决定其形状,$n$个控制点对应着$n-1$阶的贝塞尔曲线,并且可以通过递归的方式来绘制.</p>
|
||
<p><img src="../../images/Defining_Bezier_Curve_Tangents.png" alt=""></p>
|
||
<h4 id="de-casteljau-algorithm图形">de Casteljau Algorithm(图形)</h4>
|
||
<p>假设存在三个点(quadratic Bezier)</p>
|
||
<p><img src="../../images/de_Casteljau_Algorithm_step1.png" alt=""></p>
|
||
<p>通过线性插值的方式插入一个点</p>
|
||
<p><img src="../../images/de_Casteljau_Algorithm_step2.png" alt=""></p>
|
||
<p>在另一边也通过同样方式插入一个点</p>
|
||
<p><img src="../../images/de_Casteljau_Algorithm_step3.png" alt=""></p>
|
||
<p>递归重复</p>
|
||
<p><img src="../../images/de_Casteljau_Algorithm_step4.png" alt=""></p>
|
||
<p>对于在$[0,1]$区间的每个t点都使用相同算法进行计算</p>
|
||
<p><img src="../../images/de_Casteljau_Algorithm_step5.png" alt=""></p>
|
||
<p>构造一个三次方贝塞尔曲线需要总共四个输入,都递归使用线性插值</p>
|
||
<p><img src="../../images/de_Casteljau_Algorithm_step6.png" alt=""></p>
|
||
<p>可视化算法流程</p>
|
||
<p><img src="../../images/Visualizing_de_Casteljau.png" alt=""></p>
|
||
<h4 id="de-casteljau-algorithm数学公式">de Casteljau Algorithm(数学公式)</h4>
|
||
<p>de Casteljau 算法给出各点间金字塔型的变量关系</p>
|
||
<p><img src="../../images/de_Casteljau_pyramid_of.png" alt=""></p>
|
||
<h5 id="推导流程">推导流程</h5>
|
||
<p><img src="../../images/de_Casteljau_Algorithm_step5.png" alt=""></p>
|
||
<p>$$b_0^1(t) = (1 - t)b_0 + tb_1$$
|
||
$$b_1^1(t) = (1 - t)b_1 + tb_2$$
|
||
$$b_0^2(t) = (1 - t)b_0^1 + tb_1^1$$
|
||
$$b_0^2(t) = (1 - t)^2b_0 + 2t(1 - t)b_1 + t^2b_2$$</p>
|
||
<p>进而推得$n$阶贝塞尔曲线的公式为:</p>
|
||
<p>$$b^n(t) = b_0^n(t) = \sum_{j=0}^{n} {b_j B_j^n(t)}$$</p>
|
||
<p>$b^n(t)$:贝塞尔曲线阶级数n(n次向量多项式)</p>
|
||
<p>$b_j$:控制点($R^N$的向量)</p>
|
||
<p>$B_j^n$:伯恩斯坦多项式</p>
|
||
<p>伯恩斯坦多项式(Bernstein polynomial):</p>
|
||
<p>$$B_i^n(t) = \begin{pmatrix} n \\ t \end{pmatrix} t^i(1 - t)^{n - i}$$</p>
|
||
<p>例如$n = 3$时</p>
|
||
<p>我们在三维空间里有下列控制点</p>
|
||
<p>$b_0 = (0,2,3),b_1 = (2,3,5),b_2 = (6,7,9),b_3 = (3,4,5)$</p>
|
||
<p>这些点定义了以下列公式形式的贝塞尔曲线</p>
|
||
<p>$$b^n(t) = b_0(1 - t)^3 + b_1 3t(1 - t)^2 + b_2 3t^2(1 - t) + b_3 t^3$$</p>
|
||
<p>贝塞尔基本函数</p>
|
||
<p><img src="../../images/Cubic_Bezier_Basis_Functions.png" alt=""></p>
|
||
<p>插值端点:$b(0) = b_0;b(1) = b_3$</p>
|
||
<p>与末端线段相切:$b'(0) = 3(b_1 - b_0); b'(1) = 3(b_3 - b_2)$</p>
|
||
<p>能够通过控制点的位置来改变曲线</p>
|
||
<h3 id="分段贝塞尔曲线">分段贝塞尔曲线</h3>
|
||
<p>出现原因:高阶贝塞尔曲线有多个控制点,难以控制曲线形状</p>
|
||
<p>对策: 将多个低阶的贝塞尔曲线相连,构造为分段贝塞尔曲线</p>
|
||
<p>常用于:字体,路径,插画,主题演讲</p>
|
||
<p>样例:</p>
|
||
<p><img src="../../images/Demon_Piecewise_Cubic_Bezier_Curve.png" alt=""></p>
|
||
<h4 id="组合计算">组合计算</h4>
|
||
<p>要将一下两条贝塞尔曲线组合在一起则</p>
|
||
<p>$$a:[k,k+1] \rightarrow IR^N$$
|
||
$$b:[k+1,k+2] \rightarrow IR^N$$</p>
|
||
<p><img src="../../images/Continuity_Piecewise_Bezier_step1.png" alt=""></p>
|
||
<p>$c^0$处的连续性:$a_n = b_0$</p>
|
||
<p><img src="../../images/Continuity_Piecewise_Bezier_step2.png" alt=""></p>
|
||
<p>$c^1$处的连续性:$a_n = b_0 = \frac{1}{2}(a_{n-1} + b_1)$</p>
|
||
<p><img src="../../images/Continuity_Piecewise_Bezier_step3.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="贝塞尔表面bézier-surfaces">贝塞尔表面(Bézier Surfaces)</h3>
|
||
<p>对于一个双立方贝塞尔表面贴片</p>
|
||
<p>输入:$4 \times 4 $ 控制点</p>
|
||
<p>输出:由$[0,1]^2$ 参数化的2D平面</p>
|
||
<p><img src="../../images/bezier_surface_eg.png" alt=""></p>
|
||
<h4 id="计算方法">计算方法</h4>
|
||
<p>目标:计算相对于(u,v)的平面位置</p>
|
||
<ol>
|
||
<li>使用 de Casteljau 算法来计算四条贝塞尔曲线上各自的U,这将会为&quot;移动&quot;贝塞尔曲线提供4个有效的控制点</li>
|
||
<li>使用一阶 de Casteljau 算法来计算&quot;移动&quot;曲线上的点V</li>
|
||
</ol>
|
||
<p><img src="../../images/evaluation_of_bezier_surface.png" alt=""></p>
|
||
<p>可视化计算流程:</p>
|
||
<p><img src="../../images/visual_evaluation_of_bezier_surface.png" alt=""></p>
|
||
<h3 id="曲面处理mesh-operations">曲面处理(Mesh Operations)</h3>
|
||
<h4 id="曲面细分mesh-subdivision">曲面细分(Mesh Subdivision)</h4>
|
||
<p>目的:提高分辨率</p>
|
||
<p><img src="../../images/eg_mesh_subdivision.png" alt=""></p>
|
||
<p>通常做法:</p>
|
||
<ol>
|
||
<li>创建更多三角形(顶点)</li>
|
||
<li>更新它们的位置</li>
|
||
</ol>
|
||
<h5 id="loop-subdivision">Loop Subdivision</h5>
|
||
<ol>
|
||
<li>将每个三角形划分为4个三角形</li>
|
||
<li>根据权重更新顶点的位置(新旧顶点各自以不同方式进行更新)</li>
|
||
</ol>
|
||
<p>新顶点:</p>
|
||
<p><img src="../../images/loop_subdivision_new.png" alt=""></p>
|
||
<p>白点即为新顶点,其位置为周围四个顶点的权重之和</p>
|
||
<p>旧顶点:</p>
|
||
<p><img src="../../images/loop_subdivision_old.png" alt=""></p>
|
||
<p>白色旧顶点也是自身及邻接顶点的权重之和,权重的设置与旧顶点度数关联</p>
|
||
<h5 id="catmull-clark-subdivision">Catmull-Clark Subdivision</h5>
|
||
<p><img src="../../images/catmull-clark_subdivision1.png" alt=""></p>
|
||
<p>定义:</p>
|
||
<ol>
|
||
<li>所有非四边形的面都称为Non-quad face</li>
|
||
<li>所有度不为4的点称为奇异点</li>
|
||
<li>每次细分时在每个面中添加一个点,每条边的中点也都添加一个点,面上的新顶点连接所有边上的新顶点</li>
|
||
</ol>
|
||
<p>第一次细分后结果:</p>
|
||
<p><img src="../../images/catmull-clark_subdivision2.png" alt=""></p>
|
||
<p>特点:</p>
|
||
<ol>
|
||
<li>非四边形面的数量与奇异点相同,即现在共有$2+2=4$个</li>
|
||
<li>奇异点的度数与原来所在面的边数相等,即这里为3度</li>
|
||
<li>第一次细分后所有的面都会变成四边形,且后续奇异点数目不再增加</li>
|
||
</ol>
|
||
<p>Catmull-Clark 顶点更新规则</p>
|
||
<p><img src="../../images/Catmull-Clark_Vertex_Update_Rules.png" alt=""></p>
|
||
<h5 id="收敛性整体形状和折痕">收敛性:整体形状和折痕</h5>
|
||
<p><img src="../../images/convergence_of_loop_and_catmull.png" alt=""></p>
|
||
<h4 id="曲面简化mesh-simplification">曲面简化(Mesh Simplification)</h4>
|
||
<p>目的:降低分辨率的同时尽量保持形状/外观</p>
|
||
<p><img src="../../images/eg_mesh_simplification.png" alt=""></p>
|
||
<h5 id="边坍缩">边坍缩</h5>
|
||
<p>边坍缩是曲面简化的常用方法,如上图所示将一条边的两个顶点合成为一个顶点,出于尽量保持形状的目的,需要正确选择不影响或影响最小的边进行坍缩,由此引入二次误差度量(Quadric Error Metrics)</p>
|
||
<p><img src="../../images/Collapsing_An_Edge.png" alt=""></p>
|
||
<h6 id="二次误差度量quadric-error-metrics">二次误差度量(Quadric Error Metrics)</h6>
|
||
<p><img src="../../images/Quadric_Error_Metrics.png" alt=""></p>
|
||
<p>坍缩之后蓝色新顶点所在位置与原来各个平面的垂直距离之和,如此误差最小则整个模型样貌修改一定程度也会较小</p>
|
||
<h5 id="曲面简化算法流程">曲面简化算法流程</h5>
|
||
<ol>
|
||
<li>为模型每条边赋值,其值为坍缩后代替老顶点产生的新顶点所得到的最小二次误差</li>
|
||
<li>选取权重最小的边做坍缩,新顶点的位置为原计算得出使二次误差值最小的位置</li>
|
||
<li>坍缩之后,会改动与之相连的其他边,更新这些边的权值</li>
|
||
<li>重复步骤,直到符合终止条件</li>
|
||
</ol>
|
||
<p>符合贪心算法标准,无法获得最优解,但效果依旧合适</p>
|
||
<p><img src="../../images/eg_Quadric_Error_Mesh_Simplification.png" alt=""></p>
|
||
<hr>
|
||
<h4 id="纹理映射shadow-mapping">纹理映射(Shadow Mapping)</h4>
|
||
<p>Shadow Mapping是一种基于图像的算法</p>
|
||
<ol>
|
||
<li>阴影计算期间无需进行几何体计算</li>
|
||
<li>必须进行反走样处理</li>
|
||
<li>不在阴影中的点必须同时在灯光和相机范围内</li>
|
||
</ol>
|
||
<h5 id="计算流程">计算流程</h5>
|
||
<p>阴影映射总体需要两个pass</p>
|
||
<p>Pass1:render from light</p>
|
||
<ol>
|
||
<li>获得从光源视角得到的深度图像</li>
|
||
</ol>
|
||
<p><img src="../../images/render_from_light.png" alt=""></p>
|
||
<p>Pass2:render from eye</p>
|
||
<ol>
|
||
<li>从观看视角(相机视角)获得带有深度的标准图像</li>
|
||
<li>将观看视角中的可见点投影回光源
|
||
<ol>
|
||
<li>光源和观看视角的下的深度相同时为可见</li>
|
||
<li>光源和观看视角下的深度不相同则为被阻挡</li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
<p><img src="../../images/project_to_light.png" alt=""></p>
|
||
<hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>纹理</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E7%BA%B9%E7%90%86/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E7%BA%B9%E7%90%86/</guid>
|
||
<pubDate>Sat, 09 Jul 2022 21:49:09 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h4 id="重心坐标">重心坐标</h4>
|
||
<h6 id="重心坐标定义">重心坐标定义</h6>
|
||
<p><img src="http://www.inksoul.top/../../images/barycentric_coordinates.png" alt=""></p>
|
||
<p>对于一个三角形的三点坐标A,B,C,平面内的一点(x,y)可以写成三点的线性组合式</p>
|
||
<p>$$(x,y)=\alpha A + \beta B + \gamma C = \alpha + \beta + \gamma = 1$$</p>
|
||
<p>此时三个顶点的权重($\alpha , \beta , \gamma$)为(x,y)的重心坐标</p>
|
||
<p>注意:如果三个坐标值都为非负,则这个重心位于三角形内部</p>
|
||
<h6 id="三角形的几何角度下求解">三角形的几何角度下求解</h6>
|
||
<p><img src="../../images/geometric_barycentric.png" alt=""></p>
|
||
<p>将点与三个顶点相连,三个三角形的面积分别为$A_A,A_B,A_C$对应的重心坐标的计算式,</p>
|
||
<p>$$\alpha = \frac{A_A}{A_A+A_B+A_C}$$</p>
|
||
<p>$$\beta = \frac{A_B}{A_A+A_B+A_C}$$</p>
|
||
<p>$$\gamma = \frac{A_C}{A_A+A_B+A_C}$$</p>
|
||
<p>在已知四点坐标的情况下则可通过行列式的几何意义求解(任意两个二维向量组合成矩阵的行列式的绝对值为这两条向量所围成平行四边形的面积)</p>
|
||
<p>设任意一点为P(x,y)则</p>
|
||
<p>$$A_B = \lvert AP,AC \rvert $$
|
||
$$A_C = \lvert AB,AP \rvert $$
|
||
$$A_A = \lvert BC,BP \rvert $$</p>
|
||
<p>可得出
|
||
$$\gamma = \frac{(y_a - y_b) + (x_b - x_a)y + x_a y_b - x_b y_a }{(y_a - y_b)x_c + (x_b - x_a)y_c + x_a y_b - x_b y_a}$$</p>
|
||
<p>$$\beta = \frac{(y_a - y_c)x + (x_c - x_a)y + x_a y_c - x_c y_a}{(y_a - y_c)x_b + (x_c - x_a)y_b + x_a y_c - x_c y_a}$$</p>
|
||
<p>$$\alpha = 1 - \beta - \gamma$$</p>
|
||
<h6 id="三角形的坐标系角度下求解">三角形的坐标系角度下求解</h6>
|
||
<p>对于重心坐标系存在另一种等价视角:</p>
|
||
<p>以A点为原点,AB,AC分别为新的坐标系的单位向量构建坐标系,如图</p>
|
||
<p><img src="../../images/barycentric_in_coordinates.jpg" alt=""></p>
|
||
<p>给定的任意点P的坐标可表示为$P(\beta , \gamma)$ ,可推出P点坐标满足以下关系</p>
|
||
<p>$$p = a + \beta(b - a) + \gamma(c - a)$$</p>
|
||
<p>化简后得</p>
|
||
<p>$$p = (1 - \beta - \gamma )a + \beta b + \gamma c $$</p>
|
||
<p>表现为一个线性方程组如下</p>
|
||
<p>$$
|
||
\begin{bmatrix}
|
||
x_b - x_a &amp; x_c - x_a
|
||
\\
|
||
y_b - y_a &amp; y_c - y_a
|
||
\end{bmatrix}
|
||
\begin{bmatrix}
|
||
\beta
|
||
\\
|
||
\gamma
|
||
\end{bmatrix}=
|
||
\begin{bmatrix}
|
||
x_p - x_a
|
||
\\
|
||
y_p - y_a
|
||
\end{bmatrix}
|
||
$$</p>
|
||
<h6 id="重心坐标的用处">重心坐标的用处</h6>
|
||
<p>对顶点处的值进行线性插值,如下图</p>
|
||
<p><img src="../../images/barycentric_coor_interpo.png" alt=""></p>
|
||
<p>$$V = \alpha V_A + \beta V_B + \gamma V_C$$</p>
|
||
<p>$V_A,V_B,V_C$ 可以对应为:</p>
|
||
<ol>
|
||
<li>位置</li>
|
||
<li>纹理坐标</li>
|
||
<li>颜色</li>
|
||
<li>法线</li>
|
||
<li>深度</li>
|
||
<li>材质属性</li>
|
||
</ol>
|
||
<h6 id="插值部分代码实现">插值部分代码实现</h6>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="c1">//三维向量插值
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span> <span class="n">interpolate</span><span class="p">(</span><span class="kt">float</span> <span class="n">alpha</span><span class="p">,</span> <span class="kt">float</span> <span class="n">beta</span><span class="p">,</span> <span class="kt">float</span> <span class="n">gamma</span><span class="p">,</span> <span class="k">const</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span><span class="o">&amp;</span> <span class="n">vert1</span><span class="p">,</span> <span class="k">const</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span><span class="o">&amp;</span> <span class="n">vert2</span><span class="p">,</span> <span class="k">const</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span><span class="o">&amp;</span> <span class="n">vert3</span><span class="p">,</span> <span class="kt">float</span> <span class="n">weight</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="p">(</span><span class="n">alpha</span> <span class="o">*</span> <span class="n">vert1</span> <span class="o">+</span> <span class="n">beta</span> <span class="o">*</span> <span class="n">vert2</span> <span class="o">+</span> <span class="n">gamma</span> <span class="o">*</span> <span class="n">vert3</span><span class="p">)</span> <span class="o">/</span> <span class="n">weight</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="c1"></span><span class="k">static</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span> <span class="n">interpolate</span><span class="p">(</span><span class="kt">float</span> <span class="n">alpha</span><span class="p">,</span> <span class="kt">float</span> <span class="n">beta</span><span class="p">,</span> <span class="kt">float</span> <span class="n">gamma</span><span class="p">,</span> <span class="k">const</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span><span class="o">&amp;</span> <span class="n">vert1</span><span class="p">,</span> <span class="k">const</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span><span class="o">&amp;</span> <span class="n">vert2</span><span class="p">,</span> <span class="k">const</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span><span class="o">&amp;</span> <span class="n">vert3</span><span class="p">,</span> <span class="kt">float</span> <span class="n">weight</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">auto</span> <span class="n">u</span> <span class="o">=</span> <span class="p">(</span><span class="n">alpha</span> <span class="o">*</span> <span class="n">vert1</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">beta</span> <span class="o">*</span> <span class="n">vert2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">gamma</span> <span class="o">*</span> <span class="n">vert3</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">auto</span> <span class="n">v</span> <span class="o">=</span> <span class="p">(</span><span class="n">alpha</span> <span class="o">*</span> <span class="n">vert1</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">beta</span> <span class="o">*</span> <span class="n">vert2</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">gamma</span> <span class="o">*</span> <span class="n">vert3</span><span class="p">[</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="n">u</span> <span class="o">/=</span> <span class="n">weight</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">v</span> <span class="o">/=</span> <span class="n">weight</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="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</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="p">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="c1">//计算重心
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o">&lt;</span><span class="kt">float</span><span class="p">,</span> <span class="kt">float</span><span class="p">,</span> <span class="kt">float</span><span class="o">&gt;</span> <span class="n">computeBarycentric2D</span><span class="p">(</span><span class="kt">float</span> <span class="n">x</span><span class="p">,</span> <span class="kt">float</span> <span class="n">y</span><span class="p">,</span> <span class="k">const</span> <span class="n">Vector4f</span><span class="o">*</span> <span class="n">v</span><span class="p">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">c1</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">+</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">())</span><span class="o">*</span><span class="n">y</span> <span class="o">+</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">/</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">+</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">())</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">+</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">());</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">c2</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">+</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">())</span><span class="o">*</span><span class="n">y</span> <span class="o">+</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">/</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">+</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">())</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">+</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">());</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">c3</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">+</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">())</span><span class="o">*</span><span class="n">y</span> <span class="o">+</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">/</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">())</span> <span class="o">+</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">())</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">+</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span><span class="o">*</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">());</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span><span class="n">c1</span><span class="p">,</span><span class="n">c2</span><span class="p">,</span><span class="n">c3</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="c1"></span>
|
||
</span></span><span class="line"><span class="cl"><span class="c1">// auto interpolated_color(颜色)
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">auto</span> <span class="n">interpolated_color</span><span class="o">=</span><span class="n">interpolate</span><span class="p">(</span><span class="n">alpha</span><span class="p">,</span><span class="n">beta</span><span class="p">,</span><span class="n">gamma</span><span class="p">,</span><span class="n">t</span><span class="p">.</span><span class="n">color</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">t</span><span class="p">.</span><span class="n">color</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">t</span><span class="p">.</span><span class="n">color</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="c1">// auto interpolated_normal(法线)
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">auto</span> <span class="n">interpolated_normal</span> <span class="o">=</span> <span class="n">interpolate</span><span class="p">(</span><span class="n">alpha</span><span class="p">,</span><span class="n">beta</span><span class="p">,</span><span class="n">gamma</span><span class="p">,</span><span class="n">t</span><span class="p">.</span><span class="n">normal</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">t</span><span class="p">.</span><span class="n">normal</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">t</span><span class="p">.</span><span class="n">normal</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span><span class="mi">1</span><span class="p">).</span><span class="n">normalized</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"><span class="c1">// auto interpolated_texcoords(纹理坐标)
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">auto</span> <span class="n">interpolated_texcoords</span> <span class="o">=</span> <span class="n">interpolate</span><span class="p">(</span><span class="n">alpha</span><span class="p">,</span><span class="n">beta</span><span class="p">,</span><span class="n">gamma</span><span class="p">,</span><span class="n">t</span><span class="p">.</span><span class="n">tex_coords</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">t</span><span class="p">.</span><span class="n">tex_coords</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">t</span><span class="p">.</span><span class="n">tex_coords</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="c1">// auto interpolated_shadingcoords(着色坐标)
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">auto</span> <span class="n">interpolated_shadingcoords</span> <span class="o">=</span> <span class="n">interpolate</span><span class="p">(</span><span class="n">alpha</span><span class="p">,</span><span class="n">beta</span><span class="p">,</span><span class="n">gamma</span><span class="p">,</span><span class="n">view_pos</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">view_pos</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">view_pos</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></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h4 id="纹理映射处理">纹理映射处理</h4>
|
||
<h6 id="简单的纹理映射--漫反射颜色">简单的纹理映射 : 漫反射颜色</h6>
|
||
<p>伪代码 :</p>
|
||
<pre tabindex="0"><code>for each rasterized screen sample (x,y):
|
||
(u,v) = evaluate texture coordinate at (x,y)
|
||
texcolor = texture.sample(u,v);
|
||
set sample&#39;s color to texcolor
|
||
</code></pre><p>sample(x,y) : 通常为像素的重心</p>
|
||
<p>texture coordinate at (x,y):使用重心坐标值</p>
|
||
<p>sample's color : 通常为漫反射率值 kd</p>
|
||
<h6 id="纹理放大处理简单方式">纹理放大处理(简单方式)</h6>
|
||
<p>前置知识:</p>
|
||
<ol>
|
||
<li>通常不需要进行纹理放大操作,这会导致纹理分辨率不足</li>
|
||
<li>纹理的一个像素通常被称为纹理元素或纹素(texel)</li>
|
||
</ol>
|
||
<p>假设我们需要在红点处纹理采样的值f(x,y),黑点为对应的纹理采样点</p>
|
||
<p>此时我们会选取红点位置周围的四个采样点,同时计算其与周围四个采样点的偏移值(s,t)如下图</p>
|
||
<p><img src="../../images/bilinear_interpolation.png" alt=""></p>
|
||
<p>可得相应的计算过程:</p>
|
||
<ol>
|
||
<li>
|
||
<p>定义线性插值
|
||
$$lerp(x,v_0,v_1) = v_0 + x(v_1 - v_0)$$</p>
|
||
</li>
|
||
<li>
|
||
<p>计算两个辅助值
|
||
$$u_0 = lerp(s,u_{00},u_{10})$$
|
||
$$u_1 = lerp(s,u_{01},u_{11})$$</p>
|
||
</li>
|
||
<li>
|
||
<p>计算顶点插值得出结果
|
||
$$f(x,y) = lerp(t,u_0,u_1)$$</p>
|
||
</li>
|
||
</ol>
|
||
<p>采用线性插值的方式进行纹理放大的计算往往能够获得很好的结果和平衡的性能消耗</p>
|
||
<h6 id="纹理放大至过大的情况">纹理放大至过大的情况</h6>
|
||
<p>此时在点采样下会产生摩尔纹和锯齿,如下图</p>
|
||
<p><img src="../../images/moire_and_jaggies.png" alt=""></p>
|
||
<p>通常处理是进行超采样,同时也会有几个问题</p>
|
||
<ol>
|
||
<li>超采样能产生质量足够高的结果,带来的性能开销也很高</li>
|
||
<li>当纹理极度缩小时,许多纹素会被压缩在内存(texel footprint)里</li>
|
||
<li>单一像素中的信号序列过大</li>
|
||
<li>需要更高的采样频率</li>
|
||
</ol>
|
||
<p>所以我们更倾向于使用范围序列而非点序列</p>
|
||
<p><img src="../../images/point_query_and_range_query.png" alt=""></p>
|
||
<h6 id="mipmap支持-range-query">Mipmap(支持 Range Query)</h6>
|
||
<p>mipmap 可由下图表示</p>
|
||
<p><img src="../../images/mipmap_information.png" alt=""></p>
|
||
<p>对应产生的mip层次结构也由下图表示</p>
|
||
<p><img src="../../images/mip_hierarchy.png" alt=""></p>
|
||
<p>在计算对应层次的mipmap时,我们需要相邻采样点的纹理坐标来估计纹理内存</p>
|
||
<p><img src="../../images/compute_mip_level_D.png" alt=""></p>
|
||
<p>如上图所示,我们能够得到两个值</p>
|
||
<p>$$L = \max \left( \sqrt{(\frac{d_u}{d_X})^2 + (\frac{d_v}{d_X})^2},\sqrt{(\frac{d_u}{d_y})^2 + (\frac{d_v}{d_y})^2} \right) $$</p>
|
||
<p>$$D = \log_2 L$$</p>
|
||
<p>在使用时往往D值会四舍五入为整数,这会导致纹理的不连续,因此,我们还需要进行下图所示的Trilinear Interpolation 从而得到一个连续的D值</p>
|
||
<p><img src="../../images/Trilinear_interpolation.png" alt=""></p>
|
||
<p>在插值处理后的纹理依旧会存在过度模糊(overblur)的现象,但相比于超采样的高性能开销依旧有很大的提升</p>
|
||
<h6 id="anisotropic-filtering-and-ewa-filtering">Anisotropic Filtering and EWA filtering</h6>
|
||
<p>Anisotropic Filtering</p>
|
||
<ol>
|
||
<li>可以查找轴对齐的矩形区域纹理</li>
|
||
<li>对角线纹理处理依旧存在问题</li>
|
||
</ol>
|
||
<p><img src="../../images/Anisotropic_filtering.png" alt=""></p>
|
||
<p>EWA filtering</p>
|
||
<ol>
|
||
<li>权重均衡</li>
|
||
<li>采用mipmap层次结构</li>
|
||
<li>可以处理纹理中的不规则像素(irregular footprints)</li>
|
||
</ol>
|
||
<p>Irregular Pixel Footprint in Texture的产生情况如下图</p>
|
||
<p><img src="../../images/irregular_pixel_footprint.png" alt=""></p>
|
||
<h4 id="纹理的应用">纹理的应用</h4>
|
||
<h5 id="纹理的用途">纹理的用途</h5>
|
||
<p>在现代GPU中,纹理贴图 = 内存数据 + 范围序列(reang query)即反走样</p>
|
||
<p>常用的方式是向片元计算中提供相应的数据</p>
|
||
<p>应用的地方:</p>
|
||
<ol>
|
||
<li>环境光</li>
|
||
<li>存储微表面</li>
|
||
<li>程序化纹理生成</li>
|
||
<li>实体建模</li>
|
||
<li>立体渲染(体绘制)</li>
|
||
</ol>
|
||
<h6 id="环境光贴图和立方体贴图environment-and-cube-map">环境光贴图和立方体贴图(Environment and Cube Map)</h6>
|
||
<p>环境光贴图通常指在贴图上绘制模型周围环境光效,实现某些模型反射环境光的效果</p>
|
||
<p><img src="../../images/Environment_Map.png" alt=""></p>
|
||
<p>也用于一些镜面反射的物体实现真实光照</p>
|
||
<p><img src="../../images/Environmental_Lighting.png" alt=""></p>
|
||
<p><img src="../../images/Spherical_Environment_Map.png" alt=""></p>
|
||
<p>在一些球型表面贴图会存在形变问题,如下图的顶部和底部</p>
|
||
<p><img src="../../images/Spherical_Map_Problem.png" alt=""></p>
|
||
<p>立方体贴图则由球体上一个向量沿自身方向映射到立方体上的点获得</p>
|
||
<p><img src="../../images/Cube_Map.png" alt=""></p>
|
||
<p>一个立方体使用6个方形纹理贴图来生成纹理</p>
|
||
<h6 id="bump-mapping">Bump Mapping</h6>
|
||
<p>在不提高模型面数的情况下展示表面细节</p>
|
||
<ol>
|
||
<li>对表面的每一条法线进行扰动(仅用于着色计算)</li>
|
||
<li>高度偏移纹理定义的每个纹素</li>
|
||
</ol>
|
||
<p>扰动法线的计算(平面)</p>
|
||
<ol>
|
||
<li>假设原平面法线为$$n(p) = (0,1)$$</li>
|
||
<li>$ p $点处的导数为 $$dp = c * [h(p + 1) - h(p)]$$</li>
|
||
<li>扰动后的法线值为$$n(p) = (-dp,1).normalized()$$</li>
|
||
</ol>
|
||
<p><img src="../../images/perturb_the_normal.png" alt=""></p>
|
||
<p>扰动法线的计算(3D)</p>
|
||
<ol>
|
||
<li>假设原平面法线为$$n(p) = (0,0,1)$$</li>
|
||
<li>$p$点处的导数为
|
||
$$\frac{d_p}{d_u} = c_1 * [h(u + 1) - h(u)]$$
|
||
$$\frac{d_p}{d_v} = c_2 * [h(v + 1) - h(v)]$$</li>
|
||
<li>扰动后的法线为$$n = (\frac{-d_p}{d_u},\frac{-d_p}{d_v},1).normalized()$$</li>
|
||
<li>坐标计算基于本地坐标系</li>
|
||
</ol>
|
||
<p>部份代码实现</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">x</span> <span class="o">=</span> <span class="n">normal</span><span class="p">.</span><span class="n">x</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">y</span> <span class="o">=</span> <span class="n">normal</span><span class="p">.</span><span class="n">y</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">z</span> <span class="o">=</span> <span class="n">normal</span><span class="p">.</span><span class="n">z</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span> <span class="n">t</span> <span class="o">=</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">y</span><span class="o">/</span><span class="n">sqrt</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="o">+</span><span class="n">z</span><span class="o">*</span><span class="n">z</span><span class="p">),</span><span class="n">sqrt</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="o">+</span><span class="n">z</span><span class="o">*</span><span class="n">z</span><span class="p">),</span><span class="n">z</span><span class="o">*</span><span class="n">y</span><span class="o">/</span><span class="n">sqrt</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="o">+</span><span class="n">z</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">Eigen</span><span class="o">::</span><span class="n">Vector3f</span> <span class="n">b</span> <span class="o">=</span> <span class="n">normal</span><span class="p">.</span><span class="n">cross</span><span class="p">(</span><span class="n">t</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Eigen</span><span class="o">::</span><span class="n">Matrix3f</span> <span class="n">TBN</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">TBN</span> <span class="o">&lt;&lt;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">t</span><span class="p">.</span><span class="n">x</span><span class="p">(),</span><span class="n">b</span><span class="p">.</span><span class="n">y</span><span class="p">(),</span><span class="n">normal</span><span class="p">.</span><span class="n">x</span><span class="p">(),</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">t</span><span class="p">.</span><span class="n">y</span><span class="p">(),</span><span class="n">b</span><span class="p">.</span><span class="n">x</span><span class="p">(),</span><span class="n">normal</span><span class="p">.</span><span class="n">y</span><span class="p">(),</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">t</span><span class="p">.</span><span class="n">z</span><span class="p">(),</span><span class="n">b</span><span class="p">.</span><span class="n">z</span><span class="p">(),</span><span class="n">normal</span><span class="p">.</span><span class="n">z</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">u</span> <span class="o">=</span> <span class="n">payload</span><span class="p">.</span><span class="n">tex_coords</span><span class="p">.</span><span class="n">x</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">v</span> <span class="o">=</span> <span class="n">payload</span><span class="p">.</span><span class="n">tex_coords</span><span class="p">.</span><span class="n">y</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">w</span> <span class="o">=</span> <span class="n">payload</span><span class="p">.</span><span class="n">texture</span><span class="o">-&gt;</span><span class="n">width</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">h</span> <span class="o">=</span> <span class="n">payload</span><span class="p">.</span><span class="n">texture</span><span class="o">-&gt;</span><span class="n">height</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">dU</span><span class="o">=</span><span class="n">kh</span> <span class="o">*</span> <span class="n">kn</span> <span class="o">*</span> <span class="p">(</span><span class="n">payload</span><span class="p">.</span><span class="n">texture</span><span class="o">-&gt;</span><span class="n">getColor</span><span class="p">(</span><span class="n">u</span><span class="o">+</span><span class="mf">1.0f</span><span class="o">/</span><span class="n">w</span><span class="p">,</span><span class="n">v</span><span class="p">).</span><span class="n">norm</span><span class="p">()</span><span class="o">-</span><span class="n">payload</span><span class="p">.</span><span class="n">texture</span><span class="o">-&gt;</span><span class="n">getColor</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="n">norm</span><span class="p">());</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">dV</span><span class="o">=</span><span class="n">kh</span> <span class="o">*</span> <span class="n">kn</span> <span class="o">*</span> <span class="p">(</span><span class="n">payload</span><span class="p">.</span><span class="n">texture</span><span class="o">-&gt;</span><span class="n">getColor</span><span class="p">(</span><span class="n">u</span><span class="p">,</span><span class="n">v</span><span class="o">+</span><span class="mf">1.0f</span><span class="o">/</span><span class="n">h</span><span class="p">).</span><span class="n">norm</span><span class="p">()</span><span class="o">-</span><span class="n">payload</span><span class="p">.</span><span class="n">texture</span><span class="o">-&gt;</span><span class="n">getColor</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="n">norm</span><span class="p">());</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span> <span class="n">ln</span> <span class="o">=</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span><span class="p">(</span><span class="o">-</span><span class="n">dU</span><span class="p">,</span><span class="o">-</span><span class="n">dV</span><span class="p">,</span><span class="mf">1.0f</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">normal</span><span class="o">=</span><span class="n">TBN</span> <span class="o">*</span><span class="n">ln</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">// Let n = normal = (x, y, z)
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Vector b = n cross product t
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Matrix TBN = [t b n]
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// dU = kh * kn * (h(u+1/w,v)-h(u,v))
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// dV = kh * kn * (h(u,v+1/h)-h(u,v))
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Vector ln = (-dU, -dV, 1)
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Normal n = normalize(TBN * ln)
|
||
</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 class="n">Eigen</span><span class="o">::</span><span class="n">Vector3f</span> <span class="n">result_color</span> <span class="o">=</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="n">result_color</span> <span class="o">=</span> <span class="n">normal</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h6 id="纹理贴图能够影响着色效果">纹理贴图能够影响着色效果</h6>
|
||
<p>Displacement mapping</p>
|
||
<ol>
|
||
<li>是Bump mapping的更进一步</li>
|
||
<li>与Bump mapping 使用相同纹理贴图</li>
|
||
<li>会改变模型顶点坐标</li>
|
||
</ol>
|
||
<p><img src="../../images/Displacement_mapping.png" alt=""></p>
|
||
<p>3D程序化噪声和实体建模</p>
|
||
<p><img src="../../images/Procedural_noise_and_Solid.png" alt=""></p>
|
||
<p>将部分着色效果提前绘制到贴图上</p>
|
||
<p><img src="../../images/Provide_precomputed_shading.png" alt=""></p>
|
||
<p>3D图像纹理和体绘制</p>
|
||
<p><img src="../../images/3D_texture_and_volume.png" alt=""></p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>常用光照模型</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E5%B8%B8%E7%94%A8%E5%85%89%E7%85%A7%E6%A8%A1%E5%9E%8B/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E5%B8%B8%E7%94%A8%E5%85%89%E7%85%A7%E6%A8%A1%E5%9E%8B/</guid>
|
||
<pubDate>Thu, 19 May 2022 11:55:15 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h4 id="着色shading">着色(shading)</h4>
|
||
<p>着色往往是指向模型物体上色或添加材质特性的流程(不包含阴影的计算)</p>
|
||
<p>对于计算以某个点为反射点的反射向摄像机的光照,我们需要四个主要数据</p>
|
||
<ol>
|
||
<li>视线方向,v</li>
|
||
<li>模型表面法线,n</li>
|
||
<li>光线方向(许多光线中的一条),l</li>
|
||
<li>模型表面性质(如,颜色,粗糙度等)</li>
|
||
</ol>
|
||
<p><img src="../../images/shading_light_caculate.png" alt=""></p>
|
||
<h4 id="blinn-phong">blinn-phong</h4>
|
||
<p>在进一步计算时,我们先对效果进行分析,将效果拆分如下图为3个部分</p>
|
||
<p>分别为</p>
|
||
<ol>
|
||
<li>镜面反射高光(Specular highlights):对于绝缘体而言其与高光对应,对于金属而言其与它本身的光对应</li>
|
||
<li>漫反射(diffuse reflection):来自于光在物体表面的散射现象</li>
|
||
<li>环境光(ambient lighting):光在物体之间弹射,最终在整个环境中形成的一个基本光</li>
|
||
</ol>
|
||
<p><img src="../../images/light_separete.png" alt=""></p>
|
||
<p>由此可见,一个物体在渲染后体现的颜色是这三种光的总和,即每个位置的颜色就是specular+diffuse+ambient</p>
|
||
<h5 id="diffuse-reflection">Diffuse Reflection</h5>
|
||
<p>在计算漫反射时我们要考虑反射点接收了多少能量从而判断高光的亮度大小</p>
|
||
<p>根据lambert's cosine law,反射点吸收能量的多少与反射点法线和光线的夹角有关,即如图中表现的$\cos{\theta}=l\cdot n$</p>
|
||
<p><img src="../../images/lambert'scosine_low.png" alt=""></p>
|
||
<p>由此我们可以将漫反射总结为如下公式(lambertian Shading)</p>
|
||
<p>$L_d=k_d(I/r^2)max(0,n\cdot l)$</p>
|
||
<ol>
|
||
<li>$L_d$ : 我们想要的反射光线</li>
|
||
<li>$k_d$ : 漫反射系数</li>
|
||
<li>$(I/r^2)$ :到达反射点的能量值</li>
|
||
<li>$max(0,n\cdot l)$ : 反射点接收的能量值</li>
|
||
</ol>
|
||
<h5 id="specular-term高光">Specular Term(高光)</h5>
|
||
<p>高光(Specular)指的是视线在一定的角度区域观看模型表面时会产生一个类似镜面反射的效果</p>
|
||
<p><img src="../../images/Specular_show.png" alt=""></p>
|
||
<p>如图中黄色区域为可见高光的视线范围</p>
|
||
<p>计算过程中需要引入一个半程向量(光线与视线夹角一半方向上的一个单位向量,半程向量与法线向量越接近,镜面反射强度越高)</p>
|
||
<p>$$ h=bisector(v,l) = \frac{v+l}{ || v+l || } $$</p>
|
||
<p>$$L_s=k_s(I/r^2)max(0,\cos \alpha)^p$$
|
||
$$\quad =k_s(I/r^2)max(0,n \cdot h)^p$$</p>
|
||
<p><img src="../../images/specular_cacular.png" alt=""></p>
|
||
<p>$ k_s $ : 镜面反射系数
|
||
$ p $ : 高光的面积,P越大高光面积越小
|
||
$ L_s $ : 计算的高光效果光线</p>
|
||
<p>高光的效果和范围大小与$k_s$和p有关,下图展示了变化效果</p>
|
||
<p><img src="../../images/specular_value_change_show.png" alt=""></p>
|
||
<h5 id="ambient-term-环境光">ambient Term (环境光)</h5>
|
||
<p>任何物体都可以反射光,这使得光在多个物体间弹射,最终会在环境中形成一个最基本的光,通常会被视为常量</p>
|
||
<p>!这是一个近似的效果(不符合物理)</p>
|
||
<p>$$L_a=k_a I_a$$</p>
|
||
<p>$k_a$ : 环境光系数,确定当前环境的底色</p>
|
||
<h5 id="blinn-phong-reflection-model">Blinn-phong Reflection Model</h5>
|
||
<p><img src="../../images/blinn-phong_model_cacu.png" alt=""></p>
|
||
<p>$$L = L_a + L_d + L_s $$
|
||
$$\quad = k_aI_a+k_d(I/r^2)max(0,n\cdot l)+k_s(I/r^2)max(0,n\cdot h)^p$$</p>
|
||
<p>当然这种方式会产生严重的塑料感,这种感觉可以通过调整参数来减少或避免,下次再述(挖坑)</p>
|
||
<hr>
|
||
<h4 id="渲染序列">渲染序列</h4>
|
||
<p>渲染序列可以分为三种:</p>
|
||
<p>逐三角渲染(flat shading)</p>
|
||
<ol>
|
||
<li>三角形面或一个法线向量视为是一个平面</li>
|
||
<li>对平滑表面的表现力不友好</li>
|
||
</ol>
|
||
<p><img src="../../images/flat_shading.png" alt=""></p>
|
||
<p>逐顶点渲染(Gouraud shading)</p>
|
||
<ol>
|
||
<li>根据三角形顶点对颜色进行插值计算</li>
|
||
<li>每一个顶点都有一个法线向量</li>
|
||
</ol>
|
||
<p><img src="../../images/Gourand_shading.png" alt=""></p>
|
||
<ol>
|
||
<li>如何获取逐顶点的法线向量
|
||
<ol>
|
||
<li>对于标准的几何图形:顶点的法线向量就在顶点位置</li>
|
||
<li>对于非标准的几何图形:包含该顶点的周围几个表面的法线取平均值,可由计算公式$$ N_v=\frac{\sum_{i}N_i}{\lVert \sum_{i}N_i \rVert}$$ 得到</li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
<p><img src="../../images/average_normal.png" alt=""></p>
|
||
<p>逐像素渲染(phong shading)</p>
|
||
<ol>
|
||
<li>对每一个三角形的法线向量插值(Barycentric interpolation)</li>
|
||
<li>对每一个像素计算完整的渲染模型</li>
|
||
<li>注意:非Blinn-Phong反射模型</li>
|
||
</ol>
|
||
<p><img src="../../images/phong_shading.png" alt=""></p>
|
||
<hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>排序合集</title>
|
||
<link>http://www.inksoul.top/algorithm/%E6%8E%92%E5%BA%8F%E5%90%88%E9%9B%86/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/algorithm/%E6%8E%92%E5%BA%8F%E5%90%88%E9%9B%86/</guid>
|
||
<pubDate>Thu, 19 May 2022 10:34:31 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><p>内容参考:<a href="https://sort.hust.cc/">十大经典排序算法</a></p>
|
||
<hr>
|
||
<h4 id="归并排序">归并排序</h4>
|
||
<p>基本思想:</p>
|
||
<p>将待排序元素分为大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合并成为所要求的排好序的集合</p>
|
||
<p>JAVA实现</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span><span class="lnt">48
|
||
</span><span class="lnt">49
|
||
</span><span class="lnt">50
|
||
</span><span class="lnt">51
|
||
</span><span class="lnt">52
|
||
</span><span class="lnt">53
|
||
</span><span class="lnt">54
|
||
</span><span class="lnt">55
|
||
</span><span class="lnt">56
|
||
</span><span class="lnt">57
|
||
</span><span class="lnt">58
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">mergeSort</span><span class="o">(</span><span class="n">Comparable</span><span class="o">[]</span><span class="n">a</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Comparable</span> <span class="o">[]</span><span class="n">b</span><span class="o">=</span><span class="k">new</span> <span class="n">Comparable</span><span class="o">[</span><span class="n">a</span><span class="o">.</span><span class="na">length</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">s</span><span class="o">=</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">s</span><span class="o">&lt;</span><span class="n">a</span><span class="o">.</span><span class="na">length</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">mergePass</span><span class="o">(</span><span class="n">a</span><span class="o">,</span><span class="n">b</span><span class="o">,</span><span class="n">s</span><span class="o">);</span><span class="c1">//合并到数组a
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">s</span><span class="o">+=</span><span class="n">s</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">mergePass</span><span class="o">(</span><span class="n">b</span><span class="o">,</span><span class="n">a</span><span class="o">,</span><span class="n">s</span><span class="o">);</span><span class="c1">//合并到数组b
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">s</span><span class="o">+=</span><span class="n">s</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">mergePass</span><span class="o">(</span><span class="n">Comparable</span> <span class="o">[]</span><span class="n">x</span><span class="o">,</span><span class="n">Comparable</span><span class="o">[]</span><span class="n">y</span><span class="o">,</span><span class="kt">int</span> <span class="n">s</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</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="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">i</span><span class="o">&lt;=</span><span class="n">x</span><span class="o">.</span><span class="na">length</span><span class="o">-</span><span class="mi">2</span><span class="o">*</span><span class="n">s</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//合并大小为s的相邻两段子数组
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">merge</span><span class="o">(</span><span class="n">x</span><span class="o">,</span><span class="n">y</span><span class="o">,</span><span class="n">i</span><span class="o">,</span><span class="n">i</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span><span class="n">i</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">i</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">s</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//剩下的元素个数小于2s时
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="o">(</span><span class="n">i</span><span class="o">+</span><span class="n">s</span><span class="o">&lt;</span><span class="n">x</span><span class="o">.</span><span class="na">length</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">merge</span><span class="o">(</span><span class="n">x</span><span class="o">,</span><span class="n">y</span><span class="o">,</span><span class="n">i</span><span class="o">,</span><span class="n">i</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span><span class="n">x</span><span class="o">.</span><span class="na">length</span><span class="o">-</span><span class="mi">1</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//剩余元素复制到y
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">x</span><span class="o">.</span><span class="na">length</span><span class="o">;</span><span class="n">j</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">y</span><span class="o">[</span><span class="n">j</span><span class="o">]=</span><span class="n">x</span><span class="o">[</span><span class="n">j</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">merge</span><span class="o">(</span><span class="n">Comparable</span><span class="o">[]</span><span class="n">c</span><span class="o">,</span><span class="n">Comparable</span><span class="o">[]</span><span class="n">d</span><span class="o">,</span><span class="kt">int</span> <span class="n">l</span><span class="o">,</span><span class="kt">int</span> <span class="n">m</span><span class="o">,</span><span class="kt">int</span> <span class="n">r</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//合并c[l:m]和c[m+1:r]到d[l:r]
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">l</span><span class="o">,</span><span class="n">j</span><span class="o">=</span><span class="n">m</span><span class="o">+</span><span class="n">l</span><span class="o">,</span><span class="n">k</span><span class="o">=</span><span class="n">l</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">((</span><span class="n">i</span><span class="o">&lt;=</span><span class="n">m</span><span class="o">)&amp;&amp;(</span><span class="n">j</span><span class="o">&lt;=</span><span class="n">r</span><span class="o">))</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">c</span><span class="o">[</span><span class="n">i</span><span class="o">].</span><span class="na">compareTo</span><span class="o">(</span><span class="n">c</span><span class="o">[</span><span class="n">j</span><span class="o">])&lt;=</span><span class="mi">0</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">d</span><span class="o">[</span><span class="n">k</span><span class="o">++]=</span><span class="n">c</span><span class="o">[</span><span class="n">i</span><span class="o">++];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">d</span><span class="o">[</span><span class="n">k</span><span class="o">++]=</span><span class="n">c</span><span class="o">[</span><span class="n">j</span><span class="o">++];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">i</span><span class="o">&gt;</span><span class="n">m</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">q</span><span class="o">=</span><span class="n">j</span><span class="o">;</span><span class="n">q</span><span class="o">&lt;=</span><span class="n">r</span><span class="o">;</span><span class="n">q</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">d</span><span class="o">[</span><span class="n">k</span><span class="o">++]=</span><span class="n">c</span><span class="o">[</span><span class="n">q</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">q</span><span class="o">=</span><span class="n">i</span><span class="o">;</span><span class="n">q</span><span class="o">&lt;=</span><span class="n">m</span><span class="o">;</span><span class="n">q</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">d</span><span class="o">[</span><span class="n">k</span><span class="o">++]=</span><span class="n">c</span><span class="o">[</span><span class="n">q</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++实现</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">merge</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">arr</span><span class="p">,</span><span class="kt">int</span> <span class="n">l</span><span class="p">,</span><span class="kt">int</span> <span class="n">mid</span><span class="p">,</span><span class="kt">int</span> <span class="n">r</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">index</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">ptrL</span> <span class="o">=</span> <span class="n">l</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">ptrR</span> <span class="o">=</span> <span class="n">mid</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">static</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="n">tempary</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">arr</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&gt;</span> <span class="n">tempary</span><span class="p">.</span><span class="n">size</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">tempary</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">arr</span><span class="p">.</span><span class="n">size</span><span class="p">());</span><span class="c1">//更新缓存数组长度
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">ptrL</span> <span class="o">!</span> <span class="o">=</span> <span class="n">mid</span> <span class="o">&amp;&amp;</span> <span class="n">ptrR</span> <span class="o">!</span> <span class="o">=</span> <span class="n">r</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">arr</span><span class="p">[</span><span class="n">ptrL</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="p">[</span><span class="n">ptrR</span><span class="p">])</span><span class="c1">//比较左右分组后数组长度
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">tempary</span><span class="p">[</span><span class="n">index</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">ptrL</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="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">tempary</span><span class="p">[</span><span class="n">index</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">ptrR</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="k">while</span><span class="p">(</span><span class="n">ptrL</span> <span class="o">!</span> <span class="o">=</span> <span class="n">mid</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">tempary</span><span class="p">[</span><span class="n">index</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">ptrL</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="k">while</span><span class="p">(</span><span class="n">ptrR</span> <span class="o">!</span> <span class="o">=</span> <span class="n">r</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">tempary</span><span class="p">[</span><span class="n">index</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">ptrR</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">copy</span><span class="p">(</span><span class="n">tempary</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span><span class="n">tempary</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span><span class="o">+</span><span class="n">index</span><span class="p">,</span><span class="n">arr</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span><span class="o">+</span><span class="n">l</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">void</span> <span class="nf">mergeSort</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">arr</span><span class="p">,</span><span class="kt">int</span> <span class="n">l</span><span class="p">,</span><span class="kt">int</span> <span class="n">r</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">r</span> <span class="o">-</span> <span class="n">l</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="o">&gt;</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="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">mid</span> <span class="o">=</span> <span class="p">(</span> <span class="n">l</span> <span class="o">+</span> <span class="n">r</span> <span class="p">)</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">mergeSort</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span><span class="n">l</span><span class="p">,</span><span class="n">mid</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">mergeSort</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span><span class="n">mid</span><span class="p">,</span><span class="n">r</span><span class="p">);</span><span class="c1">//递归排序
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">merge</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span><span class="n">l</span><span class="p">,</span><span class="n">mid</span><span class="p">,</span><span class="n">r</span><span class="p">);</span><span class="c1">//合并数组
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="快速排序">快速排序</h4>
|
||
<p>基本思想</p>
|
||
<p>对于输入的数组a[p:r]</p>
|
||
<ol>
|
||
<li>
|
||
<p>分解:以a[p]为基准元素将a[p:r]分为3段a[p:q-1],a[q]和a[q+1:r]
|
||
<br>使得a[p:q-1]中任何元素小于等于a[q]
|
||
<br>a[q+1:r]中任何元素大于等于a[q]</p>
|
||
</li>
|
||
<li>
|
||
<p>递归求解:通过递归调用排序算法,分别对q[p:q-1]和a[q+1:r]进行排序</p>
|
||
</li>
|
||
<li>
|
||
<p>合并:由于对a[p:q-1]和a[q+1:r]的排序是就地进行,所以在a[p:q-1]和a[q+1:r]完成排序后无需额外计算,a[p:r]的排序就已经完成</p>
|
||
</li>
|
||
</ol>
|
||
<p>JAVA实现</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">qSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">qSort</span><span class="o">(</span><span class="kt">int</span> <span class="n">p</span><span class="o">,</span><span class="kt">int</span> <span class="n">r</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">p</span><span class="o">&lt;</span><span class="n">r</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">q</span> <span class="o">=</span> <span class="n">partition</span><span class="o">(</span><span class="n">p</span><span class="o">,</span><span class="n">r</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">qSort</span><span class="o">(</span><span class="n">p</span><span class="o">,</span><span class="n">q</span><span class="o">-</span><span class="mi">1</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">qSort</span><span class="o">(</span><span class="n">q</span><span class="o">+</span><span class="mi">1</span><span class="o">,</span><span class="n">r</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">partition</span><span class="o">(</span><span class="kt">int</span> <span class="n">p</span><span class="o">,</span><span class="kt">int</span> <span class="n">r</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">p</span><span class="o">,</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">j</span><span class="o">=</span><span class="n">r</span><span class="o">+</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Comparable</span> <span class="n">x</span> <span class="o">=</span> <span class="n">a</span><span class="o">[</span><span class="n">p</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//将&lt;x的元素交换到左边区域
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">//将&gt;x的元素交换到右边区域
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">while</span><span class="o">(</span><span class="kc">true</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">a</span><span class="o">[++</span><span class="n">i</span><span class="o">].</span><span class="na">compareTo</span><span class="o">(</span><span class="n">x</span><span class="o">)&lt;</span><span class="mi">0</span><span class="o">&amp;&amp;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">r</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">a</span><span class="o">[--</span><span class="n">j</span><span class="o">].</span><span class="na">compareTo</span><span class="o">(</span><span class="n">x</span><span class="o">)&gt;</span><span class="mi">0</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">i</span><span class="o">&gt;=</span><span class="n">j</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">break</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">MyMath</span><span class="o">.</span><span class="na">swap</span><span class="o">(</span><span class="n">a</span><span class="o">,</span><span class="n">i</span><span class="o">,</span><span class="n">j</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">a</span><span class="o">[</span><span class="n">p</span><span class="o">]=</span><span class="n">a</span><span class="o">[</span><span class="n">j</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">a</span><span class="o">[</span><span class="n">j</span><span class="o">]=</span><span class="n">x</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">j</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++实现</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="n">Paritition1</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">low</span><span class="p">,</span><span class="kt">int</span> <span class="n">high</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">pivot</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">low</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">low</span> <span class="o">&lt;</span> <span class="n">high</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">while</span><span class="p">(</span><span class="n">low</span> <span class="o">&lt;</span> <span class="n">high</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">high</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">pivot</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="o">--</span><span class="n">high</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="p">[</span><span class="n">low</span><span class="p">]</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">high</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 class="k">while</span> <span class="p">(</span><span class="n">low</span> <span class="o">&lt;</span> <span class="n">high</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">low</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">pivot</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="o">++</span><span class="n">low</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="p">[</span><span class="n">low</span><span class="p">]</span> <span class="o">=</span> <span class="n">pivot</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">low</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">QuickSort</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">low</span><span class="p">,</span><span class="kt">int</span> <span class="n">high</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">low</span><span class="o">&lt;</span><span class="n">high</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">pivot</span> <span class="o">=</span> <span class="n">Paritition1</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">low</span><span class="p">,</span><span class="n">high</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">QuickSort</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">low</span><span class="p">,</span><span class="n">pivot</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">QuickSort</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">pivot</span> <span class="o">+</span> <span class="mi">1</span><span class="err">,</span><span class="n">high</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></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="冒泡排序">冒泡排序</h4>
|
||
<p>主要思想:</p>
|
||
<ol>
|
||
<li>对一对相邻的元素比较,前者大于后者则交换它们</li>
|
||
<li>对数组中所有元素都做此操作,直到最后,最大的数会向泡泡一样冒到数组末尾</li>
|
||
<li>重复操作,每次都跳过上一次的最后一个元素,直到没有元素需要比较</li>
|
||
</ol>
|
||
<p>JAVA</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">BubbleSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1"></span> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copyof</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">boolean</span> <span class="n">flag</span> <span class="o">=</span><span class="kc">true</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span><span class="n">j</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span> <span class="o">-</span> <span class="n">i</span><span class="o">;</span><span class="n">j</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]</span> <span class="o">&gt;</span> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="o">])</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="n">flag</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">flag</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">break</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">BubbleSort</span><span class="p">(</span><span class="kt">int</span> <span class="n">arr</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="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">n</span> <span class="o">-</span> <span class="mi">1</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="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">n</span><span class="o">-</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span><span class="c1">//比较大小
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">&gt;</span><span class="n">arr</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></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">];</span><span class="c1">//交换位置
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</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="n">arr</span><span class="p">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span><span class="o">=</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="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="选择排序">选择排序</h4>
|
||
<p>主要思想</p>
|
||
<ol>
|
||
<li>在没排序的序列中找到最小的元素,存放到开始位置</li>
|
||
<li>在剩余元素中找到最小元素,存放到前一个元素的下一个位置</li>
|
||
<li>重复步骤直到完成</li>
|
||
</ol>
|
||
<p>JAVA</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SelectionSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1"></span> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copyof</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</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="c1">//计算比较次数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span> <span class="o">-</span> <span class="mi">1</span><span class="o">;</span><span class="n">i</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">min</span> <span class="o">=</span> <span class="n">i</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span><span class="n">j</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span><span class="n">j</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">[</span><span class="n">min</span><span class="o">])</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1"></span> <span class="n">min</span> <span class="o">=</span> <span class="n">j</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//将找到的最小值和i位置所在的值进行交换
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span><span class="o">(</span><span class="n">i</span> <span class="o">!</span> <span class="o">=</span> <span class="n">min</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">min</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">min</span><span class="o">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">selectSort</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">nums</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="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">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="kt">int</span> <span class="n">min</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</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="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</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">n</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span><span class="c1">//遍历取得最小值
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">nums</span><span class="p">[</span><span class="n">min</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">min</span> <span class="o">=</span> <span class="n">j</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="n">min</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="c1"></span> <span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">nums</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">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">nums</span><span class="p">[</span><span class="n">min</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">min</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</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></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="插入排序">插入排序</h4>
|
||
<ol>
|
||
<li>将第一个元素视为已排列的有序数组,之后的元素视为未排列的无序数组</li>
|
||
<li>从头到尾依次遍历未排序序列,将遍历到的元素插入到有序数组的适当位置</li>
|
||
</ol>
|
||
<p>JAVA</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">InsertionSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1"></span> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copyof</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//从下标为1的元素开始遍历,寻找合适位置插入
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span><span class="n">i</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1"></span> <span class="kt">int</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">];</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="c1"></span> <span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">i</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">j</span><span class="o">&gt;</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">tmp</span><span class="o">&lt;</span><span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="o">])</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">j</span><span class="o">--;</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1"></span> <span class="k">if</span><span class="o">(</span><span class="n">j</span> <span class="o">!=</span> <span class="n">i</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]</span> <span class="o">=</span> <span class="n">tmp</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"><span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">InsertionSort</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</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="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">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="kt">int</span> <span class="n">get</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="c1">//缓存要排序的数
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">int</span> <span class="n">j</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="k">while</span> <span class="p">(</span><span class="n">j</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">&gt;</span><span class="n">get</span><span class="p">)</span><span class="c1">//与已排序的有序数组比较
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span><span class="c1">//如果该数更大则右移
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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 class="n">A</span><span class="p">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">get</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></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="希尔排序">希尔排序</h4>
|
||
<ol>
|
||
<li>将整个待排列数组分为增量序列$t_1,t_2,\cdots,t_k且t_i&gt;t_j,t_k=1$</li>
|
||
<li>按照增量序列的个数K,对序列进行k趟排序</li>
|
||
<li>每次排序时根据$t_i$的值将未排序序列分割为若干个长度为m的子序列,分别进行插入排序。当i为1时,整个序列视为一个表</li>
|
||
</ol>
|
||
<p>JAVA</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ShellSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <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="c1"></span> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copyof</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</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="n">gap</span> <span class="o">=</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">gap</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">/</span><span class="mi">3</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">gap</span> <span class="o">=</span> <span class="n">gap</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">gap</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span><span class="n">gap</span><span class="o">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span><span class="n">i</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">];</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="n">i</span><span class="o">-</span><span class="n">gap</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">j</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]&gt;</span><span class="n">tmp</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">+</span><span class="n">gap</span><span class="o">]=</span><span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">j</span><span class="o">-=</span><span class="n">gap</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">+</span><span class="n">gap</span><span class="o">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">gap</span> <span class="o">=</span> <span class="o">(</span><span class="kt">int</span><span class="o">)</span> <span class="n">Math</span><span class="o">.</span><span class="na">floor</span><span class="o">(</span><span class="n">gap</span><span class="o">/</span><span class="mi">3</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"><span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="k">const</span> <span class="kt">int</span> <span class="n">INCRGAP</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">shellSort</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">[],</span><span class="kt">int</span> <span class="n">len</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">insertNum</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">unsigned</span> <span class="n">gap</span> <span class="o">=</span> <span class="n">len</span><span class="o">/</span><span class="n">INCRGAP</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span><span class="c1">//初始化步长,应该确保步长为1
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">while</span><span class="p">(</span><span class="n">gap</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">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="n">gap</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">len</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="c1"></span> <span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">insertNum</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">];</span><span class="c1">//缓存当前元素值
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">unsigned</span> <span class="n">j</span> <span class="o">=</span> <span class="n">i</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">j</span><span class="o">&gt;=</span><span class="n">gap</span> <span class="o">&amp;&amp;</span> <span class="n">insertNum</span><span class="o">&lt;</span> <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="o">-</span><span class="n">gap</span><span class="p">])</span><span class="c1">//寻找插入位置
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="o">-</span><span class="n">gap</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">gap</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="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">insertNum</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">gap</span> <span class="o">=</span> <span class="n">gap</span><span class="o">/</span><span class="n">INCRGAP</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></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="堆排序">堆排序</h4>
|
||
<ol>
|
||
<li>将要排序的数组构造为堆,根据升序或降序选择大顶堆或小顶堆</li>
|
||
<li>互换堆首和堆尾</li>
|
||
<li>将堆的尺寸缩小1,将新的数组顶点位置调整到对应位置</li>
|
||
<li>重复步骤2,直到堆的尺寸为1</li>
|
||
</ol>
|
||
<p>JAVA</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span><span class="lnt">48
|
||
</span><span class="lnt">49
|
||
</span><span class="lnt">50
|
||
</span><span class="lnt">51
|
||
</span><span class="lnt">52
|
||
</span><span class="lnt">53
|
||
</span><span class="lnt">54
|
||
</span><span class="lnt">55
|
||
</span><span class="lnt">56
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">HeapSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copyof</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</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">len</span> <span class="o">=</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="n">buildMaxHeap</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="n">len</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">len</span> <span class="o">-</span> <span class="n">i</span><span class="o">;</span> <span class="n">i</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="o">;</span><span class="n">i</span><span class="o">--)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">swap</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="mi">0</span><span class="o">,</span><span class="n">i</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">len</span><span class="o">--;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">heapify</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="mi">0</span><span class="o">,</span><span class="n">len</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">void</span> <span class="nf">buildMaxHeap</span><span class="o">(</span><span class="kt">int</span><span class="o">[],</span><span class="kt">int</span> <span class="n">len</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=(</span><span class="kt">int</span><span class="o">)</span> <span class="n">Math</span><span class="o">.</span><span class="na">floor</span><span class="o">(</span><span class="n">len</span><span class="o">/</span><span class="mi">2</span><span class="o">);</span><span class="n">i</span><span class="o">&gt;=</span> <span class="mi">0</span><span class="o">;</span><span class="n">i</span><span class="o">--)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">heapify</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="n">i</span><span class="o">,</span><span class="n">len</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">void</span> <span class="nf">heapify</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span><span class="kt">int</span> <span class="n">i</span><span class="o">,</span><span class="kt">int</span> <span class="n">len</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">left</span> <span class="o">=</span><span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">right</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">2</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">largest</span> <span class="o">=</span> <span class="n">i</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">left</span> <span class="o">&lt;</span> <span class="n">len</span> <span class="o">&amp;&amp;</span> <span class="n">arr</span><span class="o">[</span><span class="n">left</span><span class="o">]&gt;</span><span class="n">arr</span><span class="o">[</span><span class="n">largest</span><span class="o">])</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">largest</span> <span class="o">=</span> <span class="n">left</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">right</span> <span class="o">&lt;</span> <span class="n">len</span> <span class="o">&amp;&amp;</span> <span class="n">arr</span><span class="o">[</span><span class="n">right</span><span class="o">]&gt;</span> <span class="n">arr</span><span class="o">[</span><span class="n">largest</span><span class="o">])</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">largest</span> <span class="o">=</span> <span class="n">right</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">largest</span> <span class="o">!=</span><span class="n">i</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">swap</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="n">i</span><span class="o">,</span><span class="n">largest</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">heapify</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="n">largest</span><span class="o">,</span><span class="n">len</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">void</span> <span class="nf">swap</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span><span class="kt">int</span> <span class="n">i</span><span class="o">,</span><span class="kt">int</span> <span class="n">j</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]</span> <span class="o">=</span> <span class="n">temp</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">buildMaxHeap</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</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="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="n">n</span><span class="o">/</span><span class="mi">2</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="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">maxHeapIfy</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">n</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">maxHeapIfy</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">i</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">l</span> <span class="o">=</span> <span class="mi">2</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></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">r</span> <span class="o">=</span> <span class="mi">2</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></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">largest</span> <span class="o">=</span> <span class="n">i</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">l</span><span class="o">&lt;</span><span class="n">n</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">l</span><span class="p">]</span><span class="o">&gt;</span><span class="n">A</span><span class="p">[</span><span class="n">largest</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">largest</span> <span class="o">=</span> <span class="n">l</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">l</span><span class="o">&lt;</span><span class="n">n</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">r</span><span class="p">]</span><span class="o">&gt;</span><span class="n">A</span><span class="p">[</span><span class="n">largest</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">largest</span> <span class="o">=</span> <span class="n">r</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">largest</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="n">swap</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="n">A</span><span class="p">[</span><span class="n">largest</span><span class="p">]);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">maxHeapIfy</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">largest</span><span class="p">,</span><span class="n">n</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">heapSort</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">buildMaxHeap</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">n</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="n">n</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="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">swap</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">A</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">maxHeapIfy</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="mi">0</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></code></pre></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="计数排序">计数排序</h4>
|
||
<ol>
|
||
<li>找出待排序的数组中国最大和最小的元素,从而确定缓存数组的最大长度</li>
|
||
<li>根据每个值为i的元素出现的次数,存入缓存数组的第i项</li>
|
||
<li>累加所有计数</li>
|
||
<li>反向填充目标数组</li>
|
||
</ol>
|
||
<p>JAVA</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">HeapSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copyof</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</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">maxValue</span> <span class="o">=</span> <span class="n">getMaxValue</span><span class="o">(</span><span class="n">arr</span><span class="o">);</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">countingSort</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="n">maxValue</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">countingSort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span><span class="kt">int</span> <span class="n">maxValue</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">bucketLen</span> <span class="o">=</span> <span class="n">maxValue</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span><span class="o">[]</span> <span class="n">bucket</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="n">bucketLen</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span> <span class="o">:</span><span class="n">arr</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">bucket</span><span class="o">[</span><span class="n">value</span><span class="o">]++;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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">sortedIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">bucketLen</span><span class="o">;</span><span class="n">j</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">bucket</span><span class="o">[</span><span class="n">j</span><span class="o">]&gt;</span><span class="mi">0</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">sortedIndex</span><span class="o">++]</span> <span class="o">=</span> <span class="n">j</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">bucket</span><span class="o">[</span><span class="n">j</span><span class="o">]--;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span> <span class="nf">getMaxValue</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">maxValue</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span> <span class="o">:</span> <span class="n">arr</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">maxValue</span> <span class="o">&lt;</span> <span class="n">value</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">maxValue</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">maxValue</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><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;algorithm&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;string&gt;</span><span class="cp">
|
||
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;cstdlib&gt;</span><span class="cp">
|
||
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><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="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">CountSort</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">vec</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">length</span> <span class="o">=</span> <span class="n">vec</span><span class="p">.</span><span class="n">size</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">&lt;=</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">return</span> <span class="n">vec</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="kt">int</span> <span class="n">max</span> <span class="o">=</span> <span class="o">*</span><span class="n">max_element</span><span class="p">(</span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span><span class="n">vec</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">min</span> <span class="o">=</span> <span class="o">*</span><span class="n">min_element</span><span class="p">(</span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span><span class="n">vec</span><span class="p">.</span><span class="n">end</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">countArray</span><span class="p">(</span><span class="n">max</span> <span class="o">-</span> <span class="n">min</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span><span class="mi">0</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">length</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="o">++</span><span class="n">countArray</span><span class="p">[</span><span class="n">vec</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></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">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">sortArray</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">countArray</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></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">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">countArray</span><span class="p">[</span><span class="n">i</span><span class="p">];</span><span class="o">++</span><span class="n">j</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">sortArray</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">min</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="p">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">sortArray</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></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="桶排序">桶排序</h4>
|
||
<ol>
|
||
<li>利用函数映射关系将待排序数组的元素分配到桶中</li>
|
||
<li>将元素在桶中排序</li>
|
||
</ol>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span><span class="lnt">48
|
||
</span><span class="lnt">49
|
||
</span><span class="lnt">50
|
||
</span><span class="lnt">51
|
||
</span><span class="lnt">52
|
||
</span><span class="lnt">53
|
||
</span><span class="lnt">54
|
||
</span><span class="lnt">55
|
||
</span><span class="lnt">56
|
||
</span><span class="lnt">57
|
||
</span><span class="lnt">58
|
||
</span><span class="lnt">59
|
||
</span><span class="lnt">60
|
||
</span><span class="lnt">61
|
||
</span><span class="lnt">62
|
||
</span><span class="lnt">63
|
||
</span><span class="lnt">64
|
||
</span><span class="lnt">65
|
||
</span><span class="lnt">66
|
||
</span><span class="lnt">67
|
||
</span><span class="lnt">68
|
||
</span><span class="lnt">69
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">BuckSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">InserSort</span> <span class="n">insertSort</span> <span class="o">=</span> <span class="k">new</span> <span class="n">InsertSort</span><span class="o">();</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copy0f</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</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">bucketSort</span><span class="o">(</span><span class="n">Arr</span><span class="o">,</span><span class="mi">5</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">bucketSort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span><span class="kt">int</span> <span class="n">bucketSize</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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">minValue</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">maxValue</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span> <span class="o">:</span> <span class="n">arr</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">value</span> <span class="o">&lt;</span> <span class="n">minValue</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">minValue</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="n">value</span> <span class="o">&gt;</span> <span class="n">maxValue</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">maxValue</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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">bucketCount</span> <span class="o">=</span> <span class="o">(</span><span class="kt">int</span><span class="o">)</span> <span class="n">Math</span><span class="o">.</span><span class="na">floor</span><span class="o">((</span><span class="n">maxValue</span> <span class="o">-</span> <span class="n">minValue</span><span class="o">)/</span><span class="n">bucketSize</span><span class="o">)</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span><span class="o">[][]</span> <span class="n">buckets</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="n">bucketCount</span><span class="o">][</span><span class="mi">0</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span><span class="n">i</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="o">(</span><span class="kt">int</span><span class="o">)</span><span class="n">Math</span><span class="o">.</span><span class="na">floor</span><span class="o">((</span><span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">]-</span><span class="n">minValue</span><span class="o">)/</span><span class="n">bucketSize</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">buckets</span><span class="o">[</span><span class="n">index</span><span class="o">]</span> <span class="o">=</span> <span class="n">arrAppend</span><span class="o">(</span><span class="n">buckets</span><span class="o">[</span><span class="n">index</span><span class="o">],</span><span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">]);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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">arrIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">bucket</span> <span class="o">:</span> <span class="n">buckets</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">buckets</span><span class="o">.</span><span class="na">length</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">continue</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="n">bucket</span> <span class="o">=</span> <span class="n">insertSort</span><span class="o">.</span><span class="na">sort</span><span class="o">(</span><span class="n">bucket</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span> <span class="o">:</span> <span class="n">bucket</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">arrIndex</span><span class="o">++]</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="cm">/*自动扩容桶的数量*/</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">arrAppend</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copy0f</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">+</span><span class="mi">1</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span> <span class="o">-</span> <span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span><span class="lnt">48
|
||
</span><span class="lnt">49
|
||
</span><span class="lnt">50
|
||
</span><span class="lnt">51
|
||
</span><span class="lnt">52
|
||
</span><span class="lnt">53
|
||
</span><span class="lnt">54
|
||
</span><span class="lnt">55
|
||
</span><span class="lnt">56
|
||
</span><span class="lnt">57
|
||
</span><span class="lnt">58
|
||
</span><span class="lnt">59
|
||
</span><span class="lnt">60
|
||
</span><span class="lnt">61
|
||
</span><span class="lnt">62
|
||
</span><span class="lnt">63
|
||
</span><span class="lnt">64
|
||
</span><span class="lnt">65
|
||
</span><span class="lnt">66
|
||
</span><span class="lnt">67
|
||
</span><span class="lnt">68
|
||
</span><span class="lnt">69
|
||
</span><span class="lnt">70
|
||
</span><span class="lnt">71
|
||
</span><span class="lnt">72
|
||
</span><span class="lnt">73
|
||
</span><span class="lnt">74
|
||
</span><span class="lnt">75
|
||
</span><span class="lnt">76
|
||
</span><span class="lnt">77
|
||
</span><span class="lnt">78
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iterator&gt;</span><span class="cp">
|
||
</span></span></span><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"></span><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="k">const</span> <span class="kt">int</span> <span class="n">BUCKET_NUM</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="k">struct</span> <span class="nc">ListNode</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">explicit</span> <span class="nf">ListNode</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="o">:</span><span class="n">mData</span><span class="p">(</span><span class="n">i</span><span class="p">),</span><span class="n">mNext</span><span class="p">(</span><span class="nb">NULL</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">ListNode</span><span class="o">*</span> <span class="n">mNext</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">mData</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="n">ListNode</span><span class="o">*</span> <span class="nf">insert</span><span class="p">(</span><span class="n">ListNode</span><span class="o">*</span> <span class="n">head</span><span class="p">,</span><span class="kt">int</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="n">ListNode</span> <span class="n">dummyNode</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ListNode</span> <span class="o">*</span><span class="n">newNode</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ListNode</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ListNode</span> <span class="o">*</span><span class="n">pre</span><span class="p">,</span><span class="o">*</span><span class="n">curr</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">dummyNode</span><span class="p">.</span><span class="n">mNext</span> <span class="o">=</span> <span class="n">head</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">pre</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">dummyNode</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">curr</span> <span class="o">=</span> <span class="n">head</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="p">(</span><span class="nb">NULL</span><span class="o">!=</span><span class="n">curr</span> <span class="o">&amp;&amp;</span> <span class="n">curr</span><span class="o">-&gt;</span><span class="n">mData</span><span class="o">&lt;=</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="n">pre</span> <span class="o">=</span> <span class="n">curr</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">curr</span> <span class="o">=</span> <span class="n">curr</span><span class="o">-&gt;</span><span class="n">mNext</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">newNode</span><span class="o">-&gt;</span><span class="n">mNext</span> <span class="o">=</span> <span class="n">curr</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">mNext</span> <span class="o">=</span> <span class="n">newNode</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">dummyNode</span><span class="p">.</span><span class="n">mNext</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">ListNode</span><span class="o">*</span> <span class="nf">Merge</span><span class="p">(</span><span class="n">ListNode</span> <span class="o">*</span><span class="n">head1</span><span class="p">,</span><span class="n">ListNode</span> <span class="o">*</span><span class="n">head2</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">ListNode</span> <span class="n">dummyNode</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ListNode</span> <span class="o">*</span><span class="n">dummy</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">dummyNode</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="p">(</span><span class="nb">NULL</span><span class="o">!=</span><span class="n">head1</span> <span class="o">&amp;&amp;</span> <span class="nb">NULL</span><span class="o">!=</span> <span class="n">head2</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">head1</span><span class="o">-&gt;</span><span class="n">mData</span> <span class="o">&lt;=</span> <span class="n">head2</span><span class="o">-&gt;</span><span class="n">mData</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">dummy</span><span class="o">-&gt;</span><span class="n">mNext</span> <span class="o">=</span> <span class="n">head1</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">head1</span> <span class="o">=</span> <span class="n">head1</span><span class="o">-&gt;</span><span class="n">mNext</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">dummy</span><span class="o">-&gt;</span><span class="n">mNext</span> <span class="o">=</span> <span class="n">head2</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">head2</span> <span class="o">=</span> <span class="n">head2</span> <span class="o">-&gt;</span><span class="n">mNext</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">dummy</span> <span class="o">=</span> <span class="n">dummy</span> <span class="o">-&gt;</span><span class="n">mNext</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="nb">NULL</span><span class="o">!=</span><span class="n">head1</span><span class="p">)</span> <span class="n">dummy</span><span class="o">-&gt;</span><span class="n">mNext</span> <span class="o">=</span> <span class="n">head1</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="nb">NULL</span><span class="o">!=</span><span class="n">head2</span><span class="p">)</span> <span class="n">dummy</span><span class="o">-&gt;</span><span class="n">mNext</span> <span class="o">=</span> <span class="n">head2</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="n">dummyNode</span><span class="p">.</span><span class="n">mNext</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">BuckSort</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">arr</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">vector</span><span class="o">&lt;</span><span class="n">ListNode</span><span class="o">*&gt;</span> <span class="n">buckets</span><span class="p">(</span><span class="n">BUCKET_NUM</span><span class="p">,(</span><span class="n">ListNode</span><span class="o">*</span><span class="p">)(</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">n</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="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">/</span><span class="n">BUCKET_NUM</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">ListNode</span> <span class="o">*</span><span class="n">head</span> <span class="o">=</span> <span class="n">buckets</span><span class="p">.</span><span class="n">at</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">buckets</span><span class="p">.</span><span class="n">at</span><span class="p">(</span><span class="n">index</span><span class="p">)</span><span class="o">=</span><span class="n">insert</span><span class="p">(</span><span class="n">head</span><span class="p">,</span><span class="n">arr</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="n">ListNode</span> <span class="o">*</span><span class="n">head</span> <span class="o">=</span> <span class="n">buckets</span><span class="p">.</span><span class="n">at</span><span class="p">(</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">1</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">BUCKET_NUM</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="n">head</span> <span class="o">=</span> <span class="n">Merge</span><span class="p">(</span><span class="n">head</span><span class="p">,</span><span class="n">buckets</span><span class="p">.</span><span class="n">at</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="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">n</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="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">head</span><span class="o">-&gt;</span><span class="n">mData</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">head</span> <span class="o">=</span> <span class="n">head</span><span class="o">-&gt;</span><span class="n">mNext</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></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h4 id="基数排序">基数排序</h4>
|
||
<p>将整数按位数分割为不同数字,按各位数比较大小</p>
|
||
<p>在桶的分配方式上根据键值的每位数字来分配桶</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span><span class="lnt">48
|
||
</span><span class="lnt">49
|
||
</span><span class="lnt">50
|
||
</span><span class="lnt">51
|
||
</span><span class="lnt">52
|
||
</span><span class="lnt">53
|
||
</span><span class="lnt">54
|
||
</span><span class="lnt">55
|
||
</span><span class="lnt">56
|
||
</span><span class="lnt">57
|
||
</span><span class="lnt">58
|
||
</span><span class="lnt">59
|
||
</span><span class="lnt">60
|
||
</span><span class="lnt">61
|
||
</span><span class="lnt">62
|
||
</span><span class="lnt">63
|
||
</span><span class="lnt">64
|
||
</span><span class="lnt">65
|
||
</span><span class="lnt">66
|
||
</span><span class="lnt">67
|
||
</span><span class="lnt">68
|
||
</span><span class="lnt">69
|
||
</span><span class="lnt">70
|
||
</span><span class="lnt">71
|
||
</span><span class="lnt">72
|
||
</span><span class="lnt">73
|
||
</span><span class="lnt">74
|
||
</span><span class="lnt">75
|
||
</span><span class="lnt">76
|
||
</span><span class="lnt">77
|
||
</span><span class="lnt">78
|
||
</span><span class="lnt">79
|
||
</span><span class="lnt">80
|
||
</span><span class="lnt">81
|
||
</span><span class="lnt">82
|
||
</span><span class="lnt">83
|
||
</span><span class="lnt">84
|
||
</span><span class="lnt">85
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">RadixSort</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">sort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">sourceArray</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copy0f</span><span class="o">(</span><span class="n">sourceArray</span><span class="o">,</span><span class="n">sourceArray</span><span class="o">.</span><span class="na">length</span><span class="o">);</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">maxDigit</span> <span class="o">=</span> <span class="n">getMaxDigit</span><span class="o">(</span><span class="n">arr</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">radixSort</span><span class="o">(</span><span class="n">arr</span><span class="o">,</span><span class="n">maxDigit</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="cm">/*
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> 获取最高位数
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span> <span class="nf">getMaxDigit</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">maxValue</span> <span class="o">=</span> <span class="n">getMaxValue</span><span class="o">(</span><span class="n">arr</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">getNumLenght</span><span class="o">(</span><span class="n">maxValue</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span> <span class="nf">getMaxValue</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">maxValue</span> <span class="o">=</span> <span class="n">arr</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span> <span class="o">:</span> <span class="n">arr</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">maxValue</span> <span class="o">&lt;</span> <span class="n">value</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">maxValue</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">maxValue</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="kd">private</span> <span class="kt">int</span> <span class="nf">getNumLenght</span><span class="o">(</span><span class="kt">long</span> <span class="n">num</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">num</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">long</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">num</span><span class="o">;</span><span class="n">temp</span> <span class="o">!=</span><span class="mi">0</span><span class="o">;</span><span class="n">temp</span><span class="o">/=</span><span class="mi">10</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">lenght</span><span class="o">++;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">lenght</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">radixSort</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span><span class="kt">int</span> <span class="n">maxDigit</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">mod</span> <span class="o">=</span><span class="mi">10</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">dev</span> <span class="o">=</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">maxDigit</span><span class="o">;</span><span class="n">i</span><span class="o">++,</span><span class="n">dev</span><span class="o">*=</span><span class="mi">10</span><span class="o">,</span><span class="n">mod</span> <span class="o">*=</span> <span class="mi">10</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span><span class="o">[][]</span> <span class="n">counter</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="n">mod</span> <span class="o">*</span> <span class="mi">2</span><span class="o">][</span><span class="mi">0</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span> <span class="mi">0</span><span class="o">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span><span class="n">j</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">bucket</span> <span class="o">=</span> <span class="o">((</span><span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]%</span><span class="n">mod</span><span class="o">)/</span><span class="n">dev</span><span class="o">)+</span><span class="n">mod</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">counter</span><span class="o">[</span><span class="n">bucket</span><span class="o">]</span> <span class="o">=</span> <span class="n">arrAppend</span><span class="o">(</span><span class="n">counter</span><span class="o">[</span><span class="n">bucket</span><span class="o">],</span><span class="n">arr</span><span class="o">[</span><span class="n">j</span><span class="o">]);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">bucke</span><span class="o">:</span><span class="n">counter</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">value</span> <span class="o">:</span><span class="n">bucket</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">pos</span><span class="o">++]</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="c1"></span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">private</span> <span class="kt">int</span><span class="o">[]</span> <span class="nf">arrAppend</span><span class="o">(</span><span class="kt">int</span><span class="o">[]</span> <span class="n">arr</span><span class="o">,</span><span class="kt">int</span> <span class="n">value</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">copy0f</span><span class="o">(</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span> <span class="o">+</span> <span class="mi">1</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">arr</span><span class="o">[</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span> <span class="o">-</span> <span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">arr</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>C++</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span><span class="lnt">48
|
||
</span><span class="lnt">49
|
||
</span><span class="lnt">50
|
||
</span><span class="lnt">51
|
||
</span><span class="lnt">52
|
||
</span><span class="lnt">53
|
||
</span><span class="lnt">54
|
||
</span><span class="lnt">55
|
||
</span><span class="lnt">56
|
||
</span><span class="lnt">57
|
||
</span><span class="lnt">58
|
||
</span><span class="lnt">59
|
||
</span><span class="lnt">60
|
||
</span><span class="lnt">61
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">maxbit</span><span class="p">(</span><span class="kt">int</span> <span class="n">data</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">maxData</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</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">1</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="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">if</span><span class="p">(</span><span class="n">maxData</span> <span class="o">&lt;</span> <span class="n">data</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="n">maxData</span> <span class="o">=</span> <span class="n">data</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="kt">int</span> <span class="n">d</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">p</span> <span class="o">=</span> <span class="mi">10</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">maxDate</span> <span class="o">&gt;=</span> <span class="n">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="n">maxData</span> <span class="o">/=</span> <span class="mi">10</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">++</span><span class="n">d</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">d</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">void</span> <span class="nf">radixSort</span><span class="p">(</span><span class="kt">int</span> <span class="n">data</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">d</span> <span class="o">=</span> <span class="n">maxbit</span><span class="p">(</span><span class="n">data</span><span class="p">,</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="o">*</span><span class="n">tmp</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</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="o">*</span><span class="n">count</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</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">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">k</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">radix</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">1</span><span class="p">;</span><span class="n">i</span> <span class="o">&lt;=</span> <span class="n">d</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="k">for</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="n">j</span> <span class="o">&lt;</span> <span class="mi">10</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">count</span><span class="p">[</span><span class="n">j</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="k">for</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="n">j</span> <span class="o">&lt;</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">k</span> <span class="o">=</span> <span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">/</span><span class="n">radix</span><span class="p">)</span> <span class="o">%</span> <span class="mi">10</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">count</span><span class="p">[</span><span class="n">k</span><span class="p">]</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="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span><span class="n">j</span> <span class="o">&lt;</span> <span class="mi">10</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">count</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">count</span><span class="p">[</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">+</span><span class="n">count</span><span class="p">[</span><span class="n">j</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 class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">&gt;=</span> <span class="mi">0</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">k</span> <span class="o">=</span> <span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">/</span><span class="n">radix</span><span class="p">)</span> <span class="o">%</span> <span class="mi">10</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">tmp</span><span class="p">[</span><span class="n">count</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">count</span><span class="p">[</span><span class="n">k</span><span class="p">]</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="k">for</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="n">j</span> <span class="o">&lt;</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="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="n">j</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 class="n">radix</span> <span class="o">=</span> <span class="n">radix</span> <span class="o">*</span> <span class="mi">10</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">delete</span> <span class="p">[]</span><span class="n">tmp</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">delete</span> <span class="p">[]</span><span class="n">count</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/algorithm/">algorithm\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>Z-Buffer 深度缓存</title>
|
||
<link>http://www.inksoul.top/computergraphic/z-buffer_%E6%B7%B1%E5%BA%A6%E7%BC%93%E5%AD%98/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/z-buffer_%E6%B7%B1%E5%BA%A6%E7%BC%93%E5%AD%98/</guid>
|
||
<pubDate>Wed, 18 May 2022 14:07:33 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h5 id="painters-algorithm-画家算法">Painter's Algorithm 画家算法</h5>
|
||
<p>起源于油画绘制方式,从后往前,依次覆盖后面的物体</p>
|
||
<p>需要对不同深度的物体进行分类来确定面与面的绘制顺序,复杂度为$O(n\log n)$,其中n为三角形的个数,也存在一个无法解决的问题,不能处理无法确定绘制顺序的物体,例如下图互相遮挡的情况</p>
|
||
<p><img src="../../images/unresolvable_depth_order.png" alt=""></p>
|
||
<h6 id="z-buffer">Z-Buffer</h6>
|
||
<p>主要思想</p>
|
||
<ol>
|
||
<li>对于每一个采样点或像素存储一个最小的z值(深度值)</li>
|
||
<li>存储方式与frame buffer存储颜色值的方式相同,在depth buffer里存储深度值</li>
|
||
</ol>
|
||
<p>出于简化考虑,我们通常认为z值始终是正数,这意味着越小的值代表采样点或像素距离相机越近,越大的值则代表距离越远</p>
|
||
<p>Z-Buffer会在生成渲染图的同时根据各采样点(像素)的深度值生成深度图,颜色越深代表距离越近,越浅则越远</p>
|
||
<p><img src="../../images/Depth_map.png" alt=""></p>
|
||
<p>算法</p>
|
||
<p>初始化depth buffer的所有值为$\infty$</p>
|
||
<p>在光栅化的流程中增加如下伪代码流程</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span><span class="lnt">7
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-s" data-lang="s"><span class="line"><span class="cl"><span class="nf">for </span><span class="p">(</span><span class="n">each</span> <span class="n">triangle</span> <span class="bp">T</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">for</span><span class="p">(</span><span class="n">each</span> <span class="nf">sample</span><span class="p">(</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 class="n">in</span> <span class="bp">T</span><span class="p">)</span> <span class="o">//</span>循环每一个采样点,深度值在采样时确定
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">if</span><span class="p">(</span><span class="n">z</span><span class="o">&lt;</span><span class="n">zbuffer[x</span><span class="p">,</span><span class="n">y]</span><span class="p">)</span> <span class="o">//</span>判断深度值大小,确定远近
|
||
</span></span><span class="line"><span class="cl"> <span class="n">framebuffer[x</span><span class="p">,</span><span class="n">y]</span><span class="o">=</span><span class="n">rgb</span><span class="p">;</span> <span class="o">//</span>更新颜色值
|
||
</span></span><span class="line"><span class="cl"> <span class="n">zbuffer[x</span><span class="p">,</span><span class="n">y]</span><span class="o">=</span><span class="n">z</span><span class="p">;</span> <span class="o">//</span>更新深度值
|
||
</span></span><span class="line"><span class="cl"> <span class="n">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="p">;</span> <span class="o">//</span>什么都不做,因为采样流程已经完成
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>整体算法流程会形成如下图效果,复杂度为O(n),n为三角形面的数量</p>
|
||
<p><img src="../../images/Z-Buffer_test.png" alt=""></p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>TAA(temporal antialiasing)</title>
|
||
<link>http://www.inksoul.top/computergraphic/taa/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/taa/</guid>
|
||
<pubDate>Sun, 15 May 2022 17:55:10 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><hr>
|
||
<p>知识沉淀有限,后续会补充内容</p>
|
||
<p>当前内容来源:</p>
|
||
<p><a href="https://github.com/QianMo/Real-Time-Rendering-4th-Bibliography-Collection/blob/main/Chapter%201-24/%5B1938%5D%C2%A0%5BSIGGRAPH%202016%5D%20Temporal%20Antialiasing%20in%C2%A0Uncharted%204.pptx"> [SIGGRAPH 2016] Temporal Antialiasing in Uncharted 4 </a></p>
|
||
<p>十分感谢浅墨大佬的整理</p>
|
||
<hr>
|
||
<h6 id="基本思想">基本思想</h6>
|
||
<p>与超采样类似且在静态图片下实现方式相同</p>
|
||
<p>对同一像素点内采用多个采样点的方式来减少走样但将采样点分散到了一段时间内的多个帧上,在每帧采样时对采样点进行偏移,即抖动(jitter)来实现MSAA中放置多个次采样点的效果</p>
|
||
<p>采样序列也使用Halto sequence
|
||
<img src="../../images/Halton_sequence.png" alt=""></p>
|
||
<h6 id="jitter的实现">jitter的实现</h6>
|
||
<p>采样点的位置会在初始化的时候确定,之后需要在与像素中心距离$[0,1]$的范围里发生偏移</p>
|
||
<p>实现这个效果只需要对投影矩阵中的值进行改动
|
||
<img src="../../images/offset_projection_matrix.png" alt=""></p>
|
||
<p>图片中标红的值便是在归一化后的坐标空间里偏移值的替换位置</p>
|
||
<p>当然,只完成jitter只会让实时渲染的图像发生严重的抖动,接下来我们只需要让这些抖动的帧收敛(converge, PS:实在找不到合适的词来翻译)</p>
|
||
<h6 id="在渲染管线中的位置">在渲染管线中的位置</h6>
|
||
<p>TAA Shader</p>
|
||
<p>输入:</p>
|
||
<p>当前帧的HDR缓存
|
||
<br>上一帧的TAA计算结果或者历史结果缓存</p>
|
||
<p>输出:</p>
|
||
<p>当前帧的TAA结果,用于输出到渲染管线的下一处理阶段 和 作为下一帧TAA计算的历史结果缓存</p>
|
||
<p>由此可以推断出TAA Shader在渲染管线的位置</p>
|
||
<p>Depth only pass (main view scene pass)
|
||
<br>GBuffer pass (main view scene pass)
|
||
<br>Deferred lighting shader $\leftarrow$ HDR
|
||
<br>Temporal AA
|
||
<br>Post processing (tone mapping, motion blur, etc.) $\leftarrow$ LDR</p>
|
||
<h6 id="静态场景">静态场景</h6>
|
||
<p>在静态场景下应用TAA</p>
|
||
<p>设置好输入和输出
|
||
<br> 启用全屏着色
|
||
<br> 在历史值和现在值之间做插值计算</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-S" data-lang="S"><span class="line"><span class="cl"><span class="n">float3</span> <span class="n">currColor</span> <span class="o">=</span> <span class="nf">currBuffer.Load</span><span class="p">(</span><span class="n">pos</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">float3</span> <span class="n">historyColor</span> <span class="o">=</span> <span class="nf">historyBuffer.Load</span><span class="p">(</span><span class="n">pos</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">return</span> <span class="nf">lerp</span><span class="p">(</span><span class="n">historyColor</span><span class="p">,</span><span class="n">currColor</span><span class="p">,</span><span class="m">0.05</span><span class="n">f</span><span class="p">);</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>插值时,不同的权重会带来不同的影响
|
||
<br>当前帧的颜色的权重越高,抖动越明显,但收敛速度较快
|
||
<br>历史帧的颜色的权重越高,抖动越少,走样越明显,但是收敛速度慢</p>
|
||
<p>0.05是一个合适的权重值来平衡反走样质量与收敛速度,这意味着每一个新渲染的帧都只对最终的静态场景生成占比5%</p>
|
||
<hr>
|
||
<h6 id="动态场景">动态场景</h6>
|
||
<p>在动态情况下,我们需要使用全局运动向量来计算当前帧的某一个像素在上一帧的位置坐标</p>
|
||
<p>所以在GBuffer里我们通常作如下计算
|
||
<br>$ pos_{proj}\times mat_{wvp}$
|
||
<br>$ posLast_{proj}=posLast_{obj}\times matLast_{wvp}$</p>
|
||
<p>由此我们可以总结出计算运动向量(Motion Vector)所需的值</p>
|
||
<ol>
|
||
<li>上一帧的相机信息</li>
|
||
<li>每一个物体上一帧的$ mat_{o2w}$</li>
|
||
<li>每一个蒙皮的物体在上一帧时的骨骼位置,并在每一帧计算两次蒙皮和输出上一帧和目前帧的顶点位置</li>
|
||
</ol>
|
||
<hr>
|
||
<p>当然,在GBuffer里我们可以直接获得目前帧的ndc(normalized device coordinate)坐标,出于不将jitter视为运动的目的,我们也要在ndc里去除jitter带来的偏移</p>
|
||
<p>$ pos_{ndc} -= g_{projOffset} $
|
||
<br>$ posLast_{ndc} -= g_{projOffsetLast} $
|
||
<br>$ float2 \quad motionvector = (posLast_{ndc}- pos_{ndc} ) * float2(0.5f,-0.5f) $</p>
|
||
<hr>
|
||
<p>对于滚动的贴图(比如流动的单层贴图水)
|
||
<br>我们需要计算贴图在贴图UV里的变化量(deltaU,deltaV)在屏幕空间里造成了多少变化量(deltaX,deltaY)
|
||
<br>deltaU = ddx(U) * deltaX + ddy(U) * deltaY
|
||
<br>deltaV = ddx(V) * deltaX + ddy(V) * deltaY</p>
|
||
<hr>
|
||
<p>理论上所有物体都应有motion vector,但依旧有某些物体不支持motion vector</p>
|
||
<ol>
|
||
<li>有复杂贴图的动画物体,如粒子烟雾,水流,云的移动</li>
|
||
<li>半透明物体,因为motion vector仅有一层而无法写入</li>
|
||
</ol>
|
||
<p>当然,我们可以选择将它们的绘制顺序调换至TAA之后,但并非所有物体都允许这么做,任何物体在未经TAA处理的情况下都会发生抖动
|
||
<br>纠正抖动并非只是简单地去除,还要用抖动后的深度情况进行检测</p>
|
||
<hr>
|
||
<p>在对多种情况进行讨论后,我们便可以开始进行motion vector的混合计算,计算前必须去除当前采样的抖动偏移值</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-s" data-lang="s"><span class="line"><span class="cl"><span class="o">//</span>去除抖动偏移值,得到像素中心值
|
||
</span></span><span class="line"><span class="cl"><span class="n">uv</span> <span class="o">-=</span> <span class="n">_jitter</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">//</span>计算上一帧的投影坐标
|
||
</span></span><span class="line"><span class="cl"><span class="n">float2</span> <span class="n">uvLast</span> <span class="o">=</span> <span class="n">uv</span> <span class="o">+</span><span class="nf">motionVectorBuffer.Sample</span><span class="p">(</span><span class="n">point</span><span class="p">,</span><span class="n">uv</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">//</span>双线性模式采样
|
||
</span></span><span class="line"><span class="cl"><span class="n">float3</span> <span class="n">historyColor</span> <span class="o">=</span> <span class="nf">historyBuffer.Sample</span><span class="p">(</span><span class="n">linear</span><span class="p">,</span><span class="n">uvLast</span><span class="p">);</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>镜头移动的时候,很多物体之间的遮挡关系会发生变化,例如</p>
|
||
<ol>
|
||
<li>原本不出现的物体在下一帧出现,原来出现的物体被遮挡而消失</li>
|
||
<li>光线发生了改变,阴影的位置改变或高光位置改变</li>
|
||
</ol>
|
||
<p>这会导致采样motion偏移到的位置在上一帧并没有渲染数据,这时为了数据的平滑过渡,可以在像素点位置周围判断深度,取距离最近的点位来采样获取motion vector的值,减弱遮挡错误的影响</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-s" data-lang="s"><span class="line"><span class="cl"><span class="o">//</span>通过遍历采样点周围<span class="m">9</span>个像素的方式计算<span class="n">neighborMin</span>和<span class="n">neighborMax</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">float3</span> <span class="n">neighborMin</span><span class="p">,</span><span class="n">neighborMax</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"><span class="n">historyColor</span> <span class="o">=</span> <span class="nf">clamp</span><span class="p">(</span><span class="n">historyColor</span><span class="p">,</span><span class="n">neighborMin</span><span class="p">,</span><span class="n">neighborMax</span><span class="p">);</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>这种方式也存在一些弊端
|
||
<br>对于未发生改变的物体,会截断(clamp out)太多不同的历史颜色值
|
||
<br>$3\times3$的像素点周围采样无法对边缘的反走样生效</p>
|
||
<hr>
|
||
<p>这种计算方式有时会因 neighborhood min/max的值过大使clamp失效而产生鬼影(ghosting)现象</p>
|
||
<p>解决方法:</p>
|
||
<ol>
|
||
<li>使用模板位( stencil bits , PS:这个我也不好翻译)的方式将物体分割为两个部份</li>
|
||
<li>将目前帧和上一帧的stencil 输入到TAA shader中处理</li>
|
||
</ol>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-s" data-lang="s"><span class="line"><span class="cl"><span class="n">uint</span> <span class="n">currStencil</span> <span class="o">=</span> <span class="nf">stencilBuffer.Sample</span><span class="p">(</span><span class="n">point</span><span class="p">,</span><span class="n">uv</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">uint</span> <span class="n">lastStencil</span> <span class="o">=</span> <span class="nf">lastStencilBuffer.Sample</span><span class="p">(</span><span class="n">point</span><span class="p">,</span><span class="n">uvLast</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">blendFactor</span> <span class="o">=</span> <span class="p">(</span><span class="n">lastStencil</span> <span class="o">&amp;</span> <span class="mh">0x18</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="n">currStencil</span> <span class="o">&amp;</span> <span class="mh">0x18</span><span class="p">)</span> <span class="o">?</span> <span class="n">blendFactor</span> <span class="o">:</span> <span class="m">1</span><span class="n">.f</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">//</span><span class="mh">0x18</span>表示有两个<span class="n">ghosting</span> <span class="nf">bits </span><span class="p">(</span>不好翻译<span class="m">+1</span><span class="p">)</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>在经过处理后,鬼影现象消失,但当相机从向右旋转时,人物的左侧边缘像素表现效果较差</p>
|
||
<p><img src="../../images/revealed_piels_appear_bad.png" alt=""></p>
|
||
<p>为了减少这种情况的产生,我们在blendFactor为1时,返回一个经过高斯模糊的上一帧的颜色值</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-s" data-lang="s"><span class="line"><span class="cl"><span class="n">blendFactor</span> <span class="o">=</span> <span class="p">(</span><span class="n">lastStencil</span> <span class="o">&amp;</span> <span class="mh">0x18</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="n">currStencil</span> <span class="o">&amp;</span> <span class="mh">0x18</span><span class="p">)</span> <span class="o">?</span> <span class="n">blendFactor</span> <span class="o">:</span><span class="m">1</span><span class="n">.f</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"><span class="n">float3</span> <span class="n">blurredCurrColor</span>
|
||
</span></span><span class="line"><span class="cl"><span class="o">//</span><span class="n">Gaussian</span> <span class="n">blur</span> <span class="n">currColor</span> <span class="n">with</span> <span class="m">3</span><span class="n">x3</span> <span class="n">neighborhood</span>
|
||
</span></span><span class="line"><span class="cl"><span class="nf">if </span><span class="p">(</span><span class="n">blendFactor</span> <span class="o">==</span> <span class="m">1</span><span class="n">.f</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">return</span> <span class="n">blurredCurrColor</span><span class="p">;</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>Gaussian blur使用的卷积核与$3\times3$相邻像素采样一致
|
||
<br>$ \begin{bmatrix} \frac{1}{16} &amp; \frac{1}{8} &amp;\frac{1}{16} \\ \frac{1}{8} &amp;\frac{1}{4} &amp;\frac{1}{8} \\ \frac{1}{16} &amp;\frac{1}{8} &amp;\frac{1}{16} \end{bmatrix} $</p>
|
||
<p>处理后依旧有1像素厚的鬼影存在
|
||
<img src="../../images/one_pixel_thick_ghosting.png" alt=""></p>
|
||
<p>产生原因:
|
||
<br>Color history 是线性采样,Stencil history 是点采样,两者在边缘并不相容</p>
|
||
<p>解决方法
|
||
<br>在stencil buffer里让物体向外扩大1像素</p>
|
||
<ol>
|
||
<li>创建输入值为历史帧和stencil buffers的全屏shader</li>
|
||
<li>对每一个像素,将它的深度与周围4个相邻像素进行对比</li>
|
||
<li>输出深度接近的像素的模板(stencil of pixel)</li>
|
||
<li>将扩张的stencil buffer输入TAA</li>
|
||
<li>上一帧的stencil应该来自于扩张后</li>
|
||
<li>对扩张后的stencil做模板测试(stencil test)</li>
|
||
<li>边缘的检测则使用未扩张的版本</li>
|
||
</ol>
|
||
<hr>
|
||
<p>在计算完成后我们需要将目前帧的和历史帧的结果混合到一起</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-s" data-lang="s"><span class="line"><span class="cl"><span class="n">return</span> <span class="nf">lerp</span><span class="p">(</span><span class="n">historyColor</span><span class="p">,</span><span class="n">currColor</span><span class="p">,</span><span class="n">blendFactor</span><span class="p">)</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>出于平衡模糊和抖动的目的,blendFactor必须是一个动态的值
|
||
<br>由UE4在[siggraph 2014]提出的方法可知
|
||
<br>当局部对比度低的时候增加
|
||
<br>当历史帧在截断值附近或像素的偏移接近子像素时减少
|
||
<br>但在这样处理后依旧有模糊的情况残余</p>
|
||
<hr>
|
||
<p>为了修复残余的模糊情况,我们可以再加入一个全屏的锐化处理
|
||
<br>对一个$3\times3$的相邻像素序列,采取$\begin{bmatrix} 0 &amp;-1 &amp;0 \\ -1 &amp;4 &amp;-1 \\ 0 &amp;-1 &amp;0 \end{bmatrix}$的权重比例,即</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-s" data-lang="s"><span class="line"><span class="cl"><span class="n">return</span> <span class="nf">saturate</span><span class="p">(</span><span class="n">center</span> <span class="o">+</span> <span class="m">4</span> <span class="o">*</span> <span class="n">center</span><span class="o">-</span><span class="n">up</span><span class="o">-</span><span class="n">down</span><span class="o">-</span><span class="n">left</span><span class="o">-</span><span class="n">right</span><span class="p">)</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><hr>
|
||
<h6 id="taa的性能">TAA的性能</h6>
|
||
<p>主体shader在PS4的GPU上渲染1080p分辨率需要0.8ms</p>
|
||
<p>后续处理也存在开销
|
||
<br>Motion vector calculation 运动向量计算
|
||
<br>Sharpen shader (0.15ms) 锐化效果
|
||
<br>Expand stencil shader(0.4ms) 模板扩张</p>
|
||
<hr>
|
||
<p><a href="https://gamedev.stackexchange.com/questions/57607/what-is-the-difference-between-a-modelview-projection-matrix-and-world-view-proj">WVP和MVP矩阵的区别</a></p>
|
||
<p><a href="https://computergraphics.stackexchange.com/questions/1976/how-to-determine-the-object-to-world-matrix#:~:text=The%20Object-To-World%20matrix%20is%20often%20called%20%22model-matrix%22.%20This,it%20and%20the%20math%20works%20out%20pretty%20well.">$ matrix_{objToWorld} $</a></p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>走样与反走样</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E8%B5%B0%E6%A0%B7%E4%B8%8E%E5%8F%8D%E8%B5%B0%E6%A0%B7/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E8%B5%B0%E6%A0%B7%E4%B8%8E%E5%8F%8D%E8%B5%B0%E6%A0%B7/</guid>
|
||
<pubDate>Thu, 12 May 2022 22:08:22 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h3 id="走样">走样</h3>
|
||
<h4 id="从像素角度">从像素角度</h4>
|
||
<p>屏幕是由一个个像素组成,在光栅化时,只有中心被三角形覆盖的像素会被着色,而且被覆盖的像素点的分布往往是离散的,自然而然地形成如下图斜线形成的阶梯状的锯齿</p>
|
||
<p><img src="../../images/aliasing_pixel.png" alt=""></p>
|
||
<hr>
|
||
<h4 id="从信号角度">从信号角度</h4>
|
||
<h5 id="采样和滤波理论sampling-and-filtering-theory">采样和滤波理论(Sampling and Filtering Theory)</h5>
|
||
<h6 id="采样sample">采样(sample)</h6>
|
||
<p>采样就是将连续信号转换成离散信号(采样信号),经过滤波后会被恢复成重建信号</p>
|
||
<p><img src="../../images/sample_and_reconstruct.png" alt=""></p>
|
||
<p>如果采样的频率过低,则会发生走样或混叠(aliasing),如图中,蓝色的为原信号,红色为采样点,绿色虚线为重建后的信号</p>
|
||
<p>过低的采样频率会使重建的信号成为低频信号
|
||
<img src="../../images/figure.5.17.png" alt=""></p>
|
||
<p>若采样频率恰好是原信号的两倍,重建信号则表现为一条直线
|
||
<img src="../../images/figure5.17.1.png" alt=""></p>
|
||
<p>采样理论(sampling theorem):采样频率必须为原信号频率的两倍以上,才能完整地重建原始信号,存在一个最大频率,因而采样频率有频带限制
|
||
<br>奎斯特率(Nyquist rate): 频率为原信号频率两倍的采样频率<br></p>
|
||
<h6 id="重建reconstruction">重建(reconstruction)</h6>
|
||
<p>重建时需要采样信号进行滤波,通常使用下图中的三种滤波器(box filter,tent filter,sinc filter),且滤波器的面积必须为1以确保恢复的信号不会被放大或缩小</p>
|
||
<p><img src="../../images/three_filter.png" alt=""></p>
|
||
<p>box filter 对信号进行滤波并重建信号的过程如下图
|
||
<br>直接将采样点位置替换为box filter波形的方式会因 box filter 本身的不连续使重建信号产生不平滑的现象<br>
|
||
但仍然因其易于实现的特性被用于重建</p>
|
||
<p><img src="../../images/box_filter_construct.png" alt=""></p>
|
||
<hr>
|
||
<p>tent filter 在滤波时会对每个相邻的采样点之间使用线性插值,一次重建的信号更加平滑,但采样点位置会发生斜率突变,所以tent filter 并不完美</p>
|
||
<p><img src="../../images/tent_filter_constructed.png" alt=""></p>
|
||
<hr>
|
||
<p>出于让重建信号保持平滑的目的,我们必须使用一个理想低通滤波器</p>
|
||
<p>基于傅立叶变换理论的解释:理想低通滤波器在频域中的表现类似于box filter,在频域中相乘时会过滤掉所有超过这个滤波器宽度的频率,在频域的box fliter 转换到空域的时候会是一个sinc filter ,在频域相乘也等价于在空域中进行卷积,卷积即为滤波
|
||
<img src="../../images/convolution_theorem.png" alt=""></p>
|
||
<p>例如sinc filter就能够实现过滤高频信号,保留低频信号的理想低通滤波器效果</p>
|
||
<p><img src="../../images/sinc_filter_process.png" alt=""></p>
|
||
<p>对于sinc filter 在假设采样频率为$f_s$,采样点间隔为$\frac{1}{f_S}$的情况下,它会过滤掉超过$\frac{f_S}{2}$的所有高频信息,因此,sinc filter 在采样频率为1.0会是一个理想低通滤波器,此时采样信号的最大频率应当小于$\frac{1}{2}$,但是由于sinc filter 有无限的滤波范围,所以它会在某些范围内出现负值</p>
|
||
<p>尽管负值的出现不常见,但在实践时我们更倾向于使用无负值的lobes(常见的有高斯滤波器(Gaussian filter)),并且使用重采样(resample)的方式对重建信号进行放大或者缩小</p>
|
||
<p>注:如果对于卷积为主的各类滤波感到不解可见<a href="https://www.bilibili.com/video/BV1Vd4y1e7pj/">【官方双语】那么……什么是卷积?</a></p>
|
||
<hr>
|
||
<h4 id="重采样">重采样</h4>
|
||
<p>设采样信号灯的采样间隔为整数列,间隔为1,则我们可以通过重采样来将采样点间隔变为a,当$a&gt;1$时会缩小信号(downsampling),$a&lt;1$时会放大信号(upsampling)</p>
|
||
<p>如图,对重建信号使用双倍采样率进行重采样便实现了信号放大
|
||
<img src="../../images/resample_upsample.png" alt=""></p>
|
||
<p>这种方法不适用于信号缩小,易使信号过于高频</p>
|
||
<p>对于信号缩小的情况,我们需要先对1间隔采样信号使用$sinc(\frac{x}{2})$ filter 滤波产生一个连续信号,再重采样2间隔,由于频谱范围更大的低通滤波器才能过滤更多的高频信号,类似于对图像进行第一次模糊再重采样产生一个低分辨率图像</p>
|
||
<p><img src="../../images/resample_downsampling.png" alt=""></p>
|
||
<p>由下图可见,滤波可以对三角形的边缘产生模糊,进而产生一定的反走样效果
|
||
<img src="../../images/sample_resulst.png" alt="">
|
||
<img src="../../images/pre-filter_sample.png" alt=""></p>
|
||
<h3 id="反走样">反走样</h3>
|
||
<h4 id="现代反走样技术">现代反走样技术</h4>
|
||
<h5 id="screen-based-antialiasing">Screen-Based Antialiasing</h5>
|
||
<p>对于我们之前提到的采样,我们只对像素正方形的中心进行是否在三角形内部的判断,这意味着对于边缘的像素正方形,无论覆盖面积有多大,只要不包含中心点都会被判定在三角形外,从而不被渲染,当采样率提升,如下图的4spp(sample per pixel)以某种方式混合计算获得更好的像素效果</p>
|
||
<p><img src="../../images/Screen-Based.png" alt=""></p>
|
||
<p>Screen-Based Antialiasing 通常在屏幕空间区域使用采样图案来采样从而对颜色进行如下的加权计算</p>
|
||
<p>对整个像素内颜色的平均计算遵循:
|
||
$$p(x,y)=\sum_{i=1}^nw_ic(i,x,y)$$
|
||
$n:$每个像素内采样点的数量</p>
|
||
<p>$c(i,x,y):$ 计算采样位置在屏幕坐标系上的坐标$(x,y)$并填充颜色,也可以视为两个方程,$f(i,n)$定位屏幕上需要采样的位置$(x_f,y_f)$,第二个方程计算填充的颜色</p>
|
||
<p>$w_i:$每个采样点所占的权重,通常为uniform形式,由外界输入</p>
|
||
<h6 id="supersamping-antialiasing-ssaa-超采样抗锯齿">Supersamping Antialiasing (SSAA) 超采样抗锯齿</h6>
|
||
<p>在每一个像素里计算多个采样的算法往往被称为超采样(supersample)或过采样(oversample)</p>
|
||
<p>SSAA又被称为全屏幕抗锯齿(full-screen antialiasing,FSAA),也叫超采样抗锯齿(supersampling antialiasing,SSAA)</p>
|
||
<p>主要在于渲染比目标分辨率大的图像后,过滤邻近的像素点来采样至目标分辨率</p>
|
||
<p>例如:</p>
|
||
<p>当目标图像分辨率为1280$\times$1024时,渲染2560$\times$2048的图像后进行2$\times$2像素的采样,得到目标图像</p>
|
||
<p>劣势:</p>
|
||
<p>性能开销大,每次都需要对子样本进行完整的包含深度测试的采样,当然也可以减少采样点($2\times1或1\times2$)来减少部分开销</p>
|
||
<p>与超采样相关的累计缓存(accumulation buffer)也可以起到减少开销的作用,主要在于使用一个与生成图像分辨率相同的buffer,但每个通道中有更多的颜色bit</p>
|
||
<p>例如在采样的像素为$2\times2$的情况下,会生成4张图像且每张图都会在X或Y轴上偏移半个像素的距离使得输出像素的采样点正好对应图像的像素点中心</p>
|
||
<p>优势:</p>
|
||
<p>实现方式简单,只需要一个高分辨率图像和box filter就可以实现</p>
|
||
<p>下图是采样点在像素点内位置类型
|
||
<img src="../../images/sample_point_position.png" alt=""></p>
|
||
<p>案例:NAVIDIA's DSR(dynamic super resolution)</p>
|
||
<p>渲染4k的图像利用13个采样点的高斯滤波采样回1080p提升画面细节</p>
|
||
<hr>
|
||
<h6 id="msaamultisampling-antialiasing">MSAA(Multisampling antialiasing)</h6>
|
||
<p>MSAA同样在一个像素中设置多个采样点,在光栅化时计算三角形在像素内对采样点的覆盖率,之后只计算每个片元的像素着色器,采样中心点的位置计算颜色信息再乘上覆盖率,最后输出这个像素的颜色</p>
|
||
<p>颜色计算与深度判断
|
||
<img src="../../images/MSAA.png" alt=""></p>
|
||
<p>总体流程如下
|
||
<img src="../../images/MSAA_sample.png" alt="">
|
||
<img src="../../images/MSAA_color.png" alt=""></p>
|
||
<p>与SSAA不同的是,MSAA只对每个像素计算一次采样,而非对整个图像进行渲染,但计算量依旧倍增</p>
|
||
<hr>
|
||
<h6 id="csaacoverage-sampling-antialiasing-and-eqaaenhanced-quality-antialiasing">CSAA(coverage sampling antialiasing) and EQAA(enhanced quality antialiasing)</h6>
|
||
<p>两者前后分别在2006年由NVIDIA和AMD先后提出</p>
|
||
<p>两种技术都通过提前存储片元的平均效果来提高采样率</p>
|
||
<p>例如,EQAA在2f4x模式下,会对每四个采样点计算并通过表的形式存储颜色和深度值(如下图),这使得四个采样点只需1bit空间就可以确认像素位置的着色颜色值</p>
|
||
<p><img src="../../images/EQAA_color_table.png" alt=""></p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>采样与光栅化</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E9%87%87%E6%A0%B7%E4%B8%8E%E5%85%89%E6%A0%85%E5%8C%96/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E9%87%87%E6%A0%B7%E4%B8%8E%E5%85%89%E6%A0%85%E5%8C%96/</guid>
|
||
<pubDate>Thu, 12 May 2022 09:10:25 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h4 id="屏幕空间">屏幕空间</h4>
|
||
<p>屏幕空间可以被看做是由一组像素点构成,每个像素点可以被视为中心为$(x+0.5,y+0.5)$的一个正方形,</p>
|
||
<p><img src="../../images/pixel_and_screen_space.png" alt=""></p>
|
||
<hr>
|
||
<h4 id="模型的面">模型的面</h4>
|
||
<p>大多数模型的面(mesh)以三角形为主(也有一些不同的面)
|
||
选择三角形的原因:</p>
|
||
<ol>
|
||
<li>大多数多边形最终都可以被分割为三角形</li>
|
||
<li>边界清晰,便于判定某个点是否位于面内(与采样有关)</li>
|
||
<li>对于三角形的每个顶点值有清晰的插值方式(质心插值)</li>
|
||
</ol>
|
||
<hr>
|
||
<h4 id="采样的功能光栅化">采样的功能(光栅化)</h4>
|
||
<p>遍历整个屏幕上所有的像素点,如果某个像素点的中心位于三角形内,则对这个像素点进行采样</p>
|
||
<p>伪代码</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">xmax</span><span class="p">;</span> <span class="o">++</span><span class="n">x</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">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">y</span><span class="o">&lt;</span> <span class="n">xmax</span> <span class="p">;</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">image</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">inside</span><span class="p">(</span><span class="n">tri</span><span class="p">,</span><span class="n">x</span><span class="o">+</span><span class="mf">0.5</span><span class="p">,</span><span class="n">y</span><span class="o">+</span><span class="mf">0.5</span><span class="p">);</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>可视化过程如图</p>
|
||
<p><img src="../../images/sample_progress.png" alt=""></p>
|
||
<hr>
|
||
<h4 id="判断像素点在三角形内部">判断像素点在三角形内部</h4>
|
||
<p>inside的判断主要由叉乘(cross product)来实现</p>
|
||
<p>计算三角形各边的向量和目标测试点与三角形三个顶点的向量,将各边向量分别与测试点与顶点的向量进行叉乘,得出三个值,如果三个值得符号相同,则目标测试点位于三角形内,相反则测试点在三角形外</p>
|
||
<p>代码实现</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-C++" data-lang="C++"><span class="line"><span class="cl"><span class="c1">//判断测试点是否在三角形内
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">bool</span> <span class="nf">insideTriangle</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="k">const</span> <span class="n">Vector3f</span><span class="o">*</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="c1">// TODO : Implement this function to check if the point (x, y) is inside
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// the triangle represented by _v[0], _v[1], _v[2]
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></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="c1"></span> <span class="c1">//三角形三点的坐标分别为_v[0], _v[1], _v[2]
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//叉乘公式为(x1, y1)X(x2, y2) = x1*y2 - y1*x2
|
||
</span></span></span><span class="line"><span class="cl"><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="c1"></span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span> <span class="n">side1</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">side1</span> <span class="o">&lt;-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">_v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span> <span class="n">side2</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">side2</span> <span class="o">&lt;-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">_v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span> <span class="n">side3</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">side3</span> <span class="o">&lt;-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">()</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">_v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</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="c1"></span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span> <span class="n">v1</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">v1</span> <span class="o">&lt;-</span> <span class="n">x</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">y</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span> <span class="n">v2</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">v2</span> <span class="o">&lt;-</span> <span class="n">x</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">y</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">Eigen</span><span class="o">::</span><span class="n">Vector2f</span> <span class="n">v3</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">v3</span> <span class="o">&lt;-</span> <span class="n">x</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">y</span> <span class="o">-</span> <span class="n">_v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</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="c1"></span> <span class="kt">float</span> <span class="n">z1</span> <span class="o">=</span> <span class="n">side1</span><span class="p">.</span><span class="n">x</span><span class="p">()</span> <span class="o">*</span> <span class="n">v1</span><span class="p">.</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">side1</span><span class="p">.</span><span class="n">y</span><span class="p">()</span> <span class="o">*</span> <span class="n">v1</span><span class="p">.</span><span class="n">x</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">z2</span> <span class="o">=</span> <span class="n">side2</span><span class="p">.</span><span class="n">x</span><span class="p">()</span> <span class="o">*</span> <span class="n">v2</span><span class="p">.</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">side2</span><span class="p">.</span><span class="n">y</span><span class="p">()</span> <span class="o">*</span> <span class="n">v2</span><span class="p">.</span><span class="n">x</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">z3</span> <span class="o">=</span> <span class="n">side3</span><span class="p">.</span><span class="n">x</span><span class="p">()</span> <span class="o">*</span> <span class="n">v3</span><span class="p">.</span><span class="n">y</span><span class="p">()</span> <span class="o">-</span> <span class="n">side3</span><span class="p">.</span><span class="n">y</span><span class="p">()</span> <span class="o">*</span> <span class="n">v3</span><span class="p">.</span><span class="n">x</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="c1"></span> <span class="k">if</span> <span class="p">((</span><span class="n">z1</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">z2</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">z3</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">z1</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">z2</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">z3</span> <span class="o">&lt;</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="k">return</span> <span class="nb">true</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="k">return</span> <span class="nb">false</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></td></tr></table>
|
||
</div>
|
||
</div><h4 id="加速算法">加速算法</h4>
|
||
<h5 id="bounding-box">Bounding box</h5>
|
||
<p>每一次判断屏幕上的像素点是否在三角形内都检测所有在屏幕上像素点会带来额外的性能开销和渲染时间</p>
|
||
<p>使用包围盒将三角形包围后,只判断包围盒内的像素点是否在三角形内能够减少这种情况的出现</p>
|
||
<p><img src="../../images/BoundingBox.png" alt=""></p>
|
||
<p>代码实例</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"> <span class="k">auto</span> <span class="n">v</span> <span class="o">=</span> <span class="n">t</span><span class="p">.</span><span class="n">toVector4</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="c1"></span> <span class="kt">float</span> <span class="n">min_x</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">min</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">std</span><span class="o">::</span><span class="n">min</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()));</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">max_x</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">(),</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">x</span><span class="p">()));</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">min_y</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">min</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">(),</span> <span class="n">std</span><span class="o">::</span><span class="n">min</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">(),</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()));</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">float</span> <span class="n">max_y</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">(),</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">(),</span> <span class="n">v</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">y</span><span class="p">()));</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><h5 id="incremental-triangle-traversal">incremental triangle Traversal</h5>
|
||
<p>对于每一行像素点,只遍历三角形最左到最右的像素点,只适用于较窄的且经过旋转的三角形</p>
|
||
<p><img src="../../images/IncrementalTriangleTraversal.png" alt=""></p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>递归</title>
|
||
<link>http://www.inksoul.top/algorithm/%E9%80%92%E5%BD%92/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/algorithm/%E9%80%92%E5%BD%92/</guid>
|
||
<pubDate>Tue, 10 May 2022 09:10:48 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><ul>
|
||
<li>递归技术
|
||
<ul>
|
||
<li>直接或间接地调用自身的算法称为递归算法</li>
|
||
<li>用函数自身给出定义的函数称为递归函数</li>
|
||
<li>每个递归函数都必须有非递归定义的初始值,否则递归函数无法计算</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<hr>
|
||
<ul>
|
||
<li>阶乘函数
|
||
<ul>
|
||
<li>
|
||
<p>可递归地定义为$n!= \begin{cases}1,&amp; \text{n=0} \\ n(n-1)!,&amp;\text{n&gt;0} \end{cases}$</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">Factorial</span><span class="o">(</span><span class="kt">int</span> <span class="n">n</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">n</span><span class="o">==</span><span class="mi">0</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">n</span><span class="o">*</span><span class="n">Factorial</span><span class="o">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<hr>
|
||
<ul>
|
||
<li>
|
||
<p>Fibonacci数列</p>
|
||
<ul>
|
||
<li>可递归地定义为$F(n)=\begin{cases}1, &amp;\text{n=0},1 \\ F(n-1)+F(n-2) &amp;\text{n&gt;1} \end{cases}$</li>
|
||
</ul>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">fibonacci</span><span class="o">(</span><span class="kt">int</span> <span class="n">n</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">n</span><span class="o">&lt;=</span><span class="mi">1</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">fibonacci</span><span class="o">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="o">)+</span><span class="n">fibonacci</span><span class="o">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div></li>
|
||
</ul>
|
||
<hr>
|
||
<ul>
|
||
<li>
|
||
<p>排列问题</p>
|
||
<ul>
|
||
<li>
|
||
<p>当$n=1时,perm(R)=(r)$,其中r是集合R中唯一的元素;</p>
|
||
</li>
|
||
<li>
|
||
<p>$当n&gt;1时,perm(R)=(r)$
|
||
$perm(R)由(r_1)perm(R_1),(r_2)perm(R_2),\cdots,(r_n)perm(R_n)构成$</p>
|
||
</li>
|
||
<li>
|
||
<p>算法perm(list,k,m)递归地产生所有前缀是list[0:k-1],且后缀是list[k:m]的全排列的所有排列。调用perm(list,0,n-1)即产生list[0:n-1]的全排列</p>
|
||
</li>
|
||
<li>
|
||
<p>一般情况下,$k&lt;m$</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">perm</span><span class="o">(</span><span class="n">Object</span><span class="o">[]</span> <span class="n">list</span><span class="o">,</span><span class="kt">int</span> <span class="n">k</span><span class="o">,</span><span class="kt">int</span> <span class="n">m</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">k</span><span class="o">==</span><span class="n">m</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="c1"></span> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span><span class="n">i</span><span class="o">&lt;=</span><span class="n">m</span><span class="o">;</span><span class="n">i</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="n">list</span><span class="o">[</span><span class="n">i</span><span class="o">]);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//还有多个元素,递归产生排列
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">k</span><span class="o">;</span><span class="n">i</span><span class="o">&lt;=</span><span class="n">m</span><span class="o">;</span><span class="n">i</span><span class="o">++)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">MyMath</span><span class="o">.</span><span class="na">swap</span><span class="o">(</span><span class="n">list</span><span class="o">,</span><span class="n">k</span><span class="o">,</span><span class="n">i</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">perm</span><span class="o">(</span><span class="n">list</span><span class="o">,</span><span class="n">k</span><span class="o">+</span><span class="mi">1</span><span class="o">,</span><span class="n">m</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">MyMath</span><span class="o">.</span><span class="na">swap</span><span class="o">(</span><span class="n">list</span><span class="o">,</span><span class="n">k</span><span class="o">,</span><span class="n">i</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">MyMath</span><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">swap</span><span class="o">(</span><span class="n">Object</span><span class="o">[]</span> <span class="n">list</span><span class="o">,</span><span class="kt">int</span> <span class="n">k</span><span class="o">,</span><span class="kt">int</span> <span class="n">m</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">k</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">k</span> <span class="o">=</span> <span class="n">m</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">m</span> <span class="o">=</span> <span class="n">temp</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<hr>
|
||
<ul>
|
||
<li>
|
||
<p>整数划分问题</p>
|
||
<ul>
|
||
<li>
|
||
<p>将正整数$n$表示成一系列正整数之和,$n=n_1+n_2+...+n_k$,其中$n_1\geq n_2\geq ...\geq n_k\geq 1,k\geq 1$</p>
|
||
</li>
|
||
<li>
|
||
<p>将最大加数$n_1$不大于$m$的划分个数记作$q(n,m)$可建立如下递归关系</p>
|
||
<ul>
|
||
<li>当最大加数$n_1$不大于1时,任何正整数n只有一种划分形式,即$n=\begin{matrix} n \\ \overbrace{1+1+\cdots+1}\end{matrix}$</li>
|
||
<li>最大加数$n_1$实际上不能大于$n$。因此,$q(1,m)=1$。</li>
|
||
<li>正整数$n$的划分由$n_1=n$的划分和$n_1\leq n-1$的划分组成</li>
|
||
<li>正整数$n$的最大加数$n_1$不大于$m$的划分由$n_1=m$的划分和$n_1\leq m-1$的划分组成</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">q</span><span class="o">(</span><span class="kt">int</span> <span class="n">n</span><span class="o">,</span><span class="kt">int</span> <span class="n">m</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">((</span><span class="n">n</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">)||(</span><span class="n">m</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">))</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">0</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">((</span><span class="n">n</span><span class="o">==</span><span class="mi">1</span><span class="o">)||(</span><span class="n">m</span><span class="o">==</span><span class="mi">1</span><span class="o">))</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">n</span><span class="o">&lt;</span><span class="n">m</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">q</span><span class="o">(</span><span class="n">n</span><span class="o">,</span><span class="n">n</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">n</span><span class="o">==</span><span class="n">m</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">q</span><span class="o">(</span><span class="n">n</span><span class="o">,</span><span class="n">m</span><span class="o">-</span><span class="mi">1</span><span class="o">)+</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">q</span><span class="o">(</span><span class="n">n</span><span class="o">,</span><span class="n">m</span><span class="o">-</span><span class="mi">1</span><span class="o">)+</span><span class="n">q</span><span class="o">(</span><span class="n">n</span><span class="o">-</span><span class="n">m</span><span class="o">,</span><span class="n">m</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div></li>
|
||
</ul>
|
||
<hr>
|
||
<ul>
|
||
<li>
|
||
<p>Hanoi塔问题</p>
|
||
<ul>
|
||
<li>
|
||
<p>设a,b,c是三个塔座。开始是在塔座a上有一叠共n个圆盘,这些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号为1,2,···,n。现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置。在移动圆盘时应该遵守以下移动规则。</p>
|
||
<ul>
|
||
<li>每次只移动一个圆盘</li>
|
||
<li>任何时刻都不允许将较大的圆盘压在较小的圆盘之上。</li>
|
||
<li>在满足前两个规则的前提下,可将圆盘移至a,b,c任一塔座上</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<p>递归关系</p>
|
||
<ul>
|
||
<li>$n=1$时,将编号为一的圆盘从塔座a直接移至塔座b上即可。</li>
|
||
<li>$n&gt;1$时,需要利用塔座c作为辅助塔座,
|
||
<ul>
|
||
<li>将$n-1$个较小的圆盘依照移动规则从塔座a移至塔座c,</li>
|
||
<li>将剩下的最大圆盘从塔座a移至塔座b,</li>
|
||
<li>将$n-1$个较小的圆盘依照移动规则从塔座c移至塔座b</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">hanoi</span><span class="o">(</span><span class="kt">int</span> <span class="n">n</span><span class="o">,</span><span class="kt">char</span> <span class="n">a</span><span class="o">,</span><span class="kt">char</span> <span class="n">b</span><span class="o">,</span><span class="kt">char</span> <span class="n">c</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">n</span><span class="o">&gt;</span><span class="mi">0</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">hanoi</span><span class="o">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="n">c</span><span class="o">,</span> <span class="n">b</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">move</span><span class="o">(</span><span class="n">n</span><span class="o">,</span><span class="n">a</span><span class="o">,</span><span class="n">b</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">hanoi</span><span class="o">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span><span class="n">c</span><span class="o">,</span><span class="n">b</span><span class="o">,</span><span class="n">a</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">move</span><span class="o">(</span><span class="kt">int</span> <span class="n">n</span><span class="o">,</span><span class="kt">char</span> <span class="n">a</span><span class="o">,</span><span class="kt">char</span> <span class="n">b</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;第&#34;</span><span class="o">+</span><span class="n">n</span><span class="o">+</span><span class="s">&#34;个盘子从&#34;</span><span class="o">+</span><span class="n">a</span><span class="o">+</span><span class="s">&#34;---&gt;&#34;</span><span class="o">+</span><span class="n">b</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div></li>
|
||
<li>
|
||
<p>递归调用总结和系统原理</p>
|
||
<ul>
|
||
<li>实现递归调用的关键:为算法建立递归调用工作栈</li>
|
||
<li>运行被调用算法前的行为
|
||
<ul>
|
||
<li>为所有实参指针,返回地址等信息传递给被调用算法</li>
|
||
<li>为被调用算法的局部变量分配存储区</li>
|
||
<li>将控制转移到被调用算法的入口</li>
|
||
</ul>
|
||
</li>
|
||
<li>从被调用算法返回调用算法时
|
||
<ul>
|
||
<li>保存被调用算法的计算结果</li>
|
||
<li>释放分配给被调用算法的数据区</li>
|
||
<li>依照被调用算法保存的返回地址将控制转移到调用算法</li>
|
||
</ul>
|
||
</li>
|
||
<li>嵌套调用时的系统原则:后调用先返回,即算法间的信息传递和控制转移通过栈来实现</li>
|
||
<li>递归算法的调用层次
|
||
<ul>
|
||
<li>调用一个递归算法的主算法为第0层算法</li>
|
||
<li>从主算法调用递归算法为进入第1层调用</li>
|
||
<li>从第i层递归调用本算法为进入第i+1层调用。</li>
|
||
<li>退出第i层递归调用,则返回至i-1层调用。</li>
|
||
</ul>
|
||
</li>
|
||
<li>递归调用的栈使用情况示意</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th style="text-align:center">主算法栈块</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td style="text-align:center">M</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">主算法调用递归算法A的栈块</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">算法A的第一层递归调用工作记录</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">算法A的第二层递归调用工作记录</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">TOP</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center">M</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/algorithm/">algorithm\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>3D基本变换和观测变换(viewing transform)</title>
|
||
<link>http://www.inksoul.top/computergraphic/%E5%9F%BA%E6%9C%AC%E5%8F%98%E6%8D%A2/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/computergraphic/%E5%9F%BA%E6%9C%AC%E5%8F%98%E6%8D%A2/</guid>
|
||
<pubDate>Tue, 10 May 2022 09:10:25 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h2 id="3d基本变换">3D基本变换</h2>
|
||
<h3 id="平移矩阵">平移矩阵</h3>
|
||
<p>通常处理三维中对模型进行平移的行为</p>
|
||
<p><br>$T(t_x,t_y,t_z) = \begin{pmatrix} 1 &amp;0 &amp;0 &amp;t_x \\ 0 &amp;1 &amp;0 &amp;t_y \\ 0 &amp;0 &amp;0 &amp;t_z \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix} $<br></p>
|
||
<p>$t_x,t_y,t_z$通常表示对应轴上平移的距离</p>
|
||
<hr>
|
||
<h3 id="缩放矩阵">缩放矩阵</h3>
|
||
<p>通常处理三维中对模型进行缩放的行为</p>
|
||
<p>$S(s_x,s_y,s_z) = \begin{pmatrix} s_x &amp;0 &amp;0 &amp;0 \\0 &amp;s_y &amp;0 &amp;0 \\ 0 &amp;0 &amp;s_z &amp;0 \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix} $</p>
|
||
<p>$s_x,s_y,s_z$通常表示对应xyz轴的缩放比例</p>
|
||
<hr>
|
||
<h3 id="旋转矩阵">旋转矩阵</h3>
|
||
<p>这个矩阵通常处理三维中对模型绕坐标轴进行旋转的行为</p>
|
||
<hr>
|
||
<p>绕x轴旋转的矩阵为
|
||
$\begin{pmatrix} 1 &amp;0 &amp;0 &amp;0 \\ 0 &amp;cos(r) &amp;-sin(r) &amp;0 \\ 0 &amp;sin(r) &amp;cos(r) &amp;0 \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix} $</p>
|
||
<hr>
|
||
<p>绕y轴旋转的矩阵为
|
||
$\begin{pmatrix} cos(r) &amp;0 &amp;sin(r) &amp;0 \\ 0 &amp;1 &amp;0 &amp;0 \\ -sin(r) &amp;0 &amp;cos(r) &amp;0 \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix} $</p>
|
||
<hr>
|
||
<p>绕z轴旋转的矩阵为
|
||
$\begin{pmatrix} cos(r) &amp;-sin(r) &amp;0 &amp;0 \\ sin(r) &amp;cos(r) &amp;0 &amp;0 \\ 0 &amp;0 &amp;1 &amp;0 \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix} $</p>
|
||
<hr>
|
||
<p>对于给定三个旋转角度的旋转,通常使用欧拉角</p>
|
||
<p>$R_{xyz}(\alpha,\beta,\gamma)=R_x(\alpha)R_y(\beta)R_z(\gamma)$</p>
|
||
<p>此时的三个旋转方向将被称为roll,pich,yaw</p>
|
||
<p><img src="../../images/flight_euler_angle.png" alt="flight_euler"></p>
|
||
<hr>
|
||
<p>对于围绕某一特定点进行旋转的行为,则将该点平移至原点处后视为绕特定轴旋转
|
||
<img src="../../images/rotate_around_point.png" alt=""></p>
|
||
<hr>
|
||
<h3 id="视角变换矩阵">视角变换矩阵</h3>
|
||
<p>这个矩阵通常用来定义相机对应的视角朝向,利用这个矩阵来将相机位置移动到原点,便于后续的模型进行平移旋转等变换</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||
</span><span class="lnt">2
|
||
</span><span class="lnt">3
|
||
</span><span class="lnt">4
|
||
</span><span class="lnt">5
|
||
</span><span class="lnt">6
|
||
</span><span class="lnt">7
|
||
</span><span class="lnt">8
|
||
</span><span class="lnt">9
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="n">Eigen</span><span class="o">::</span><span class="n">Matrix4f</span> <span class="n">view</span> <span class="o">=</span> <span class="n">Eigen</span><span class="o">::</span><span class="n">Matrix4f</span><span class="o">::</span><span class="n">Identity</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"><span class="n">Eigen</span><span class="o">::</span><span class="n">Matrix4f</span> <span class="n">translate</span><span class="p">;</span>
|
||
</span></span><span class="line"><span class="cl"><span class="n">translate</span> <span class="o">&lt;&lt;</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="o">-</span><span class="n">eye_pos</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
|
||
</span></span><span class="line"><span class="cl"> <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="o">-</span><span class="n">eye_pos</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
|
||
</span></span><span class="line"><span class="cl"> <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="o">-</span><span class="n">eye_pos</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
|
||
</span></span><span class="line"><span class="cl"> <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></span><span class="line"><span class="cl"><span class="n">view</span> <span class="o">=</span> <span class="n">translate</span> <span class="o">*</span> <span class="n">view</span><span class="p">;</span><span class="c1">//移动相机位置到顶点
|
||
</span></span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div><p>在上述代码中,eye_pos(x,y,z,1)往往为相机的位置</p>
|
||
<hr>
|
||
<h3 id="正交投影矩阵">正交/投影矩阵</h3>
|
||
<h4 id="正交矩阵">正交矩阵</h4>
|
||
<p>正交矩阵将使摄像头置于坐标系原点,看向-Z轴方向,可以在Y轴上平行移动。
|
||
最终结果将表现为在XY轴平面上的2D图像,让模型坐标归一化到[-1,1]之间</p>
|
||
<hr>
|
||
<p>总体流程</p>
|
||
<p>为了将一个$[l,r]\times[b,t]\times[f,n]$的长方体转换为符合canonical(正则、规范、标准)的正方体,我们需要进行两步操作</p>
|
||
<p>第一步</p>
|
||
<p>平移这个长方体到坐标系的原点</p>
|
||
<p>对应矩阵$M_{translate}=\begin{bmatrix} \frac{2}{r-l} &amp;0 &amp;0 &amp;0 \\ 0 &amp;\frac{2}{t-b} &amp;0 &amp;0 \\ 0 &amp;0 &amp;0 &amp;\frac{2}{n-f} \\ 0 &amp;0 &amp;0 &amp;1 \end{bmatrix}$</p>
|
||
<p>第二步</p>
|
||
<p>缩放这个长方体到符合正则、规范、标准的正方体</p>
|
||
<p>对应矩阵$M_{scale}=\begin{bmatrix} 1 &amp;0 &amp;0 &amp;-\frac{r+l}{2} \\ 0 &amp;1 &amp;0 &amp;-\frac{t+b}{2} \\ 0 &amp;0 &amp;1 &amp;-\frac{n+f}{2} \\ 0 &amp;0 &amp;0 &amp;1 \end{bmatrix}$</p>
|
||
<p>由第一二步可得出</p>
|
||
<p>正交矩阵为$M_{ortho}=\begin{bmatrix} \frac{2}{r-l} &amp;0 &amp;0 &amp;0 \\ 0 &amp;\frac{2}{t-b} &amp;0 &amp;0 \\ 0 &amp;0 &amp;0 &amp;\frac{2}{n-f} \\ 0 &amp;0 &amp;0 &amp;1 \end{bmatrix}\times\begin{bmatrix} 1 &amp;0 &amp;0 &amp;-\frac{r+l}{2} \\ 0 &amp;1 &amp;0 &amp;-\frac{t+b}{2} \\ 0 &amp;0 &amp;1 &amp;-\frac{n+f}{2} \\ 0 &amp;0 &amp;0 &amp;1 \end{bmatrix}$</p>
|
||
<p>图示</p>
|
||
<p><img src="../../images/3I~K5PRW$Y5JLF3%7DRC@RE0P.png" alt="正交矩阵"></p>
|
||
<hr>
|
||
<h4 id="投影矩阵">投影矩阵</h4>
|
||
<p>投影矩阵将使模型满足自然界透视效果,如物体近大远小、所有的平行线变得不再平行,总会交于一点</p>
|
||
<hr>
|
||
<p>推导过程</p>
|
||
<p>将远平面与近平面连线形成的梯形“挤压”到成为一个正方体</p>
|
||
<p><img src="../../images/X(%7BM%7BB)24R8DF%5BAB98E9%5D@1.png" alt=""></p>
|
||
<p>挤压的过程对梯形做横切面可知,计算挤压后的坐标点值实质上为计算相似三角形</p>
|
||
<p>如下图,可知挤压后的坐标与之前的坐标存在的数学关系为
|
||
<img src="../../images/3O_1NAGAMER%25%5BEP6T91$LBO.png" alt=""></p>
|
||
<p>$$y^{'}=\frac{n}{z}y$$ $$x^{'}=\frac{n}{z}x$$</p>
|
||
<p>由此可知经过“挤压”后的坐标为
|
||
$$M_{persp-&gt;ortho}\times\begin{pmatrix}
|
||
x \\ y \\ z \\ 1
|
||
\end{pmatrix}=\begin{pmatrix}
|
||
nx \\ ny \\ {未知} \\ z
|
||
\end{pmatrix}$$</p>
|
||
<p>所以
|
||
$$M_{persp-&gt;ortho}=\begin{pmatrix}
|
||
n &amp;0 &amp;0 &amp;0 \\ 0 &amp;n &amp;0 &amp;0 \\ ? &amp;? &amp;? &amp;? \\ 0 &amp;0 &amp;1 &amp;0
|
||
\end{pmatrix}$$</p>
|
||
<p>又由远平面在被“挤压”后相当于近平面做正交投影得到的远平面,可知</p>
|
||
<ol>
|
||
<li>任何在近平面上的点的坐标在“挤压”的过程中不发生改变</li>
|
||
<li>任何在远平面的点的坐标中的Z值不发生改变,即$$\begin{pmatrix}
|
||
0 \\ 0 \\ f \\ 1
|
||
\end{pmatrix}\rArr\begin{pmatrix}
|
||
0 \\ 0 \\ f \\ 1
|
||
\end{pmatrix}==\begin{pmatrix}
|
||
0 \\ 0 \\ f^2 \\ f
|
||
\end{pmatrix}$$</li>
|
||
</ol>
|
||
<p>在将上述坐标公式中Z的值以n替换之后可得
|
||
$$\begin{pmatrix}
|
||
x \\ y \\ n \\ 1
|
||
\end{pmatrix}\rArr\begin{pmatrix}
|
||
x \\ y \\ n \\ 1
|
||
\end{pmatrix}==\begin{pmatrix}
|
||
nx \\ ny \\ n^2 \\ n
|
||
\end{pmatrix}$$
|
||
据此,可推测第三行未知坐标值符合以下关系
|
||
$$\begin{pmatrix}
|
||
0 &amp;0 &amp;A &amp;B
|
||
\end{pmatrix}\begin{pmatrix}
|
||
x \\ y \\ n \\ 1
|
||
\end{pmatrix}=n^2$$
|
||
因此
|
||
$$An+B=n^2$$
|
||
联立性质2推导的
|
||
$$Af+B=f^2$$
|
||
可得出
|
||
$$A=n+f$$
|
||
$$B=-nf$$</p>
|
||
<p>所以
|
||
$$M_{persp}=M_{ortho}M_{persp-&gt;ortho}=$$
|
||
$$\begin{pmatrix} \frac{2}{r-l} &amp;0 &amp;0 &amp;0 \\ 0 &amp;\frac{2}{t-b} &amp;0 &amp;0 \\ 0 &amp;0 &amp;0 &amp;\frac{2}{n-f} \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix}$$
|
||
$$\times$$
|
||
$$\begin{pmatrix} 1 &amp;0 &amp;0 &amp;-\frac{r+l}{2} \\ 0 &amp;1 &amp;0 &amp;-\frac{t+b}{2} \\ 0 &amp;0 &amp;1 &amp;-\frac{n+f}{2} \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix}$$
|
||
$$\times$$
|
||
$$\begin{pmatrix} n &amp;0 &amp;0 &amp;0 \\ 0 &amp;n &amp;0 &amp;0 \\ 0 &amp;0 &amp;n+f &amp;-nf \\ 0 &amp;0 &amp;1 &amp;0 \end{pmatrix}$$</p>
|
||
<hr>
|
||
<h4 id="涉及fovy的投影矩阵">涉及FovY的投影矩阵</h4>
|
||
<p>FovY表示视域,即摄像机在固定时能看到的最大角度或最低角度的范围</p>
|
||
<p>Aspect ratio 表示纵横比,投影平面的长宽比
|
||
<img src="../../images/fovY.png" alt=""></p>
|
||
<p>对应的相似三角形关系不变,参数改变
|
||
<img src="../../images/triangle.png" alt="">
|
||
可得如下关系
|
||
$$\tan{\frac{fovY}{2}}=\frac{t}{|n|}$$
|
||
$$aspect=\frac{r}{t}$$
|
||
因此
|
||
$$t=near\times tan(\frac{fovY}{2})$$</p>
|
||
<p>$$r=aspect\times near\times tan(\frac{fovY}{2})$$
|
||
$$l=-aspect\times near \times tan(fovY/2)$$
|
||
带入上述由l,b,n,f构成的矩阵可得
|
||
$$M_{persp-&gt;ortho}$$
|
||
$$=$$
|
||
$$\begin{pmatrix} \frac{2}{r-l} &amp;0 &amp;0 &amp;0 \\ 0 &amp;\frac{2}{t-b} &amp;0 &amp;0 \\ 0 &amp;0 &amp;\frac{2}{n-f} &amp;0 \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix}$$
|
||
$$\times$$
|
||
$$\begin{pmatrix} 1 &amp;0 &amp;0 &amp;-\frac{r+l}{2} \\ 0 &amp;1 &amp;0 &amp;-\frac{t+b}{2} \\ 0 &amp;0 &amp;1 &amp;-\frac{n+f}{2} \\ 0 &amp;0 &amp;0 &amp;1 \end{pmatrix}$$
|
||
$$=$$</p>
|
||
<p>$$\begin{pmatrix}
|
||
\frac{\frac{\cot{FovY}}{2}}{apsect*near} &amp;0 &amp;0 &amp;0 \\ 0 &amp; \frac{\frac{\cot{FovY}}{2}}{near} &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; \frac{2}{near-far} &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 1
|
||
\end{pmatrix}$$</p>
|
||
<p>$$\times$$</p>
|
||
<p>$$\begin{pmatrix}
|
||
1 &amp;0 &amp;0 &amp;0 \\ 0 &amp;1 &amp;0 &amp;0 \\ 0 &amp;0 &amp;1 &amp;-\frac{near+far}{2} \\ 0 &amp;0 &amp;0 &amp;1
|
||
\end{pmatrix}$$</p>
|
||
<p>$$=$$</p>
|
||
<p>$$\begin{pmatrix}
|
||
\frac{\frac{\cot{FovY}}{2}}{apsect * near} &amp;0 &amp;0 &amp;0 \\ 0 &amp;\frac{\frac{\cot{FovY}}{2}}{near} &amp;0 &amp;0 \\ 0 &amp;0 &amp;\frac{2}{near-far} &amp;-\frac{near+far}{near-far} \\ 0 &amp;0 &amp;0 &amp;1
|
||
\end{pmatrix}$$</p>
|
||
<hr>
|
||
<h4 id="视口变换">视口变换</h4>
|
||
<p>经过MVP矩阵计算后得到的一个正则的正方体需要将X轴和Y轴上的坐标映射到屏幕坐标[0,width]$\times$[0,height]</p>
|
||
<p>变换时需要先将[-1,1]缩放到屏幕大小[width,height],再进行平移使得原点坐标与屏幕原点对齐</p>
|
||
<p>变换矩阵
|
||
$$M_{viewport}=\begin{bmatrix}
|
||
\frac{width}{2} &amp;0 &amp;0 &amp;\frac{width}{2} \\ 0 &amp;\frac{height}{2} &amp;0 &amp;\frac{height}{2} \\ 0 &amp;0 &amp;1 &amp;0 \\ 0 &amp;0 &amp;0 &amp;1
|
||
\end{bmatrix}$$</p>
|
||
</description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/computergraphic/">computergraphic\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
<item>
|
||
<title>分治法</title>
|
||
<link>http://www.inksoul.top/algorithm/%E5%88%86%E6%B2%BB%E6%B3%95/</link>
|
||
<guid isPermaLink="true">http://www.inksoul.top/algorithm/%E5%88%86%E6%B2%BB%E6%B3%95/</guid>
|
||
<pubDate>Tue, 10 May 2022 09:10:25 +0800</pubDate>
|
||
|
||
<author>qingci30@163.com (InkSoul)</author>
|
||
|
||
<copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)</copyright>
|
||
|
||
<description><h5 id="基本思想">基本思想</h5>
|
||
<p>将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解这些子问题,然后将各子问题的解合并得到原问题的解
|
||
子问题数量不定,但最好使每个子问题的规模相等</p>
|
||
<p>一般算法设计模式</p>
|
||
<pre tabindex="0"><code>divide-and-conquer(p)
|
||
{
|
||
if(|p|&lt;=n0)
|
||
adhoc(p);
|
||
divide p into smaller subinstances p1,p2,pk;
|
||
for(i=1,i&lt;=k,k++)
|
||
yi=divide-and-conquer(pi);
|
||
return merge(y1,···,yk);
|
||
}
|
||
</code></pre><hr>
|
||
<h6 id="二分搜索技术">二分搜索技术</h6>
|
||
<p>将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较。</p>
|
||
<ol>
|
||
<li>
|
||
<p>$x=[n/2]$,则找到x,算法终止</p>
|
||
</li>
|
||
<li>
|
||
<p>$x&lt;a[n/2]$,在数组a的左半部继续搜索x</p>
|
||
</li>
|
||
<li>
|
||
<p>$x&gt;a[n/2]$,在数组a的右半部继续搜索x</p>
|
||
<p>具体算法</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">binarySearch</span><span class="o">(</span><span class="kt">int</span> <span class="o">[]</span> <span class="n">a</span><span class="o">,</span><span class="kt">int</span> <span class="n">x</span><span class="o">,</span><span class="kt">int</span> <span class="n">n</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//在a[0]&lt;=a[1]&lt;=···&lt;=a[n-1]中搜索x
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">//找到x时返回起在数组中的位置,则返回-1
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">int</span> <span class="n">left</span> <span class="o">=</span><span class="mi">0</span><span class="o">;</span><span class="kt">int</span> <span class="n">right</span><span class="o">=</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">while</span><span class="o">(</span><span class="n">left</span><span class="o">&lt;=</span><span class="n">right</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">middle</span><span class="o">=(</span><span class="n">left</span><span class="o">+</span><span class="n">right</span><span class="o">)/</span><span class="mi">2</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">x</span><span class="o">==</span><span class="n">a</span><span class="o">[</span><span class="n">middle</span><span class="o">])</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">middle</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">x</span><span class="o">&gt;</span><span class="n">a</span><span class="o">[</span><span class="n">middle</span><span class="o">])</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">left</span><span class="o">=</span><span class="n">middle</span><span class="o">+</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">right</span><span class="o">=</span><span class="n">middle</span><span class="o">-</span><span class="mi">1</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="o">-</span><span class="mi">1</span><span class="o">;</span><span class="c1">//未找到x
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div></li>
|
||
</ol>
|
||
<h5 id="棋盘覆盖">棋盘覆盖</h5>
|
||
<p>在一个$2^k\times2^k$ 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘,在该问题中要用4中种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任意2个L型骨牌不得重叠覆盖</p>
|
||
<p>利用分治法得出的简洁算法</p>
|
||
<p>当k&gt;0时,将$ 2^k\times 2^k $棋盘分割为4个$ 2^{k-1}\times 2^{k-1}$ 子棋盘,特殊方格必定位于4个较小子棋盘之一,其余3个子棋盘中无特殊方格。未来将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖着3个较小棋盘的会合处,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题,递归地使用这种分割,直至棋盘简化为1</p>
|
||
<div class="highlight"><div class="chroma">
|
||
<table class="lntable"><tr><td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||
</span><span class="lnt"> 2
|
||
</span><span class="lnt"> 3
|
||
</span><span class="lnt"> 4
|
||
</span><span class="lnt"> 5
|
||
</span><span class="lnt"> 6
|
||
</span><span class="lnt"> 7
|
||
</span><span class="lnt"> 8
|
||
</span><span class="lnt"> 9
|
||
</span><span class="lnt">10
|
||
</span><span class="lnt">11
|
||
</span><span class="lnt">12
|
||
</span><span class="lnt">13
|
||
</span><span class="lnt">14
|
||
</span><span class="lnt">15
|
||
</span><span class="lnt">16
|
||
</span><span class="lnt">17
|
||
</span><span class="lnt">18
|
||
</span><span class="lnt">19
|
||
</span><span class="lnt">20
|
||
</span><span class="lnt">21
|
||
</span><span class="lnt">22
|
||
</span><span class="lnt">23
|
||
</span><span class="lnt">24
|
||
</span><span class="lnt">25
|
||
</span><span class="lnt">26
|
||
</span><span class="lnt">27
|
||
</span><span class="lnt">28
|
||
</span><span class="lnt">29
|
||
</span><span class="lnt">30
|
||
</span><span class="lnt">31
|
||
</span><span class="lnt">32
|
||
</span><span class="lnt">33
|
||
</span><span class="lnt">34
|
||
</span><span class="lnt">35
|
||
</span><span class="lnt">36
|
||
</span><span class="lnt">37
|
||
</span><span class="lnt">38
|
||
</span><span class="lnt">39
|
||
</span><span class="lnt">40
|
||
</span><span class="lnt">41
|
||
</span><span class="lnt">42
|
||
</span><span class="lnt">43
|
||
</span><span class="lnt">44
|
||
</span><span class="lnt">45
|
||
</span><span class="lnt">46
|
||
</span><span class="lnt">47
|
||
</span><span class="lnt">48
|
||
</span><span class="lnt">49
|
||
</span><span class="lnt">50
|
||
</span><span class="lnt">51
|
||
</span><span class="lnt">52
|
||
</span><span class="lnt">53
|
||
</span><span class="lnt">54
|
||
</span><span class="lnt">55
|
||
</span><span class="lnt">56
|
||
</span><span class="lnt">57
|
||
</span></code></pre></td>
|
||
<td class="lntd">
|
||
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Divide_and_conquer</span> <span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">chessBoard</span><span class="o">(</span><span class="kt">int</span> <span class="n">tr</span><span class="o">,</span><span class="kt">int</span> <span class="n">tc</span><span class="o">,</span><span class="kt">int</span> <span class="n">dr</span><span class="o">,</span><span class="kt">int</span> <span class="n">dc</span><span class="o">,</span><span class="kt">int</span> <span class="n">size</span><span class="o">){</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">tile</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">board</span><span class="o">[][]=</span><span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="mi">6</span><span class="o">][</span><span class="mi">6</span><span class="o">];</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="o">(</span><span class="n">size</span><span class="o">==</span><span class="mi">1</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="o">;</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">t</span><span class="o">=</span><span class="n">tile</span><span class="o">++,</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">s</span><span class="o">=</span><span class="n">size</span><span class="o">/</span><span class="mi">2</span><span class="o">;</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="c1"></span> <span class="k">if</span><span class="o">(</span><span class="n">dr</span><span class="o">&lt;</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">&amp;&amp;</span><span class="n">dc</span><span class="o">&lt;</span><span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">,</span> <span class="n">tc</span><span class="o">,</span> <span class="n">dr</span><span class="o">,</span> <span class="n">dc</span><span class="o">,</span> <span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="o">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="c1">//用t号L型骨牌覆盖右下角
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">board</span><span class="o">[</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">][</span><span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">]=</span><span class="n">t</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="c1"></span> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">,</span><span class="n">tc</span><span class="o">,</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span><span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span><span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="c1"></span> <span class="k">if</span><span class="o">(</span><span class="n">dr</span><span class="o">&lt;</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">&amp;&amp;</span><span class="n">dc</span><span class="o">&gt;=</span><span class="n">tc</span><span class="o">+</span><span class="n">s</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="c1"></span> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">,</span> <span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">dr</span><span class="o">,</span> <span class="n">dc</span><span class="o">,</span> <span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</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="c1"></span> <span class="c1">//用t号L型骨牌覆盖左下角
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">board</span><span class="o">[</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">][</span><span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">]=</span><span class="n">t</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="c1"></span> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">,</span> <span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span> <span class="n">tc</span><span class="o">,</span> <span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="c1"></span> <span class="k">if</span><span class="o">(</span><span class="n">dr</span><span class="o">&gt;=</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">&amp;&amp;</span><span class="n">dc</span><span class="o">&lt;</span><span class="n">tc</span><span class="o">+</span><span class="n">s</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="c1"></span> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tc</span><span class="o">,</span> <span class="n">dr</span><span class="o">,</span> <span class="n">dc</span><span class="o">,</span> <span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</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="c1"></span> <span class="c1">//用t号L型骨牌覆盖右下角
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">board</span><span class="o">[</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">][</span><span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">]=</span><span class="n">t</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="c1"></span> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tc</span><span class="o">,</span> <span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span> <span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</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="c1"></span> <span class="k">if</span><span class="o">(</span><span class="n">dr</span><span class="o">&gt;=</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">&amp;&amp;</span><span class="n">dc</span><span class="o">&gt;=</span><span class="n">tc</span><span class="o">+</span><span class="n">s</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="c1"></span> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">dr</span><span class="o">,</span> <span class="n">dc</span><span class="o">,</span> <span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="k">else</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="c1"></span> <span class="c1">//用t号L型骨牌覆盖左下角
|
||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">board</span><span class="o">[</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">][</span><span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">]=</span><span class="n">t</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="c1"></span> <span class="n">chessBoard</span><span class="o">(</span><span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tr</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">tc</span><span class="o">+</span><span class="n">s</span><span class="o">,</span> <span class="n">s</span><span class="o">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="o">}</span>
|
||
</span></span></code></pre></td></tr></table>
|
||
</div>
|
||
</div></description>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<category domain="http://www.inksoul.top/algorithm/">algorithm\</category>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</item>
|
||
|
||
</channel>
|
||
</rss>
|