-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
429 lines (205 loc) · 295 KB
/
local-search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>ViTwo - 在线视频同步插件</title>
<link href="/post/58452aca/"/>
<url>/post/58452aca/</url>
<content type="html"><![CDATA[<p>因为最近因为和朋友一起联机看视频发现很难一起暂停快进,就在网上找了同步视频的插件。结果发现现在的要么是不能用视频播放器的原生控制键,要么就是不能再盗版网站上使用💦想了想感觉应该也不难实现,所以写了一个 chrome 的插件。因为不想交5美金注册费所以没上架 chrome extension store。不过我放在了 Github 上,可以在这里下载:<a href="https://github.com/Trotyl15/ViTwo">https://github.com/Trotyl15/ViTwo</a> 。基本可以支持80%的正盗版视频网站(?)</p><p>那些用别的源的有iframe的网站因为chrome有cors限制所以不行,可能可以试试cors bypass插件不过我还没试过。如果自己手动inspect一下网页进去找到视频的源网站打开的话倒是也一样,觉得有用的米娜github点个小星星捏。</p><p>插件长这样👇懒得硬凹样式了不过图标和背景都是我画的(`ヮ´ )</p><p><img src="https://github.com/user-attachments/assets/62913c9c-e522-4e4e-8d51-9330d0d21f1b" srcset="/img/loading.gif" lazyload alt=""></p>]]></content>
<categories>
<category>试验场</category>
</categories>
<tags>
<tag>chrome extension</tag>
</tags>
</entry>
<entry>
<title>Deploying Hexo Anywhere using Github Action</title>
<link href="/post/a664806d/"/>
<url>/post/a664806d/</url>
<content type="html"><![CDATA[<p>According to <a href="https://docs.github.com/en/actions">Github Action’s documentation</a>, this is a tool that helps you to:</p><blockquote><p>Automate, customize, and execute your software development workflows right in your repository with GitHub Actions. You can discover, create, and share actions to perform any job you’d like, including CI/CD, and combine actions in a completely customized workflow.</p></blockquote><p><strong>TL;DR</strong>: CI/CD platform that automates your build, test, and deployment pipeline.</p><p>After getting github action integrated, you no longer need to use any hexo/npm related commands when you deploy. It simplifies the process to just pushing changes to a private repository.</p><p>In the following guide, I would assume you already have your Hexo blog’s generated static files in a github repo.</p><h1 id="Here’s-what-you-need-to-do"><a href="#Here’s-what-you-need-to-do" class="headerlink" title="Here’s what you need to do"></a>Here’s what you need to do</h1><h2 id="Initializing-Repository"><a href="#Initializing-Repository" class="headerlink" title="Initializing Repository"></a>Initializing Repository</h2><p>Initialize a <strong>private</strong> <span class="heimu" title="你知道的太多了">Important! There are sensitive files!</span> repository on GitHub that will store all the files in your blog’s root directory. Call it whatever you want, I’m using <code>blog-backup</code>. </p><h2 id="Add-SSH-Key"><a href="#Add-SSH-Key" class="headerlink" title="Add SSH Key"></a>Add SSH Key</h2><ol><li>On your computer, open up git bash and use this command <figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">ssh-keygen -f github-deploy-key</span><br></code></pre></td></tr></table></figure> enter until you see the key’s randomart image.</li><li><p>Go to the directory which you used git bashed at and find these two files:<code>github-deploy-key</code> and <code>github-deploy-key.pub</code></p><p> The first one is the private key and second one is the public key. Keep them safe and don’t send them to anyone or accidentally push them to github…</p></li><li><p>Head to your root file repository and go to <code>Settings</code> -> <code>Secrets</code> -> <code>New repository secret</code>. </p><p> Use <code>HEXO_DEPLOY_PRI</code> for the name and paste the contents in your <code>github-deploy-key</code> for value and click <code>Add Secret</code>.</p></li><li><p>Head to your original Hexo blog’s repository (The generated static files), and go to <code>Settings</code> -> <code>Deploy keys</code> -> <code>Add deploy key</code>.</p><p> Paste the contents in your <code>github-deploy-key.pub</code> file into the key, set the title to <code>HEXO_DEPLOY_PUB</code>, and select the checkbox <code>Allow write access</code>.</p></li></ol><h2 id="Create-config-file"><a href="#Create-config-file" class="headerlink" title="Create config file"></a>Create config file</h2><ol><li>Create a new directory under your root folder <code>.github/workflows/deploy.yml</code></li><li><p>Confilg the yaml file</p><p> Here’s mine: <strong>(Remember to change the <code>env</code> variables and time zone under <code>Configuration environment</code>)</strong></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># Action name</span><br><span class="hljs-attr">name:</span> <span class="hljs-string">Hexo</span> <span class="hljs-string">Auto</span> <span class="hljs-string">Deploy</span><br><br><span class="hljs-attr">on:</span><br> <span class="hljs-comment"># Trigger condition 1: main branch receives a push </span><br> <span class="hljs-attr">push:</span><br> <span class="hljs-attr">branches:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-string">main</span><br> <span class="hljs-comment"># Trigger condition 2: Run workflow button manually pressed</span><br> <span class="hljs-attr">workflow_dispatch:</span><br><br><span class="hljs-comment"># change this enviroenment varibles to your own</span><br><span class="hljs-attr">env:</span><br> <span class="hljs-attr">GIT_USER:</span> <span class="hljs-string">GitUserId</span><br> <span class="hljs-attr">GIT_EMAIL:</span> <span class="hljs-string">[email protected]</span><br> <span class="hljs-comment"># Deploy to this repo after generated</span><br> <span class="hljs-attr">GIT_DEPLOY_REPO:</span> <span class="hljs-string">GitUser/My-Blog</span><br> <span class="hljs-comment"># Deploy to this branch after generated</span><br> <span class="hljs-attr">GIT_DEPLOY_BRANCH:</span> <span class="hljs-string">master</span><br> <span class="hljs-comment"># Hexo's source repo (the public one)</span><br> <span class="hljs-attr">GIT_SOURCE_REPO:</span> <span class="hljs-string">[email protected]:GitUser/My-Blog.git</span><br><br><br><span class="hljs-attr">jobs:</span><br> <span class="hljs-attr">build:</span><br> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">on</span> <span class="hljs-string">node</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.node_version</span> <span class="hljs-string">}}</span> <span class="hljs-string">and</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.os</span> <span class="hljs-string">}}</span><br> <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span><br> <span class="hljs-attr">if:</span> <span class="hljs-string">github.event.repository.owner.id</span> <span class="hljs-string">==</span> <span class="hljs-string">github.event.sender.id</span><br> <span class="hljs-attr">strategy:</span><br> <span class="hljs-attr">matrix:</span><br> <span class="hljs-attr">os:</span> [<span class="hljs-string">ubuntu-18.04</span>]<br> <span class="hljs-attr">node_version:</span> [<span class="hljs-number">12.</span><span class="hljs-string">x</span>]<br><br> <span class="hljs-attr">steps:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span><br> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v2</span><br><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">deploy</span> <span class="hljs-string">repo</span><br> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v2</span><br> <span class="hljs-attr">with:</span><br> <span class="hljs-attr">repository:</span> <span class="hljs-string">${{</span> <span class="hljs-string">env.GIT_DEPLOY_REPO</span> <span class="hljs-string">}}</span><br> <span class="hljs-attr">ref:</span> <span class="hljs-string">${{</span> <span class="hljs-string">env.GIT_DEPLOY_BRANCH</span> <span class="hljs-string">}}</span><br> <span class="hljs-attr">path:</span> <span class="hljs-string">.deploy_git</span><br><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Use</span> <span class="hljs-string">Node.js</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.node_version</span> <span class="hljs-string">}}</span><br> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/setup-node@v1</span><br> <span class="hljs-attr">with:</span><br> <span class="hljs-attr">node-version:</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.node_version</span> <span class="hljs-string">}}</span><br><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Configuration</span> <span class="hljs-string">environment</span><br> <span class="hljs-attr">env:</span><br> <span class="hljs-attr">HEXO_DEPLOY_PRI:</span> <span class="hljs-string">${{secrets.HEXO_DEPLOY_PRI}}</span><br> <span class="hljs-attr">run:</span> <span class="hljs-string">|</span> <span class="hljs-comment"># Make sure you change the timezone</span><br> <span class="hljs-string">sudo</span> <span class="hljs-string">timedatectl</span> <span class="hljs-string">set-timezone</span> <span class="hljs-string">"Continent/City"</span><br> <span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">~/.ssh/</span><br> <span class="hljs-string">echo</span> <span class="hljs-string">"$HEXO_DEPLOY_PRI"</span> <span class="hljs-string">></span> <span class="hljs-string">~/.ssh/id_rsa</span><br> <span class="hljs-string">chmod</span> <span class="hljs-number">600</span> <span class="hljs-string">~/.ssh/id_rsa</span><br> <span class="hljs-string">ssh-keyscan</span> <span class="hljs-string">-t</span> <span class="hljs-string">rsa</span> <span class="hljs-string">github.com</span> <span class="hljs-string">>></span> <span class="hljs-string">~/.ssh/known_hosts</span><br> <span class="hljs-string">ssh-keyscan</span> <span class="hljs-string">-t</span> <span class="hljs-string">rsa</span> <span class="hljs-string">e.coding.net</span> <span class="hljs-string">>></span> <span class="hljs-string">~/.ssh/known_hosts</span><br> <span class="hljs-string">ssh-keyscan</span> <span class="hljs-string">-t</span> <span class="hljs-string">rsa</span> <span class="hljs-string">gitee.com</span> <span class="hljs-string">>></span> <span class="hljs-string">~/.ssh/known_hosts</span><br> <span class="hljs-string">git</span> <span class="hljs-string">config</span> <span class="hljs-string">--global</span> <span class="hljs-string">user.name</span> <span class="hljs-string">$GIT_USER</span><br> <span class="hljs-string">git</span> <span class="hljs-string">config</span> <span class="hljs-string">--global</span> <span class="hljs-string">user.email</span> <span class="hljs-string">$GIT_EMAIL</span><br><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Hexo</span> <span class="hljs-comment"># Install Hexo</span><br> <span class="hljs-attr">run:</span> <span class="hljs-string">|</span><br> <span class="hljs-string">npm</span> <span class="hljs-string">install</span> <span class="hljs-string">hexo-cli</span> <span class="hljs-string">-g</span><br><br> <br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Cache</span> <span class="hljs-string">Modules</span> <span class="hljs-comment"># Cache Hexo extensions</span><br> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/cache@v1</span><br> <span class="hljs-attr">id:</span> <span class="hljs-string">cache-modules</span><br> <span class="hljs-attr">with:</span><br> <span class="hljs-attr">path:</span> <span class="hljs-string">node_modules</span><br> <span class="hljs-attr">key:</span> <span class="hljs-string">${{runner.OS}}-${{hashFiles('**/package-lock.json')}}</span><br><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Dependencies</span> <span class="hljs-comment"># Runs if the extension is not cached, or new extensions added</span><br> <span class="hljs-attr">if:</span> <span class="hljs-string">steps.cache-modules.outputs.cache-hit</span> <span class="hljs-type">!=</span> <span class="hljs-string">'true'</span><br> <span class="hljs-attr">run:</span> <span class="hljs-string">|</span> <span class="hljs-comment"># Please make sure you have package-lock.json in your root repo (this one)</span><br> <span class="hljs-string">npm</span> <span class="hljs-string">ci</span><br><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Generate</span><br> <span class="hljs-attr">run:</span> <span class="hljs-string">|</span><br> <span class="hljs-string">hexo</span> <span class="hljs-string">clean</span><br> <span class="hljs-string">hexo</span> <span class="hljs-string">generate</span><br> <br> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span><br> <span class="hljs-attr">run:</span> <span class="hljs-string">|</span><br> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">deploy</span><br></code></pre></td></tr></table></figure></li></ol><h2 id="Push-Codes"><a href="#Push-Codes" class="headerlink" title="Push Codes"></a>Push Codes</h2><p>The finial step is just to push everything you have from you root directory to your private repo, and remember to check if the workflow ran successfully on the Github Actions page.</p><hr><p><img src="https://media.tenor.com/DN4JBeneqdkAAAAd/congratulations-evangelion.gif" srcset="/img/loading.gif" lazyload width="250"/></p><p>Congrats! Now you can edit you blog anywhere <del>and have something to do when you’re slacking off at work</del> . <span class="heimu" title="你知道的太多了">pls.. hr, don’t see this.</span></p><p>Feel free to leave a comment below for any questions and suggestions you have.</p>]]></content>
<tags>
<tag>Hexo</tag>
<tag>Github Action</tag>
</tags>
</entry>
<entry>
<title>基于 Mapbox 实现 PyQt5上的离线地图</title>
<link href="/post/b65dbbb5/"/>
<url>/post/b65dbbb5/</url>
<content type="html"><![CDATA[<p>懒得看的话可以直接 clone 我的 repo:<a href="https://github.com/Trotyl15/Offline-Mapbox-in-PyQt5">Offline-Mapbox-in-PyQt5</a> <del>记得给个小星星🧐</del></p><p><span class="heimu" title="你知道的太多了">到底是谁先流行的 Folium??一点也不好用!😭</span></p><p>我一共试了 Folium, Google Map 和 Mapbox,Folium 不能动态更新 marker,Google Map 不能离线,只有 Mapbox 还行。。还没试 Leaflet,谁有空谁试吧😇(记得告诉我可不可以)</p><h2 id="获取-Maptile"><a href="#获取-Maptile" class="headerlink" title="获取 Maptile"></a>获取 Maptile</h2><p>我用的是 <a href="https://www.openstreetmap.org/">OpenStreetMap</a> 和 <a href="http://maperitive.net/">Maperitive</a></p><ol><li>用 OpenStreetMap 获取需要地图的<code>.osm</code>文件</li><li>用 Maperitive 把<code>.osm</code>转换成<code>.png</code></li></ol><h2 id="Web-部分"><a href="#Web-部分" class="headerlink" title="Web 部分"></a>Web 部分</h2><p>创建一个 html,可以叫<code>map.html</code></p><h3 id="获取需要的文件"><a href="#获取需要的文件" class="headerlink" title="获取需要的文件"></a>获取需要的文件</h3><ol><li>建议自己注册一个 mapbox 账户,输入 token 然后按照步骤嵌入地图到 html</li><li>用浏览器打开 html 后打开 Developer Tool,在 source 里找到需要的js, css文件和其他文件(如sprite等)下载下来</li><li>html 里引入需要文件,如<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'./api/assets/mapbox-gl.js'</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br><span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">'./api/assets/mapbox-gl.css'</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">'stylesheet'</span>/></span><br><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"jquery-3.6.4.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br></code></pre></td></tr></table></figure> 我写一个字符的 JavaScript 就想用 jQuery, 所以我这里也引入了 jQuery</li></ol><h3 id="Host-Files-on-Local-Server"><a href="#Host-Files-on-Local-Server" class="headerlink" title="Host Files on Local Server"></a>Host Files on Local Server</h3><p>把文件放进对应路径后写一个<code>server.py</code>用来 host 文件<br><figure class="highlight xl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs xl"><span class="hljs-keyword">import</span> http.server<br><span class="hljs-keyword">import</span> socketserver<br><br>PORT = <span class="hljs-number">8888</span><br><br>Handler = http.server.SimpleHTTPRequestHandler<br><br><span class="hljs-keyword">with</span> socketserver.TCPServer((<span class="hljs-string">""</span>, PORT), Handler) <span class="hljs-keyword">as</span> httpd:<br> httpd.serve_forever()<br></code></pre></td></tr></table></figure></p><h3 id="Setup-Config"><a href="#Setup-Config" class="headerlink" title="Setup Config"></a>Setup Config</h3><p>在 html 里按自己要求设置一下 Mapbox 的参数,比如我是这样的<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><br><span class="javascript"><span class="hljs-keyword">var</span> map = <span class="hljs-keyword">new</span> mapboxgl.Map({</span><br><span class="javascript"> container: <span class="hljs-string">'map'</span>,</span><br> style: {<br><span class="javascript"> <span class="hljs-string">"version"</span>: <span class="hljs-number">8</span>,</span><br><span class="javascript"> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Mapbox Streets"</span>,</span><br><span class="javascript"> <span class="hljs-string">"sprite"</span>: <span class="hljs-string">"http://localhost:8888/mapbox_build/sprite/sprite"</span>,</span><br><span class="javascript"> <span class="hljs-comment">// "glyphs": "http://localhost:8888/mapbox_build/fonts/{fontstack}/{range}.pbf",</span></span><br><span class="javascript"> <span class="hljs-string">"sources"</span>: {</span><br><span class="javascript"> <span class="hljs-string">"osm-tiles"</span>: {</span><br><span class="javascript"> <span class="hljs-string">"type"</span>: <span class="hljs-string">"raster"</span>,</span><br><span class="javascript"> <span class="hljs-string">'tiles'</span>: [</span><br><span class="javascript"> <span class="hljs-string">"http://localhost:8888/tiles/{z}/{x}/{y}.png"</span></span><br> ],<br><br> }<br> },<br><span class="javascript"> <span class="hljs-string">"layers"</span>: [{</span><br><span class="javascript"> <span class="hljs-string">"id"</span>: <span class="hljs-string">"123"</span>,</span><br><span class="javascript"> <span class="hljs-string">"type"</span>: <span class="hljs-string">"raster"</span>,</span><br><span class="javascript"> <span class="hljs-string">"source"</span>: <span class="hljs-string">"osm-tiles"</span>,</span><br><span class="javascript"> <span class="hljs-string">"source-layer"</span>: <span class="hljs-string">"osmtiles"</span></span><br> }]<br> },<br> center: [-71.6516848, 48.5107057],<br> zoom: 15<br> });<br><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br></code></pre></td></tr></table></figure><br>现在这里所有东西都是本地文件,已经可以离线用了</p><h2 id="嵌入-PyQt5"><a href="#嵌入-PyQt5" class="headerlink" title="嵌入 PyQt5"></a>嵌入 PyQt5</h2><p>用 PyQt 的 webengin 嵌入 html,新建<code>.py</code>文件<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> sys<br><span class="hljs-keyword">from</span> PyQt5.QtWidgets <span class="hljs-keyword">import</span> QApplication, QWidget, QHBoxLayout, QVBoxLayout<br><span class="hljs-keyword">from</span> PyQt5.QtWebEngineWidgets <span class="hljs-keyword">import</span> QWebEngineView <span class="hljs-comment"># pip install PyQtWebEngine</span><br><span class="hljs-keyword">from</span> PyQt5 <span class="hljs-keyword">import</span> QtCore<br><span class="hljs-keyword">from</span> PyQt5.QtCore <span class="hljs-keyword">import</span> *<br><br><br><span class="hljs-string">"""</span><br><span class="hljs-string">Mapbox in PyQt5</span><br><span class="hljs-string">"""</span><br><br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyApp</span>(<span class="hljs-params">QWidget</span>):</span><br> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span><br> <span class="hljs-built_in">super</span>().__init__()<br> self.setWindowTitle(<span class="hljs-string">'Mapbox in PyQt Example'</span>)<br> self.window_width, self.window_height = <span class="hljs-number">600</span>, <span class="hljs-number">400</span><br> self.setMinimumSize(self.window_width, self.window_height)<br><br> layout = QVBoxLayout()<br> self.setLayout(layout)<br><br> webView = QWebEngineView()<br> webView.load(QUrl(<span class="hljs-string">'http://localhost:8888/map.html'</span>))<br> layout.addWidget(webView)<br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:<br> app = QApplication(sys.argv)<br> app.setStyleSheet(<span class="hljs-string">'''</span><br><span class="hljs-string"> QWidget {</span><br><span class="hljs-string"> font-size: 35px;</span><br><span class="hljs-string"> }</span><br><span class="hljs-string"> '''</span>)<br><br> myApp.show()<br><br> <span class="hljs-keyword">try</span>:<br> sys.exit(app.exec_())<br> <span class="hljs-keyword">except</span> SystemExit:<br> print(<span class="hljs-string">'Closing Window...'</span>)<br></code></pre></td></tr></table></figure></p><h2 id="Python-和-Html-的交互"><a href="#Python-和-Html-的交互" class="headerlink" title="Python 和 Html 的交互"></a>Python 和 Html 的交互</h2><p>因为我需要实时更改 mapbox marker 的位置,所以我用了一个 json 来存 coordinate 的参数</p><h3 id="json"><a href="#json" class="headerlink" title="json:"></a>json:</h3><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs json">{<span class="hljs-attr">"coordinate"</span>: [<span class="hljs-number">-71.65108479999981</span>, <span class="hljs-number">48.51130570000019</span>]}<br></code></pre></td></tr></table></figure><h3 id="js"><a href="#js" class="headerlink" title="js:"></a>js:</h3><figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs reasonml"><span class="hljs-keyword">let</span> marker = <span class="hljs-keyword">new</span> mapboxgl.<span class="hljs-constructor">Marker()</span>;<br><br>set<span class="hljs-constructor">Interval(<span class="hljs-params">function</span>()</span> { <br>$.get<span class="hljs-constructor">JSON(<span class="hljs-string">"map.json"</span>, <span class="hljs-params">function</span> (<span class="hljs-params">json</span>)</span> {<br>console.log(json);<br>marker.set<span class="hljs-constructor">LngLat(<span class="hljs-params">json</span>.<span class="hljs-params">coordinate</span>)</span>;<br>.add<span class="hljs-constructor">To(<span class="hljs-params">map</span>)</span>;<br>}); <br>},<span class="hljs-number">10</span>);<br></code></pre></td></tr></table></figure><h3 id="python"><a href="#python" class="headerlink" title="python:"></a>python:</h3><p>写入 json 的 function<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs sql">def reloadMap():<br> <span class="hljs-keyword">with</span> <span class="hljs-keyword">open</span>(<span class="hljs-string">"map.json"</span>, <span class="hljs-string">"r"</span>) <span class="hljs-keyword">as</span> jsonFile:<br> <span class="hljs-keyword">data</span> = json.load(jsonFile)<br><br> <span class="hljs-keyword">data</span>[<span class="hljs-string">"coordinate"</span>] = [<span class="hljs-keyword">data</span>[<span class="hljs-string">"coordinate"</span>][<span class="hljs-number">0</span>]+<span class="hljs-number">0.00001</span>,<span class="hljs-keyword">data</span>[<span class="hljs-string">"coordinate"</span>][<span class="hljs-number">1</span>]+<span class="hljs-number">0.00001</span>]<br> <br> <span class="hljs-keyword">with</span> <span class="hljs-keyword">open</span>(<span class="hljs-string">"map.json"</span>, <span class="hljs-string">"w"</span>) <span class="hljs-keyword">as</span> jsonFile:<br> json.dump(<span class="hljs-keyword">data</span>, jsonFile)<br></code></pre></td></tr></table></figure><br>用 PyQt 自带的 QTimer 在新的线程上重复调用<code>reloadMap()</code><br><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs jboss-cli">timer = QTimer<span class="hljs-params">()</span><br>timer.timeout.<span class="hljs-keyword">connect</span><span class="hljs-params">(reloadMap)</span> <span class="hljs-comment"># execute `reloadMap`</span><br>timer.<span class="hljs-keyword">set</span>Interval<span class="hljs-params">(50)</span> <span class="hljs-comment"># 1000ms = 1s</span><br>timer.start<span class="hljs-params">()</span><br></code></pre></td></tr></table></figure></p><h2 id="撒花"><a href="#撒花" class="headerlink" title="撒花"></a>撒花</h2><p>有问题的话欢迎评论呀!</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/emoji/rei.gif" srcset="/img/loading.gif" lazyload height="250"></p>]]></content>
<categories>
<category>试验场</category>
</categories>
<tags>
<tag>jQuery</tag>
<tag>Python</tag>
<tag>PyQt5</tag>
<tag>JavaScript</tag>
<tag>Mapbox</tag>
</tags>
</entry>
<entry>
<title>Flask 的常用模块和命令</title>
<link href="/post/36c70eb9/"/>
<url>/post/36c70eb9/</url>
<content type="html"><![CDATA[<p>本健忘症晚期患者自用</p><h1 id="模块"><a href="#模块" class="headerlink" title="模块"></a>模块</h1><h2 id="Basebones-App"><a href="#Basebones-App" class="headerlink" title="Basebones App"></a>Basebones App</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask<br>app = Flask(__name__)<br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/hello'</span></span>)</span><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello</span>():</span><br><span class="hljs-keyword">return</span> <span class="hljs-string">'Hello, World!'</span><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:<br>app.run(debug=<span class="hljs-literal">True</span>)<br></code></pre></td></tr></table></figure><h2 id="Routing"><a href="#Routing" class="headerlink" title="Routing"></a>Routing</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/hello/<string:name>, methods=['</span>GET<span class="hljs-string">', '</span>POST<span class="hljs-string">'])</span></span></span><br><span class="hljs-meta"><span class="hljs-params"><span class="hljs-string">def hello(name): </span></span></span><br><span class="hljs-meta"><span class="hljs-params"><span class="hljs-string">return '</span>Hello <span class="hljs-string">' + name + '</span>!<span class="hljs-string">' </span></span></span><br></code></pre></td></tr></table></figure><h2 id="Templates"><a href="#Templates" class="headerlink" title="Templates"></a>Templates</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">return</span> render_template(<span class="hljs-string">'template_file.html'</span>, val1 = value1, ...)<br></code></pre></td></tr></table></figure><h2 id="JSON-Responses"><a href="#JSON-Responses" class="headerlink" title="JSON Responses"></a>JSON Responses</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> jsonify<br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/returnstuff'</span></span>)</span><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">returnstuff</span>():</span><br>num_list = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>]<br>num_dict = {<span class="hljs-string">'numbers'</span> : num_list, <span class="hljs-string">'name'</span> : <span class="hljs-string">'Numbers'</span>}<br><span class="hljs-comment">#returns {'output' : {'numbers' : [1,2,3,4,5], 'name' : 'Numbers'}}</span><br><span class="hljs-keyword">return</span> jsonify({<span class="hljs-string">'output'</span> : num_dict})<br></code></pre></td></tr></table></figure><h2 id="Access-Request-Data"><a href="#Access-Request-Data" class="headerlink" title="Access Request Data"></a>Access Request Data</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python">request.args[<span class="hljs-string">'name'</span>] <span class="hljs-comment">#query string arguments</span><br>request.form[<span class="hljs-string">'name'</span>] <span class="hljs-comment">#form data</span><br>request.method <span class="hljs-comment">#request type</span><br>request.cookies.get(<span class="hljs-string">'cookie_name'</span>) <span class="hljs-comment">#cookies</span><br>request.files[<span class="hljs-string">'name'</span>] <span class="hljs-comment">#files</span><br></code></pre></td></tr></table></figure><h2 id="Redirect"><a href="#Redirect" class="headerlink" title="Redirect"></a>Redirect</h2><figure class="highlight isbl"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs isbl"><span class="hljs-variable">return</span> <span class="hljs-function"><span class="hljs-title">redirect</span>(<span class="hljs-title">url_for</span>(<span class="hljs-string">'index'</span>))</span><br></code></pre></td></tr></table></figure><h1 id="命令"><a href="#命令" class="headerlink" title="命令"></a>命令</h1><h2 id="Create-virtual-environment-locally"><a href="#Create-virtual-environment-locally" class="headerlink" title="Create virtual environment locally"></a>Create virtual environment locally</h2><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dockerfile">virtualenv <span class="hljs-keyword">env</span><br></code></pre></td></tr></table></figure><h2 id="Activate-virtual-environment"><a href="#Activate-virtual-environment" class="headerlink" title="Activate virtual environment"></a>Activate virtual environment</h2><figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs gradle"><span class="hljs-keyword">source</span> env<span class="hljs-regexp">/Scripts/</span>activate<br></code></pre></td></tr></table></figure><h2 id="Create-database"><a href="#Create-database" class="headerlink" title="Create database"></a>Create database</h2><figure class="highlight python-repl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python-repl">$ python<br><span class="hljs-meta">>>></span> <span class="python"><span class="hljs-keyword">from</span> app <span class="hljs-keyword">import</span> db</span><br><span class="hljs-meta">>>></span> <span class="python">db.create_all()</span><br></code></pre></td></tr></table></figure><h1 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h1><p>用的 Heroku</p><h2 id="Freeze-requirements"><a href="#Freeze-requirements" class="headerlink" title="Freeze requirements"></a>Freeze requirements</h2><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">pip <span class="hljs-keyword">freeze</span> > requirements.txt<br></code></pre></td></tr></table></figure><h2 id="Procile"><a href="#Procile" class="headerlink" title="Procile"></a>Procile</h2><figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs groovy"><span class="hljs-attr">web:</span> gunicorn <span class="hljs-attr">app:</span>app<br></code></pre></td></tr></table></figure><h2 id="Get-postgresql"><a href="#Get-postgresql" class="headerlink" title="Get postgresql"></a>Get postgresql</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-tag">heroku</span> <span class="hljs-selector-tag">addons</span><span class="hljs-selector-pseudo">:create</span> <span class="hljs-selector-tag">heroku-postgresql</span><span class="hljs-selector-pseudo">:hobby-dev</span> <span class="hljs-selector-tag">--app</span> <span class="hljs-selector-attr">[appname]</span><br></code></pre></td></tr></table></figure><h2 id="Get-datatbase-url"><a href="#Get-datatbase-url" class="headerlink" title="Get datatbase url"></a>Get datatbase url</h2><figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ada">heroku conig <span class="hljs-comment">--app [appname] </span><br></code></pre></td></tr></table></figure><p><strong>Remember to change <code>postgres://...</code> to <code>postgresql://...</code></strong></p>]]></content>
<tags>
<tag>python</tag>
<tag>flask</tag>
<tag>heroku</tag>
</tags>
</entry>
<entry>
<title>MySQL 数据库和 SQL 的学习笔记</title>
<link href="/post/4d712855/"/>
<url>/post/4d712855/</url>
<content type="html"><![CDATA[<p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/05BF466E1360CC64351C9467ADBB0960.jpg" srcset="/img/loading.gif" lazyloadwidth = "300px"/></p><h1 id="SQL-的四种分类"><a href="#SQL-的四种分类" class="headerlink" title="SQL 的四种分类"></a>SQL 的四种分类</h1><ul><li>DDL (Data Definition Language): 操作数据库</li><li>DML (Data Manipulation Language): 操作数据库中表的数据</li><li>DQL (Data Query Language): 查询数据库中表的数据</li><li>DCL (Data Control Language): 数据库的权限控制</li></ul><h1 id="DDL"><a href="#DDL" class="headerlink" title="DDL"></a>DDL</h1><h2 id="操作数据库"><a href="#操作数据库" class="headerlink" title="操作数据库"></a>操作数据库</h2><ol><li><p>创建</p><ul><li><p>创建数据库:<code>CREATE DATEBASE;</code></p></li><li><p>创建数据库(判断,如果不存在则创建):<code>CREATE DATABASE IF NOT EXISTS 数据库名称;</code></p></li></ul></li><li><p>查询:<code>SHOW DATABASES;</code></p></li><li><p>使用数据库</p><ul><li><p>查看当前使用的数据库:<code>SELECT DATABASE();</code></p></li><li><p>使用数据库:<code>USE 数据库名称;</code></p></li></ul></li><li><p>删除</p><ul><li>删除数据库:<code>DROP DATABASE 数据库名称;</code></li><li>删除数据库:<code>DROP DATABASE IF EXISTS 数据库名称;</code></li></ul></li></ol><h2 id="操作表-(CRUD)"><a href="#操作表-(CRUD)" class="headerlink" title="操作表 (CRUD)"></a>操作表 (CRUD)</h2><h3 id="创建(Create)"><a href="#创建(Create)" class="headerlink" title="创建(Create)"></a>创建(Create)</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> table_name (<br> column1 datatype,<br> column2 datatype,<br> column3 datatype,<br> ...<br> columnn datatype<br>);<br></code></pre></td></tr></table></figure><p>Example:</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> tb_user(<br> <span class="hljs-keyword">id</span> <span class="hljs-built_in">int</span>,<br> username <span class="hljs-built_in">varchar</span>(<span class="hljs-number">20</span>), <span class="hljs-comment">#最高20位的用户名</span><br> <span class="hljs-keyword">password</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-number">32</span>)<br>);<br></code></pre></td></tr></table></figure><h3 id="查询(Retrieve"><a href="#查询(Retrieve" class="headerlink" title="查询(Retrieve)"></a>查询(Retrieve)</h3><ul><li><p>查询当前数据库下所有表名称:<code>SHOW TABLES;</code></p></li><li><p>查询表结构:<code>DESC 表名称;</code></p><p>Example Output:</p><figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc">mysql> desc tb<span class="hljs-emphasis">_user;</span><br><span class="hljs-emphasis">+----------+-------------+------+-----+---------+-------+</span><br><span class="hljs-emphasis">| Field | Type | Null | Key | Default | Extra |</span><br><span class="hljs-emphasis">+----------+-------------+------+-----+---------+-------+</span><br><span class="hljs-emphasis">| id | int(11) | YES | | NULL | |</span><br><span class="hljs-emphasis">| username | varchar(20) | YES | | NULL | |</span><br><span class="hljs-emphasis">| password | varchar(32) | YES | | NULL | |</span><br><span class="hljs-emphasis">+----------+-------------+------+-----+---------+-------+</span><br><span class="hljs-emphasis">3 rows in set (0.00 sec)</span><br></code></pre></td></tr></table></figure></li></ul><h3 id="修改(Update)"><a href="#修改(Update)" class="headerlink" title="修改(Update)"></a>修改(Update)</h3><ol><li>修改表名:<code>ALTER TABLE 表名 RENAME TO 新的表名;</code></li><li>添加一行:<code>ALTER TABLE 表名 ADD 列名 数据类型;</code></li><li>修改数据类型:<code>ALTER TABLE 表名 MODIFY 列名 新数据格式;</code> </li><li>修改列名和数据类型:<code>ALTER TABLE 表名 CHANGE 列名 新列名 新数据格式;</code></li><li>删除列:<code>ALTER TABLE 表名 DROP 列名;</code></li></ol><h3 id="删除(Delete)"><a href="#删除(Delete)" class="headerlink" title="删除(Delete)"></a>删除(Delete)</h3><ol><li>删除表:<code>DROP TABLE 表名;</code></li><li>删除表时判断表是否存在: <code>DROP TABLE IF EXISTS 表名;</code></li></ol><h1 id="DML"><a href="#DML" class="headerlink" title="DML"></a>DML</h1><h2 id="添加(Insert)"><a href="#添加(Insert)" class="headerlink" title="添加(Insert)"></a>添加(Insert)</h2><ol><li>给指定列添加数据:<code>INSERT INTO 表名(列名1,列名,...) VALUES(制1,值2,...);</code></li><li>给全部列添加数据:<code>INSERT INTO表名 VALUES(值1,值2,...);</code></li><li>批量添加数据:<ul><li><code>INSERT INTO 表名(列名1,列名2,...) VALUES(值1,值2,...),(值1,值2,...),(值1,值2,...)...;</code></li><li><code>INSERT INTO 表名(值1,值2,...),(值1,值2,...),(值1,值2,...),...;</code></li></ul></li></ol><h2 id="修改(Update)-1"><a href="#修改(Update)-1" class="headerlink" title="修改(Update)"></a>修改(Update)</h2><ol><li>修改列表数据:<code>UPDATE 表名 SET 列名1=值1,列名2=制2,...[WHERE 条件];</code></li></ol><h2 id="删除(Delete)-1"><a href="#删除(Delete)-1" class="headerlink" title="删除(Delete)"></a>删除(Delete)</h2><ol><li>删除数据:<code>DELETE FROM 表名 [WHERE 条件]</code></li></ol><h1 id="DQL"><a href="#DQL" class="headerlink" title="DQL"></a>DQL</h1><h2 id="查询语法"><a href="#查询语法" class="headerlink" title="查询语法"></a>查询语法</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span><br>字段列表<br><span class="hljs-keyword">FROM</span><br>表名列表<br><span class="hljs-keyword">WHERE</span><br>条件列表<br><span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span><br>分组字段<br><span class="hljs-keyword">HAVING</span><br>分组后的条件<br><span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span><br>排序字段<br><span class="hljs-keyword">LIMIT</span><br>分页限定<br></code></pre></td></tr></table></figure><h2 id="基础查询"><a href="#基础查询" class="headerlink" title="基础查询"></a>基础查询</h2><ol><li><p>查询多个字段</p><p><code>SELECT 字段列表 FROM 表名;</code></p><p><code>SELECT * FROM 表名; -- 查询所有数据</code></p></li><li><p>去除重复记录</p><p>关键词:<code>DISTINCT</code></p><p>例:<code>select DISTINCT address from stu;</code></p></li><li><p>别名</p><p>关键词:<code>AS (也可以省略)</code></p><p>例:</p><p><code>select name AS 姓名 from stu;</code><br><code>select name 姓名 from stu;</code></p></li></ol><h2 id="条件查询(WHERE)"><a href="#条件查询(WHERE)" class="headerlink" title="条件查询(WHERE)"></a>条件查询(WHERE)</h2><p>The following operators can be used in the <code>WHERE</code> clause:</p><div class="table-container"><table><thead><tr><th>Operator</th><th>Description</th></tr></thead><tbody><tr><td>=</td><td>Equal</td></tr><tr><td>></td><td>Greater than</td></tr><tr><td><</td><td>Less than</td></tr><tr><td>>=</td><td>Greater than or equal</td></tr><tr><td><=</td><td>Less than or equal</td></tr><tr><td><> or !=</td><td>Not equal</td></tr><tr><td>BETWEEN … AND …</td><td>Between a certain range</td></tr><tr><td>LIKE …</td><td>Search for a pattern <code>_</code> represents a single random character <code>%</code> represents multiple random characters</td></tr><tr><td>IN(…)</td><td>To specify multiple possible values for a column</td></tr><tr><td>IS NULL</td><td>Is null</td></tr><tr><td>AND or &&</td><td>And</td></tr><tr><td>OR or \</td><td>Or</td></tr><tr><td>NOT or !</td><td>not</td></tr></tbody></table></div><h2 id="排序查询(ORDER-BY)"><a href="#排序查询(ORDER-BY)" class="headerlink" title="排序查询(ORDER BY)"></a>排序查询(ORDER BY)</h2><ol><li>排序查询语法:<code>SELECT FROM 字段列表 ORDER BY 排序字段名1 [排序方式1],排序字段名2 [排序方式2]...;</code></li></ol><p>排序方式:</p><ul><li>ASC:升序排列(默认)</li><li>DESC:降序排列</li></ul><h2 id="聚合函数"><a href="#聚合函数" class="headerlink" title="聚合函数"></a>聚合函数</h2><div class="table-container"><table><thead><tr><th>函数名</th><th>功能</th></tr></thead><tbody><tr><td>count(列名)</td><td>统计数量(一般选用不为null的列)</td></tr><tr><td>max(列名)</td><td>最大值</td></tr><tr><td>min(列名)</td><td>最小值</td></tr><tr><td>sum(列名)</td><td>求和</td></tr><tr><td>avg(列名)</td><td>平均值</td></tr></tbody></table></div><p>语法:<code>SELECT 聚合函数名(列名) FROM 表;</code></p><h2 id="分组查询(GROUP-BY)"><a href="#分组查询(GROUP-BY)" class="headerlink" title="分组查询(GROUP BY)"></a>分组查询(GROUP BY)</h2><ol><li>分组查询语法:<code>SELECT 字段列表 FROM 表名 [WHERE 分组前条件限定] GROUP BY 分组字段名 [HAVING 分组后条件过滤];</code></li></ol><h2 id="分页查询(LIMIT)"><a href="#分页查询(LIMIT)" class="headerlink" title="分页查询(LIMIT)"></a>分页查询(LIMIT)</h2><ol><li>分页查询语法:<code>SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询条目组;</code></li></ol><p>起始索引 = (当前页面 - 1)* 每页条数 </p><h1 id="约束(Constraints)"><a href="#约束(Constraints)" class="headerlink" title="约束(Constraints)"></a>约束(Constraints)</h1><ul><li><code>NOT NULL</code> - Ensures that a column cannot have a NULL value</li><li><code>UNIQUE</code> - Ensures that all values in a column are different</li><li><code>PRIMARY KEY</code> - A combination of a <code>NOT NULL</code> and <code>UNIQUE</code>. Uniquely identifies each row in a table</li><li><code>FOREIGN KEY</code> - Prevents actions that would destroy links between tables</li><li><code>CHECK</code> - Ensures that the values in a column satisfies a specific condition</li><li><code>DEFAULT</code> - Sets a default value for a column if no value is specified</li><li><code>CREATE INDEX</code> - Used to create and retrieve data from the database very quickly</li></ul><h2 id="外键约束"><a href="#外键约束" class="headerlink" title="外键约束"></a>外键约束</h2><ol><li>添加外键约束</li></ol><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-comment">-- 创建表时添加外键约束</span><br><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> 表名(<br> 列名 数据类型,<br> …<br> [<span class="hljs-keyword">CONSTRAINT</span>] [外键名称] <span class="hljs-keyword">FOREIGN</span> <span class="hljs-keyword">KEY</span>(外键列名) <span class="hljs-keyword">REFERENCES</span> 主表(主表列名)<br>);<br></code></pre></td></tr></table></figure><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-comment">-- 建完表后添加外键约束</span><br><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> 表名 <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">CONSTRAINT</span> 外键名称 <span class="hljs-keyword">FOREIGN</span> <span class="hljs-keyword">KEY</span> (外键字段名称) <span class="hljs-keyword">REFERENCES</span> 主表名称(主表列名称);<br></code></pre></td></tr></table></figure><ol><li>删除外键约束</li></ol><figure class="highlight sas"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sas"><span class="hljs-meta">ALTER</span> <span class="hljs-meta">TABLE</span> 表名 <span class="hljs-meta">DROP</span> <span class="hljs-meta">FOREIGN</span> <span class="hljs-meta">KEY</span> 外键名称<br></code></pre></td></tr></table></figure><h1 id="多表查询"><a href="#多表查询" class="headerlink" title="多表查询"></a>多表查询</h1><h2 id="内连接(A-∩-B)"><a href="#内连接(A-∩-B)" class="headerlink" title="内连接(A ∩ B)"></a>内连接(A ∩ B)</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-comment">-- 隐式内连接</span><br><span class="hljs-keyword">SELECT</span> 字段列表 <span class="hljs-keyword">FROM</span> 表<span class="hljs-number">1</span>,表<span class="hljs-number">2</span>… <span class="hljs-keyword">WHERE</span> 条件;<br><br><span class="hljs-comment">-- 显示内连接</span><br><span class="hljs-keyword">SELECT</span> 字段列表 <span class="hljs-keyword">FROM</span> 表<span class="hljs-number">1</span> [<span class="hljs-keyword">INNER</span>] <span class="hljs-keyword">JOIN</span> 表<span class="hljs-number">2</span> <span class="hljs-keyword">ON</span> 条件;<br></code></pre></td></tr></table></figure><h2 id="外链接(A-∪-B)"><a href="#外链接(A-∪-B)" class="headerlink" title="外链接(A ∪ B)"></a>外链接(A ∪ B)</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-comment">-- 左外连接</span><br><span class="hljs-keyword">SELECT</span> 字段列表 <span class="hljs-keyword">FROM</span> 表<span class="hljs-number">1</span> <span class="hljs-keyword">LEFT</span> [<span class="hljs-keyword">OUTER</span>] <span class="hljs-keyword">JOIN</span> 表<span class="hljs-number">2</span> <span class="hljs-keyword">ON</span> 条件;<br><br><span class="hljs-comment">-- 右外连接</span><br><span class="hljs-keyword">SELECT</span> 字段列表 <span class="hljs-keyword">FROM</span> 表<span class="hljs-number">1</span> <span class="hljs-keyword">RIGHT</span> [<span class="hljs-keyword">OUTER</span>] <span class="hljs-keyword">JOIN</span> 表<span class="hljs-number">2</span> <span class="hljs-keyword">ON</span> 条件;<br></code></pre></td></tr></table></figure><h1 id="事务(Transaction)"><a href="#事务(Transaction)" class="headerlink" title="事务(Transaction)"></a>事务(Transaction)</h1><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-comment">-- 开启事务</span><br><span class="hljs-keyword">START</span> <span class="hljs-keyword">TRANSACTION</span>;<br><span class="hljs-comment">-- 或者</span><br><span class="hljs-keyword">BEGIN</span>;<br><br><span class="hljs-comment">-- 提交事务</span><br><span class="hljs-keyword">COMMIT</span>;<br><br><span class="hljs-comment">-- 回滚事务</span><br><span class="hljs-keyword">ROLLBACK</span>;<br></code></pre></td></tr></table></figure><h2 id="事务的四大特征"><a href="#事务的四大特征" class="headerlink" title="事务的四大特征"></a>事务的四大特征</h2><ol><li>原子性(Atomicity): 事务是不可分割的最小操作单位,要么同时成功,要么同时失败 </li><li>一致性(Consistency) :事务完成时,必须使所有的数据都保持一致状态 </li><li>隔离性(Isolation) :多个事务之间,操作的可见性 </li><li>持久性(Durability) :事务一旦提交或回滚,它对数据库中的数据的改变就是永久的</li></ol>]]></content>
<tags>
<tag>SQL</tag>
<tag>MySQL</tag>
</tags>
</entry>
<entry>
<title>从 0 开始学习油猴脚本的编写到发布</title>
<link href="/post/4c463cc2/"/>
<url>/post/4c463cc2/</url>
<content type="html"><![CDATA[<p>因为我实在受不了我们学校网站的视频进度条和PDF浏览器,我就写了个跳转网页到文件源地址的小脚本<br>👉<a href="https://greasyfork.org/en/scripts/439394-waterloo-learn-video-pdf-redirect">Waterloo Learn Video & PDF Redirect (greasyfork.org)</a> <span class="heimu" title="你知道的太多了">偷偷引流</span></p><p>中途找教程的时候还挺折磨的,我就写一篇从编写到发布的流程介绍吧。</p><h2 id="技术栈"><a href="#技术栈" class="headerlink" title="技术栈"></a>技术栈</h2><ul><li>HTML</li><li>JavaScript</li><li>jQuery(最好,不会你用原生 JS 写应该也一样)</li></ul><h2 id="获取-Tampermonkey-浏览器插件"><a href="#获取-Tampermonkey-浏览器插件" class="headerlink" title="获取 Tampermonkey 浏览器插件"></a>获取 Tampermonkey 浏览器插件</h2><p>有手就行,没下的去这里下:<a href="https://www.tampermonkey.net/">Tampermonkey</a></p><h2 id="脚本编写"><a href="#脚本编写" class="headerlink" title="脚本编写"></a>脚本编写</h2><h3 id="点这个「加号」新建脚本。"><a href="#点这个「加号」新建脚本。" class="headerlink" title="点这个「加号」新建脚本。"></a>点这个「加号」新建脚本。</h3><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/tampermonkey/image_95.png" srcset="/img/loading.gif" lazyload style="zoom:60%;" /></p><h3 id="修改-header"><a href="#修改-header" class="headerlink" title="修改 header"></a>修改 header</h3><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/tampermonkey/image_96.png" srcset="/img/loading.gif" lazyload style="zoom: 67%;" /></p><p>其中 <code>@name</code> 是脚本的名称,<code>@match</code> 是这个脚本需要被运用在哪些网站上,以 Bilibili 番剧举例则是:<code>https://www.bilibili.com/bangumi/play/*</code>。其他你们自己看着填。</p><p>如果用 jQuery 的话,最好再加一行 <code>/* globals jQuery, $, waitForKeyElements */</code>,不然它老显示<code>eslint: no-under - '$' is not defined.</code>,我嫌烦。</p><h3 id="代码部分"><a href="#代码部分" class="headerlink" title="代码部分"></a>代码部分</h3><p>就和 JS 一样,比如我在这加一句 alert,他对应的页面就会弹出那个 alert。</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/tampermonkey/image_98.png" srcset="/img/loading.gif" lazyload style="zoom: 67%;" /></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/tampermonkey/image_97.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="脚本发布"><a href="#脚本发布" class="headerlink" title="脚本发布"></a>脚本发布</h2><p>在这里登录了以后填写一个表单:<a href="https://greasyfork.org/en/script_versions/new">Post a new script (greasyfork.org)</a></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/tampermonkey/image_99.png" srcset="/img/loading.gif" lazyload alt=""></p><p>点击发布就完事儿了!!</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/emoji/ciruno.gif" srcset="/img/loading.gif" lazyload alt=""></p>]]></content>
<tags>
<tag>jQuery</tag>
<tag>Tampermonkey</tag>
</tags>
</entry>
<entry>
<title>记一次拖了一个学期的 dubug 经历</title>
<link href="/post/5a8a6c8d/"/>
<url>/post/5a8a6c8d/</url>
<content type="html"><![CDATA[<p>事情是这样的,这学期刚开学的时候我发现我的博客在手机端和宽度不够的情况下导航栏出 bug 了。</p><p><img src="https://user-images.githubusercontent.com/55414757/133869599-3535344d-3509-4be6-a1b4-38ef1e92638e.gif" srcset="/img/loading.gif" lazyload alt=""></p><p>像这样,导航栏收不回去,且 Posts 和 Pages 不能展开。</p><p>我给 fluid 写了一份 issue,不过 fluid 作者说是我可能有插件和它冲突了。当时我正好懒 + 这个 bug 对电脑端使用影响不大所以我就没去动它。</p><p>今天正好有空所以我就把它修完了,这里记录一下吧,花了我两三个多小时草。结果发现是一个很小的问题导致的。</p><h2 id="问题排查"><a href="#问题排查" class="headerlink" title="问题排查"></a>问题排查</h2><p>先找到 fluid <a href="https://hexo.fluid-dev.com/">官方的网站 demo</a> 和我的对比一下,发现当它的导航栏展开了以后,右上角会变成 「X」的图标。</p><p>打开它的 html 源代码搜索 「nav」和我的对比一下,发现我的在展开的时候它的类不能成功变成 <code>class="navbar-col-show"</code>,但是在没有展开的时候所有地方都是一样的。</p><p>所以应该是导航栏的 js 出问题了。</p><p>我先是以为我的 <code>nav.ejs</code> 文件出错了,然后浪费了很多时间排查这个文件和引入它的地方有没有出错。</p><p>然后搞了半天,想想不行,打开 EventListener 的 click 和官方 demo 对比,发现我的多了奇奇怪怪的几个文件,不能确定其中哪几个是我网站的插件。排查了一下发现,只要 remove 掉 两个 <code>events.js</code> 之一和 <code>debugger:///VMxxx jquery.min.js</code> 导航栏就好了。其中 <code>events.js</code> 能让图标成功变成「X」, <code>debugger:///VMxxx jquery.min.js</code> 能让导航栏成功折叠和重新展开。</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image_82.png" srcset="/img/loading.gif" lazyload alt=""></p><p>下面一步花了我最久的时间:排查到底是哪里引入了这俩不用的 js。</p><h2 id="问题解决"><a href="#问题解决" class="headerlink" title="问题解决"></a>问题解决</h2><h3 id="第一步,找到哪里引入了-jquery"><a href="#第一步,找到哪里引入了-jquery" class="headerlink" title="第一步,找到哪里引入了 jquery"></a>第一步,找到哪里引入了 jquery</h3><p>我在页脚那里的 CDN trace 确实有用到 jquery,但是那里我引入的是 3.2.1 的 jQuery,而非 3.6.0(EventListener 那里的 <code>VMxxx jquery.min.js</code> 版本)。我恍然大悟,莫非是 fluid 自带的 jquery 和这个冲突了?但是我如果不在页脚那里引入 jquery,CDN trace 就不能正确显示了,所以看来是得把主题自带的 jquery 给删了。用 VsCode 找到引入 jquery 的地方:<code>scripts.ejs</code>,然后把引入 jquery 那行给注释掉 <code><%- js_ex(theme.static_prefix.jquery, 'jquery.min.js') %></code> </p><p>好,现在导航栏可以自由展开折叠了,但是右上角的图标还是不能正确显示。得找到哪里 引入了第二次 <code>events.js</code></p><h3 id="第二步,找到哪里引入了第二次-events-js"><a href="#第二步,找到哪里引入了第二次-events-js" class="headerlink" title="第二步,找到哪里引入了第二次 events.js"></a>第二步,找到哪里引入了第二次 events.js</h3><p>用 VsCode 搜索「events.js」发现我只在 <code>scripts.ejs</code> 里引入了一次。但是为什么在网站的源代码里会显示两次 <code><script src="/js/events.js"></script></code> 捏。最后发现我在 <code>footer.ejs</code> 最底下引入了一次 <code>scripts.ejs</code>。凎,应该是上次更新主题的时候没删干净。</p><h2 id="撒花"><a href="#撒花" class="headerlink" title="撒花"></a>撒花</h2><p>嘿嘿,这样导航栏的 bug 就被完美解决啦。成功又水了一篇。</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/xjgxh-pxafb.gif" srcset="/img/loading.gif" lazyload width="300"/></p>]]></content>
<tags>
<tag>Hexo</tag>
</tags>
</entry>
<entry>
<title>音乐乐理基础</title>
<link href="/post/8867a8f4/"/>
<url>/post/8867a8f4/</url>
<content type="html"><![CDATA[<p>因为要学吉他所以学了点基础乐理,看的是 <a href="https://detail.tmall.com/item.htm?spm=a220o.1000855.0.da321h.37802ab7D3vHcD&id=556507690378">音乐理论基础—李重光</a>,就着 <a href="https://www.bilibili.com/video/BV11x411m7rg">红色激情的视频</a>。</p><p>这里放放我记的笔记。想全屏看pdf的话 <a href="https://blog.trotyl.xyz/pdf/music_theory.pdf">链接在这</a>。</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/img-1635198459462501326cc36e2f865fcbaad9a21fb7ee4.jpg" srcset="/img/loading.gif" lazyload style="zoom:50%;" /></p> <div class="row"> <embed src="https://blog.trotyl.xyz/pdf/music_theory.pdf" width="100%" height="550" type="application/pdf"></div>]]></content>
<tags>
<tag>乐理</tag>
</tags>
</entry>
<entry>
<title>Windows 软件推荐|持续更新</title>
<link href="/post/22dee00c/"/>
<url>/post/22dee00c/</url>
<content type="html"><![CDATA[<p>最近我铁子也从 Mac 换成 Windows 了,因为我当时换的时候还是花了点时间适应的,寻思可以<del>水</del>写一篇哈哈<img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/emoji/miharo/miharo-8.png" srcset="/img/loading.gif" lazyload style="zoom: 25%;" /></p><p>推荐的软件主要包含了「帮助适应从 Mac 转到 Windows 的软件」和「普通但是在 Windows 上贼好用的软件」</p><p>每个软件我都会附上<strong>官网链接</strong>,买或者<span class="heimu" title="你知道的太多了">找破解版</span>什么的自己选择。</p><p>以后新遇到好用的软件我会更新。</p><hr><h1 id="1、Drawboard-PDF"><a href="#1、Drawboard-PDF" class="headerlink" title="1、Drawboard PDF"></a>1、Drawboard PDF</h1><p><a href="https://www.drawboard.com/">Drawboard: Easier PDF markup software</a></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/drawboard.png" srcset="/img/loading.gif" lazyload alt=""></p><p>全平台里<span class="heimu" title="你知道的太多了">没有 Mac 版本</span>最好用的 PDF 批注软件,支持数位板压感,很适合直接做老师发下来的 PDF 作业和 quiz。</p><p>之前我遇到了一个 bug,反馈给他们了以后他们当天就把他修复了,然后推了一个更新后的版本到 Microsoft Store,这办事速度值得我把它放在第一个。</p><p><strong>价格</strong>: 免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210813003405871.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="2、Snipaste"><a href="#2、Snipaste" class="headerlink" title="2、Snipaste"></a>2、Snipaste</h1><p><a href="https://www.snipaste.com/">Snipaste</a></p><p><img src="https://www.snipaste.com/img/logo.svg" srcset="/img/loading.gif" lazyload style="zoom: 25%;" /></p><p>截图+贴图软件,支持图片取色、编辑、马赛克、批注等。F1截图,F2贴图(把复制的图片贴在电脑窗口的最前端)画画时找参考图的时候非常好用</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210813010212231.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="3、Wox-Everything"><a href="#3、Wox-Everything" class="headerlink" title="3、Wox + Everything"></a>3、Wox + Everything</h1><p><a href="http://www.wox.one/">Wox</a></p><p><img src="https://avatars.githubusercontent.com/u/15628601?s=200&v=4" srcset="/img/loading.gif" lazyload style="zoom: 67%;" /></p><p><a href="https://www.voidtools.com/">Everything</a></p><p><img src="https://bizaladdin-image.baidu.com/0/pic/216797840_-466681421.jpg" srcset="/img/loading.gif" lazyload alt=""></p><p>高配版 「spotlight」,快速搜索电脑文件应用,利用 action key 快速打开搜索引擎搜索。</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210813125714888.png" srcset="/img/loading.gif" lazyload alt="1"></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image_900.png" srcset="/img/loading.gif" lazyload alt="2"></p><h1 id="4、Ditto"><a href="#4、Ditto" class="headerlink" title="4、Ditto"></a>4、Ditto</h1><p><a href="https://ditto-cp.sourceforge.io/">Ditto clipboard manager (sourceforge.io)</a></p><p><img src="https://store-images.s-microsoft.com/image/apps.21473.13510798887950305.d9b285e1-1829-480b-a018-980604fa17cc.df6c59c8-9b0e-4195-a06e-84b9bc76ccc0?mode=scale&q=90&h=200&w=200&background=#ffffff" srcset="/img/loading.gif" lazyload style="zoom: 50%;" /></p><p>一个剪切板软件,虽然没有 Mac 端的 「Paste」UI好,但胜在免费。</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210813131845382.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="5、QuickLook"><a href="#5、QuickLook" class="headerlink" title="5、QuickLook"></a>5、QuickLook</h1><p><a href="https://pooi.moe/QuickLook/">QuickLook</a></p><p><img src="https://avatars.githubusercontent.com/u/41779057?s=200&v=4" srcset="/img/loading.gif" lazyload style="zoom: 50%;" /></p><p>开源软件,模拟 Mac 的 「Preview」,按下空格快速查看文件。</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210813150318387.png" srcset="/img/loading.gif" lazyload style="zoom: 80%;" /></p><h1 id="6、RocketDock"><a href="#6、RocketDock" class="headerlink" title="6、RocketDock"></a>6、RocketDock</h1><p><a href="https://punklabs.com/">Punk Labs</a>(拉到最底下)</p><p><img src="https://punklabs.com/images/projects/RocketDock-256.png" srcset="/img/loading.gif" lazyload style="zoom: 50%;" /></p><p>仿 MacOS 的 Dock,可以把软件放在 Dock 里方便打开。UWP 软件的话添加空白图标然后把软件 lnk 的地址填上然后放上图标就可以了。</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210814145746784.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="7、Fences"><a href="#7、Fences" class="headerlink" title="7、Fences"></a>7、Fences</h1><p><a href="https://www.stardock.com/products/fences/">Stardock Fences: Organize your desktop shortcuts and icons</a></p><p><img src="https://www.stardock.com/products/fences4/images/top/fences_icon_256.png" srcset="/img/loading.gif" lazyload style="zoom: 50%;" /></p><p>整理桌面文件夹+创建文件夹桌面快捷入口。兼容 QuickLook。</p><p><strong>价格</strong>:$12.99 CAD</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210814150316073.png" srcset="/img/loading.gif" lazyload style="zoom: 67%;" /></p><h1 id="8、TIM"><a href="#8、TIM" class="headerlink" title="8、TIM"></a>8、TIM</h1><p><a href="https://office.qq.com/">TIM (qq.com)</a></p><p><img src="https://dss1.bdstatic.com/6OF1bjeh1BF3odCf/it/u=948423566,3120774668&fm=74&app=80&f=PNG&size=f121,121?sec=1880279984&t=73738e3bcc56ada427d90ad141c3979b" srcset="/img/loading.gif" lazyload alt=""></p><p>用来登录 QQ 和录屏的,比原版 QQ 好用不知道多少倍。一个是 UI 比较简洁,一个是它在录屏的时候比 QQ 好用,可以边录屏边在其他地方做事情。对比其他录屏软件,它不用录屏的结束以后再花时间转码存储。</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210814153428078.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="9、Edge"><a href="#9、Edge" class="headerlink" title="9、Edge"></a>9、Edge</h1><p><a href="https://www.microsoft.com/en-us/edge?r=1">Download Microsoft Edge Web Browser | Microsoft</a></p><p><img src="https://cdn.vox-cdn.com/thumbor/0n6dqQfk9MuOBSiM39Pog2Bw39Y=/1400x1400/filters:format(jpeg)/cdn.vox-cdn.com/uploads/chorus_asset/file/19341372/microsoftedgenewlogo.jpg" srcset="/img/loading.gif" lazyload style="zoom: 10%;" /></p><p><strong>全!世!界!最!好!用!的!浏!览!器!</strong>没有之一。好用得离谱。因为是 chromium 内核,所以可以用谷歌插件。我很喜欢的一个点就是你输入你想用的搜索引擎然后按 Tab 可以直接用那个搜索引擎搜索。</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210814160902792.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="10、MagicPods"><a href="#10、MagicPods" class="headerlink" title="10、MagicPods"></a>10、MagicPods</h1><p><a href="https://magicpods.app/">MagicPods - Add a little magic to your AirPods✨</a></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210814163754280.png" srcset="/img/loading.gif" lazyload style="zoom:33%;" /></p><p>一个可以让你的 Winodws 显示 airpods 电量的软件。</p><p><strong>价格</strong>:$2.49 CAD</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210814164455335.png" srcset="/img/loading.gif" lazyload alt=""></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210814164507544.png" srcset="/img/loading.gif" lazyload style="zoom:80%;" /></p><h1 id="11、KikoPlayer"><a href="#11、KikoPlayer" class="headerlink" title="11、KikoPlayer"></a>11、KikoPlayer</h1><p><a href="https://github.com/KikoPlayProject/KikoPlay">KikoPlay</a></p><p><img src="https://github.com/KikoPlayProject/KikoPlay/blob/master/res/images/kikoplay-4.png?raw=true" srcset="/img/loading.gif" lazyload style="zoom:80%;" /></p><p>本地视频弹幕匹配软件,对喜欢下载视频但是 i弹幕人士非常友好。可以把本地的视频匹配到 Bilibili、Acfun、爱奇艺和腾讯视频等弹幕网站上的弹幕。</p><p><strong>价格</strong>:免费</p><p><strong>软件截图</strong>:</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/others/image-20210815151105229.png" srcset="/img/loading.gif" lazyload alt=""></p>]]></content>
<categories>
<category>好用的xx推荐</category>
</categories>
<tags>
<tag>杂七杂八</tag>
</tags>
</entry>
<entry>
<title>Java Server and Client 实现聊天室</title>
<link href="/post/38733/"/>
<url>/post/38733/</url>
<content type="html"><![CDATA[<p>cs的作业,这里放一下吧。肝了两天两夜,要写吐了。</p><p>用java socket实现简易聊天室, 因为server端不是我写的,我就发下client端的.</p><p>这是几个截图:<br><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/Img/note/RHHS/cs/1b8e3969c8422c0c566e83208e43c6b.png" srcset="/img/loading.gif" lazyload alt=""><br><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/Img/note/RHHS/cs/82bcf8971585036abe13eed78f995ea.png" srcset="/img/loading.gif" lazyload alt=""></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/Img/note/RHHS/cs/96446f52b137b6b01061ab5e241834a.png" srcset="/img/loading.gif" lazyload alt=""></p><p>下面是源码:<br><figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">import javax.swing.*;<br>import java.awt.*;<br>import java.awt.event.ActionEvent;<br>import java.awt.event.ActionListener;<br>import java.awt.event.WindowEvent;<br>import java.awt.event.WindowListener;<br>import java.io.BufferedReader;<br>import java.io.IOException;<br>import java.io.InputStreamReader;<br>import java.io.PrintWriter;<br>import java.net.Socket;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * ChatClient.java</span><br><span class="hljs-comment"> * @version 1.0</span><br><span class="hljs-comment"> * @author Trotyl</span><br><span class="hljs-comment"> * @since 2020 Dec.3</span><br><span class="hljs-comment"> * The client side of a chat program</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-keyword">class</span> ChatClient {<br> <span class="hljs-keyword">private</span> JFrame connectWindow;<span class="hljs-comment">//first window</span><br> <span class="hljs-keyword">private</span> JTextField typeField;<span class="hljs-comment">//type field</span><br> <span class="hljs-keyword">private</span> JTextArea msgArea;<span class="hljs-comment">//message area</span><br> <span class="hljs-keyword">private</span> Socket mySocket; <span class="hljs-comment">//socket for connection</span><br> <span class="hljs-keyword">private</span> BufferedReader input; <span class="hljs-comment">//reader for network stream</span><br> <span class="hljs-keyword">private</span> PrintWriter output; <span class="hljs-comment">//printWriter for network output</span><br> <span class="hljs-keyword">private</span> boolean running = <span class="hljs-literal">true</span>; <span class="hljs-comment">//thread status via boolean</span><br> <span class="hljs-keyword">private</span> JLabel connectionError;<span class="hljs-comment">//label</span><br> <span class="hljs-keyword">private</span> boolean isConnected = <span class="hljs-literal">false</span>;<br> <span class="hljs-keyword">private</span> JComboBox userList;<span class="hljs-comment">//list of all online users</span><br> <span class="hljs-keyword">private</span> String userName;<span class="hljs-comment">//current user name</span><br> <span class="hljs-keyword">private</span> JTextArea statusArea;<span class="hljs-comment">//area of all the users online</span><br> <span class="hljs-keyword">private</span> JLabel label;<br> <span class="hljs-keyword">private</span> String selected;<span class="hljs-comment">//selected user</span><br><br> public static void main(String<span class="hljs-literal">[]</span> args) {<br> <span class="hljs-keyword">new</span> <span class="hljs-constructor">ChatClient()</span>.get<span class="hljs-constructor">Port()</span>;<br> }<br><br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * window for entering the ip and port</span><br><span class="hljs-comment"> */</span><br> public void get<span class="hljs-constructor">Port()</span> {<br> <span class="hljs-comment">//setting up the connecting window</span><br> connectWindow = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JFrame(<span class="hljs-string">"connect"</span>)</span>;<br> JPanel panel = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JPanel()</span>;<br> panel.set<span class="hljs-constructor">PreferredSize(<span class="hljs-params">new</span> Dimension(400, 250)</span>);<br> JLabel name = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"Connect"</span>)</span>;<br> name.set<span class="hljs-constructor">Bounds(170, 20, 70, 20)</span>;<br> panel.set<span class="hljs-constructor">Layout(<span class="hljs-params">null</span>)</span>;<br> JLabel hostL = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"ip "</span>)</span>;<br> JTextField hostT = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextField(10)</span>;<br> hostL.set<span class="hljs-constructor">Bounds(110, 70, 70, 20)</span>;<br> hostT.set<span class="hljs-constructor">Text(<span class="hljs-string">"127.0.0.1"</span>)</span>;<br> hostT.set<span class="hljs-constructor">Bounds(170, 70, 150, 20)</span>;<br> JLabel portL = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"port "</span>)</span>;<br> portL.set<span class="hljs-constructor">Bounds(110, 150, 70, 20)</span>;<br> JTextField portT = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextField(10)</span>;<br> portT.set<span class="hljs-constructor">Text(<span class="hljs-string">"5000"</span>)</span>;<br> portT.set<span class="hljs-constructor">Bounds(170, 150, 150, 20)</span>;<br> JButton connectButton = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JButton(<span class="hljs-string">"connect"</span>)</span>;<br> connectButton.set<span class="hljs-constructor">Bounds(80, 200, 90, 30)</span>;<br> connectionError = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">""</span>)</span>;<br> connectionError.set<span class="hljs-constructor">Foreground(Color.<span class="hljs-params">red</span>)</span>;<br> connectionError.set<span class="hljs-constructor">Bounds(200, 200, 200, 30)</span>;<br> <span class="hljs-comment">//adding all the components</span><br> panel.add(name);<br> panel.add(hostL);<br> panel.add(hostT);<br> panel.add(portL);<br> panel.add(portT);<br> panel.add(connectionError);<br> panel.add(connectButton);<br> <span class="hljs-comment">//exit on close</span><br> connectWindow.set<span class="hljs-constructor">DefaultCloseOperation(JFrame.EXIT_ON_CLOSE)</span>;<br> connectWindow.add(panel);<br> connectWindow.pack<span class="hljs-literal">()</span>;<br> <span class="hljs-comment">//press the connect button when press enter</span><br> connectWindow.get<span class="hljs-constructor">RootPane()</span>.set<span class="hljs-constructor">DefaultButton(<span class="hljs-params">connectButton</span>)</span>;<br> <span class="hljs-comment">//open in the middle of the screen</span><br> connectWindow.set<span class="hljs-constructor">LocationRelativeTo(<span class="hljs-params">null</span>)</span>;<br> connectWindow.set<span class="hljs-constructor">Visible(<span class="hljs-params">true</span>)</span>;<br> connectButton.add<span class="hljs-constructor">ActionListener(<span class="hljs-params">new</span> ActionListener()</span> {<br> @Override<br> public void action<span class="hljs-constructor">Performed(ActionEvent <span class="hljs-params">e</span>)</span> {<br> String host = hostT.get<span class="hljs-constructor">Text()</span>;<br> String port = portT.get<span class="hljs-constructor">Text()</span>;<br> <span class="hljs-comment">//connect</span><br> connect(host, port);<br> hostT.set<span class="hljs-constructor">Text(<span class="hljs-string">""</span>)</span>;<br> portT.set<span class="hljs-constructor">Text(<span class="hljs-string">""</span>)</span>;<br> <span class="hljs-keyword">if</span> (isConnected) {<br> <span class="hljs-comment">//open login page</span><br> log<span class="hljs-constructor">In()</span>;<br> }<br> }<br> });<br> }<br><br> public Socket connect(String ip, String port) {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Attempting to make a connection.."</span>);<br> <span class="hljs-comment">//default ip and port are 127.0.0.1 and 5000</span><br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-built_in">int</span> port1 = <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Integer</span>.</span></span>parse<span class="hljs-constructor">Int(<span class="hljs-params">port</span>)</span>;<br> mySocket = <span class="hljs-keyword">new</span> <span class="hljs-constructor">Socket(<span class="hljs-params">ip</span>, <span class="hljs-params">port1</span>)</span>; <span class="hljs-comment">//attempt socket connection (local address). This will wait until a connection is made</span><br> InputStreamReader stream1 = <span class="hljs-keyword">new</span> <span class="hljs-constructor">InputStreamReader(<span class="hljs-params">mySocket</span>.<span class="hljs-params">getInputStream</span>()</span>); <span class="hljs-comment">//Stream for network input</span><br> input = <span class="hljs-keyword">new</span> <span class="hljs-constructor">BufferedReader(<span class="hljs-params">stream1</span>)</span>;<br> output = <span class="hljs-keyword">new</span> <span class="hljs-constructor">PrintWriter(<span class="hljs-params">mySocket</span>.<span class="hljs-params">getOutputStream</span>()</span>); <span class="hljs-comment">//assign printWriter to network stream</span><br> connectWindow.dispose<span class="hljs-literal">()</span>;<br> isConnected = <span class="hljs-literal">true</span>;<br> } catch (Exception e) { <span class="hljs-comment">//connection error occurred</span><br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Connection to Server Failed"</span>);<br> connectionError.set<span class="hljs-constructor">Text(<span class="hljs-string">"Wrong ip or port"</span>)</span>;<br> }<br> <span class="hljs-keyword">if</span> (isConnected<span class="hljs-operator"> == </span><span class="hljs-literal">true</span>) {<br> <span class="hljs-comment">//this is to get rid of the first and second welcome message that disturbs the login</span><br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">if</span> (input.ready<span class="hljs-literal">()</span>) {<br> input.read<span class="hljs-constructor">Line()</span>;<br> }<br> } catch (IOException ex) {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Failed to receive msg from the server"</span>);<br> }<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">if</span> (input.ready<span class="hljs-literal">()</span>) {<br> input.read<span class="hljs-constructor">Line()</span>;<br> }<br> } catch (IOException ex) {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Failed to receive msg from the server"</span>);<br> }<br> }<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Connection made."</span>);<br> return mySocket;<br> }<br><br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * window for login</span><br><span class="hljs-comment"> */</span><br> public void log<span class="hljs-constructor">In()</span> {<br> <span class="hljs-comment">//setting up the log in page</span><br> JFrame logInWindow = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JFrame(<span class="hljs-string">"LogIn"</span>)</span>;<br> JPanel panel = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JPanel()</span>;<br> panel.set<span class="hljs-constructor">Layout((<span class="hljs-params">new</span> GridLayout(4, 2)</span>));<br> JLabel passwordL = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"password"</span>)</span>;<br> JTextField passwordT = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextField(10)</span>;<br> JLabel userNameL = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"username"</span>)</span>;<br> JTextField userNameT = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextField(10)</span>;<br> JButton logInButton = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JButton(<span class="hljs-string">"log in"</span>)</span>;<br> JButton registerButton = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JButton(<span class="hljs-string">"register"</span>)</span>;<br> JLabel logInError = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">""</span>)</span>;<br> JLabel blank = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">""</span>)</span>;<br> logInError.set<span class="hljs-constructor">Foreground(Color.<span class="hljs-params">red</span>)</span>;<br> <span class="hljs-comment">//adding all the components</span><br> panel.add(userNameT);<br> panel.add(userNameL);<br> panel.add(passwordT);<br> panel.add(passwordL);<br> panel.add(logInButton);<br> panel.add(registerButton);<br> panel.add(logInError);<br> panel.add(blank);<br> logInWindow.set<span class="hljs-constructor">DefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)</span>;<br> logInWindow.add(BorderLayout.CENTER, panel);<br> logInWindow.set<span class="hljs-constructor">Size(500, 200)</span>;<br> logInWindow.set<span class="hljs-constructor">LocationRelativeTo(<span class="hljs-params">null</span>)</span>;<br> logInWindow.set<span class="hljs-constructor">Visible(<span class="hljs-params">true</span>)</span>;<br> logInWindow.get<span class="hljs-constructor">RootPane()</span>.set<span class="hljs-constructor">DefaultButton(<span class="hljs-params">logInButton</span>)</span>;<br> <span class="hljs-comment">//when the log in button is pressed</span><br> logInButton.add<span class="hljs-constructor">ActionListener(<span class="hljs-params">new</span> ActionListener()</span> {<br> @Override<br> public void action<span class="hljs-constructor">Performed(ActionEvent <span class="hljs-params">e</span>)</span> {<br> userName = userNameT.get<span class="hljs-constructor">Text()</span>;<br> String password = passwordT.get<span class="hljs-constructor">Text()</span>;<br> <span class="hljs-comment">//check if username and password is blank</span><br> <span class="hljs-keyword">if</span> (userName.equals(<span class="hljs-string">""</span>)<span class="hljs-operator"> || </span>password.equals(<span class="hljs-string">""</span>)) {<br> logInError.set<span class="hljs-constructor">Text(<span class="hljs-string">"username and password can't be blank"</span>)</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-comment">//pass in the password and username</span><br> output.println(userName + <span class="hljs-string">":"</span> + password);<br> output.flush<span class="hljs-literal">()</span>;<br> <span class="hljs-comment">//read message</span><br> boolean loop = <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">while</span> (loop) {<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">if</span> (input.ready<span class="hljs-literal">()</span>) {<br> <span class="hljs-comment">//check for an incoming message</span><br> String msg;<br> msg = input.read<span class="hljs-constructor">Line()</span>; <span class="hljs-comment">//read the message</span><br> <span class="hljs-keyword">if</span> (msg.equals(<span class="hljs-string">"Username is currently online! Please use another account! \"username:password\""</span>)) {<br> logInError.set<span class="hljs-constructor">Text(<span class="hljs-string">"user online, try another account"</span>)</span>;<br> loop = <span class="hljs-literal">false</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (msg.equals(<span class="hljs-string">"Username or password incorrect! Please try again! \"username:password\""</span>)) {<br> logInError.set<span class="hljs-constructor">Text(<span class="hljs-string">"username of password incorrect"</span>)</span>;<br> loop = <span class="hljs-literal">false</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (msg.starts<span class="hljs-constructor">With(<span class="hljs-string">"Welcome"</span>)</span>) {<span class="hljs-comment">//if success</span><br> <span class="hljs-comment">//close the log in window and open the message window</span><br> logInWindow.dispose<span class="hljs-literal">()</span>;<br> loop = <span class="hljs-literal">false</span>;<br> start<span class="hljs-constructor">Messaging()</span>;<br> }<br> }<br> } catch (IOException ex) {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Failed to receive msg from the server"</span>);<br> }<br> }<br> }<br> }<br> });<br><br> <span class="hljs-comment">//when the register button is pressed</span><br> registerButton.add<span class="hljs-constructor">ActionListener(<span class="hljs-params">new</span> ActionListener()</span> {<br> @Override<br> public void action<span class="hljs-constructor">Performed(ActionEvent <span class="hljs-params">e</span>)</span> {<br> <span class="hljs-comment">//close the login widow and open a register window</span><br> logInWindow.dispose<span class="hljs-literal">()</span>;<br> register<span class="hljs-literal">()</span>;<br> }<br> });<br> }<br><br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * window for registering an account</span><br><span class="hljs-comment"> */</span><br> public void register<span class="hljs-literal">()</span> {<br> <span class="hljs-comment">//components</span><br> JFrame registrationWindow = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JFrame(<span class="hljs-string">"Registration"</span>)</span>;<br> JPanel panel = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JPanel()</span>;<br> panel.set<span class="hljs-constructor">Layout((<span class="hljs-params">new</span> GridLayout(3, 3)</span>));<br> JLabel userNameL = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"user name "</span>)</span>;<br> JTextField userNameT = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextField(10)</span>;<br> JLabel passwordL = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"password "</span>)</span>;<br> JTextField passwordT = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextField(10)</span>;<br> JButton registerButton = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JButton(<span class="hljs-string">"register"</span>)</span>;<br> JButton logInButton = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JButton(<span class="hljs-string">"log in"</span>)</span>;<br> JLabel text = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">""</span>)</span>;<br> text.set<span class="hljs-constructor">Foreground(Color.<span class="hljs-params">red</span>)</span>;<br> <span class="hljs-comment">//add the components to panel</span><br> panel.add(userNameL);<br> panel.add(userNameT);<br> panel.add(registerButton);<br> panel.add(passwordL);<br> panel.add(passwordT);<br> panel.add(logInButton);<br> panel.add(text);<br> <span class="hljs-comment">//exit on close</span><br> registrationWindow.set<span class="hljs-constructor">DefaultCloseOperation(JFrame.EXIT_ON_CLOSE)</span>;<br> registrationWindow.add(BorderLayout.CENTER, panel);<br> registrationWindow.set<span class="hljs-constructor">Size(550, 170)</span>;<br> registrationWindow.set<span class="hljs-constructor">LocationRelativeTo(<span class="hljs-params">null</span>)</span>;<br> registrationWindow.set<span class="hljs-constructor">Visible(<span class="hljs-params">true</span>)</span>;<br> <span class="hljs-comment">//when log in button is pressed</span><br> logInButton.add<span class="hljs-constructor">ActionListener(<span class="hljs-params">new</span> ActionListener()</span> {<br> @Override<br> public void action<span class="hljs-constructor">Performed(ActionEvent <span class="hljs-params">e</span>)</span> {<br> <span class="hljs-comment">//close the register window and open the log in window</span><br> registrationWindow.dispose<span class="hljs-literal">()</span>;<br> log<span class="hljs-constructor">In()</span>;<br> }<br> });<br><br> <span class="hljs-comment">//when register button is pressed</span><br> registerButton.add<span class="hljs-constructor">ActionListener(<span class="hljs-params">new</span> ActionListener()</span> {<br> @Override<br> public void action<span class="hljs-constructor">Performed(ActionEvent <span class="hljs-params">e</span>)</span> {<br> <span class="hljs-comment">//get the username and password</span><br> String userName = userNameT.get<span class="hljs-constructor">Text()</span>;<br> String password = passwordT.get<span class="hljs-constructor">Text()</span>;<br> <span class="hljs-comment">//check if they are blank</span><br> <span class="hljs-keyword">if</span> (userName.equals(<span class="hljs-string">""</span>)<span class="hljs-operator"> || </span>password.equals(<span class="hljs-string">""</span>)) {<br> text.set<span class="hljs-constructor">Text(<span class="hljs-string">"name and pwd can't be blank"</span>)</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-comment">//pass in the username and password to the server</span><br> output.println(<span class="hljs-string">"register:"</span> + userName + <span class="hljs-string">":"</span> + password);<br> output.flush<span class="hljs-literal">()</span>;<br> boolean loop = <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">while</span> (loop) {<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">if</span> (input.ready<span class="hljs-literal">()</span>) {<br> <span class="hljs-comment">//check for an incoming message</span><br> String msg;<br> msg = input.read<span class="hljs-constructor">Line()</span>; <span class="hljs-comment">//read the message</span><br> <span class="hljs-keyword">if</span> (msg.equals(<span class="hljs-string">"Username already exists, please use another one"</span>)) {<br> text.set<span class="hljs-constructor">Text(<span class="hljs-string">"username already exists"</span>)</span>;<br> loop = <span class="hljs-literal">false</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (msg.starts<span class="hljs-constructor">With(<span class="hljs-string">"Successfully"</span>)</span>) {<br> registrationWindow.dispose<span class="hljs-literal">()</span>;<br> loop = <span class="hljs-literal">false</span>;<br> <span class="hljs-comment">//start login window</span><br> log<span class="hljs-constructor">In()</span>;<br> }<br> }<br> } catch (IOException ex) {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Failed to receive msg from the server"</span>);<br> }<br> }<br> }<br> }<br> });<br> <span class="hljs-comment">//exit on close</span><br> registrationWindow.set<span class="hljs-constructor">DefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)</span>;<br> }<br><br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * message window</span><br><span class="hljs-comment"> */</span><br> public void start<span class="hljs-constructor">Messaging()</span> {<br> <span class="hljs-comment">//send message to all users as default</span><br> selected = <span class="hljs-string">"All"</span>;<br> <span class="hljs-comment">//start two new threads</span><br> Thread t = <span class="hljs-keyword">new</span> <span class="hljs-constructor">Thread(<span class="hljs-params">new</span> CheckMessage()</span>);<br> Thread t2 = <span class="hljs-keyword">new</span> <span class="hljs-constructor">Thread(<span class="hljs-params">new</span> <span class="hljs-params">checkUsers</span>()</span>);<br> t.start<span class="hljs-literal">()</span>;<br> t2.start<span class="hljs-literal">()</span>;<br> <span class="hljs-comment">//frame and components</span><br> JFrame window = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JFrame(<span class="hljs-string">"Chat Client"</span>)</span>;<br> JPanel southPanel = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JPanel()</span>;<br> southPanel.set<span class="hljs-constructor">Layout(<span class="hljs-params">new</span> GridLayout(2, 2)</span>);<br> label = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JLabel(<span class="hljs-string">"press [Enter] to send"</span>)</span>;<br> <span class="hljs-comment">//area that contains status of online users</span><br> statusArea = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextArea(18, 14)</span>;<br> statusArea.set<span class="hljs-constructor">Editable(<span class="hljs-params">false</span>)</span>;<br> JButton sendButton = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JButton(<span class="hljs-string">"SEND"</span>)</span>;<br> sendButton.add<span class="hljs-constructor">ActionListener(<span class="hljs-params">new</span> SendButtonListener()</span>);<br> typeField = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextField(10)</span>;<br> <span class="hljs-comment">//place where selecting which person to chat with</span><br> userList = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JComboBox()</span>;<br> userList.add<span class="hljs-constructor">Item(<span class="hljs-string">"All"</span>)</span>;<br> msgArea = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JTextArea()</span>;<br> msgArea.set<span class="hljs-constructor">Editable(<span class="hljs-params">false</span>)</span>;<br> southPanel.add(userList);<br> southPanel.add(label);<br> southPanel.add(typeField);<br> southPanel.add(sendButton);<br> <span class="hljs-comment">//add a scroll pane to the two text areas</span><br> JScrollPane jsp = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JScrollPane(<span class="hljs-params">msgArea</span>)</span>;<br> JScrollPane jsp2 = <span class="hljs-keyword">new</span> <span class="hljs-constructor">JScrollPane(<span class="hljs-params">statusArea</span>)</span>;<br> window.add(BorderLayout.SOUTH, southPanel);<br> window.add(jsp);<br> window.add(BorderLayout.WEST, jsp2);<br> <span class="hljs-comment">//exit on close</span><br> window.set<span class="hljs-constructor">DefaultCloseOperation(JFrame.EXIT_ON_CLOSE)</span>;<br> window.set<span class="hljs-constructor">Size(400, 400)</span>;<br> window.set<span class="hljs-constructor">Visible(<span class="hljs-params">true</span>)</span>;<br> <span class="hljs-comment">//getting all the users' information just after log in</span><br> output.println(<span class="hljs-string">"-list"</span>);<br> output.flush<span class="hljs-literal">()</span>;<br> <span class="hljs-comment">//open at middle of the screen</span><br> window.set<span class="hljs-constructor">LocationRelativeTo(<span class="hljs-params">null</span>)</span>;<br> window.get<span class="hljs-constructor">RootPane()</span>.set<span class="hljs-constructor">DefaultButton(<span class="hljs-params">sendButton</span>)</span>;<br> window.add<span class="hljs-constructor">WindowListener(<span class="hljs-params">new</span> WindowListener()</span> {<br> @Override<br> public void window<span class="hljs-constructor">Opened(WindowEvent <span class="hljs-params">e</span>)</span> {<br> }<br><br> @Override<br> public void window<span class="hljs-constructor">Closing(WindowEvent <span class="hljs-params">e</span>)</span> {<br> <span class="hljs-comment">//tell the server to close it's socket when closing</span><br> output.println(<span class="hljs-string">"$closed$"</span>);<br> output.flush<span class="hljs-literal">()</span>;<br> }<br><br> @Override<br> public void window<span class="hljs-constructor">Closed(WindowEvent <span class="hljs-params">e</span>)</span> {<br> running = <span class="hljs-literal">false</span>;<br> }<br><br> @Override<br> public void window<span class="hljs-constructor">Iconified(WindowEvent <span class="hljs-params">e</span>)</span> {<br> }<br><br> @Override<br> public void window<span class="hljs-constructor">Deiconified(WindowEvent <span class="hljs-params">e</span>)</span> {<br> }<br><br> @Override<br> public void window<span class="hljs-constructor">Activated(WindowEvent <span class="hljs-params">e</span>)</span> {<br> }<br><br> @Override<br> public void window<span class="hljs-constructor">Deactivated(WindowEvent <span class="hljs-params">e</span>)</span> {<br> }<br> });<br> }<br><br> <span class="hljs-comment">//inner class that implements Runnable</span><br> <span class="hljs-keyword">class</span> CheckMessage implements Runnable {<br> <span class="hljs-comment">//convert second to hours or minutes or still seconds</span><br> String convert<span class="hljs-constructor">Time(String <span class="hljs-params">sec</span>)</span> {<br> <span class="hljs-built_in">int</span> second = <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Integer</span>.</span></span>parse<span class="hljs-constructor">Int(<span class="hljs-params">sec</span>)</span>;<br> <span class="hljs-keyword">if</span> (second > <span class="hljs-number">86400</span>) {<br> return <span class="hljs-number">86400</span><span class="hljs-operator"> / </span><span class="hljs-number">24</span> + <span class="hljs-string">" days"</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (second > <span class="hljs-number">3600</span>) {<br> return second<span class="hljs-operator"> / </span><span class="hljs-number">60</span> + <span class="hljs-string">" hours"</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (second > <span class="hljs-number">60</span>) {<br> return second<span class="hljs-operator"> / </span><span class="hljs-number">60</span> + <span class="hljs-string">" mins"</span>;<br> } <span class="hljs-keyword">else</span> {<br> return second + <span class="hljs-string">" secs"</span>;<br> }<br> }<br><br> @Override<br> public void run<span class="hljs-literal">()</span> {<br> <span class="hljs-keyword">while</span> (running) { <span class="hljs-comment">// loop unit a message is received</span><br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">if</span> (input.ready<span class="hljs-literal">()</span>) {<span class="hljs-comment">//check for an incoming message</span><br> String msg;<br> msg = input.read<span class="hljs-constructor">Line()</span>; <span class="hljs-comment">//read the message</span><br> <span class="hljs-keyword">if</span> (msg.equals(<span class="hljs-string">"use -pm:username:message to send a pm"</span>)<span class="hljs-operator"> || </span>msg.equals(<span class="hljs-string">"Online Users: "</span>)<span class="hljs-operator"> || </span>msg.contains(<span class="hljs-string">", seen"</span>)) {<br> <span class="hljs-keyword">if</span> (msg.equals(<span class="hljs-string">"Online Users: "</span>)) {<br> statusArea.set<span class="hljs-constructor">Text(<span class="hljs-string">"Online Users:\n"</span>)</span>;<br> selected = userList.get<span class="hljs-constructor">SelectedItem()</span> + <span class="hljs-string">""</span>;<br> userList.remove<span class="hljs-constructor">AllItems()</span>;<br> userList.add<span class="hljs-constructor">Item(<span class="hljs-string">"All"</span>)</span>;<br> <span class="hljs-keyword">if</span> (!selected.equals(<span class="hljs-string">"All"</span>)) {<br> userList.add<span class="hljs-constructor">Item(<span class="hljs-params">selected</span>)</span>;<br> }<br> userList.set<span class="hljs-constructor">SelectedItem(<span class="hljs-params">selected</span>)</span>;<br> }<br> <span class="hljs-built_in">int</span> i = msg.index<span class="hljs-constructor">Of(<span class="hljs-string">", seen"</span>)</span>;<br> <span class="hljs-keyword">if</span> (i != -<span class="hljs-number">1</span>) {<br> String onlineUser = msg.substring(<span class="hljs-number">0</span>, i);<br> String userStatus = msg.substring(<span class="hljs-number">0</span>, i) + <span class="hljs-string">"\nlast activity ["</span> + convert<span class="hljs-constructor">Time(<span class="hljs-params">msg</span>.<span class="hljs-params">substring</span>(<span class="hljs-params">i</span> + 7, <span class="hljs-params">msg</span>.<span class="hljs-params">indexOf</span>(<span class="hljs-string">"."</span>)</span>)) + <span class="hljs-string">"] ago"</span>;<br> statusArea.append(userStatus + <span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">if</span> (!onlineUser.equals(userName)<span class="hljs-operator"> && </span>!onlineUser.equals(selected)) {<br> userList.add<span class="hljs-constructor">Item(<span class="hljs-params">onlineUser</span>)</span>;<br> }<br> }<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (msg.equals(<span class="hljs-string">"Unknown user!"</span>)) {<br> label.set<span class="hljs-constructor">Foreground(Color.<span class="hljs-params">red</span>)</span>;<br> label.set<span class="hljs-constructor">Text(<span class="hljs-string">"["</span> + <span class="hljs-params">selected</span> + <span class="hljs-string">"] is offline"</span>)</span>;<br> userList.set<span class="hljs-constructor">SelectedItem(<span class="hljs-string">"All"</span>)</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!msg.starts<span class="hljs-constructor">With(<span class="hljs-string">"use -"</span>)</span>) {<br> <span class="hljs-comment">//if it's not a server instruction</span><br> msgArea.append(msg + <span class="hljs-string">"\n"</span>);<br> <span class="hljs-comment">//getting who is the one sending the message</span><br> <span class="hljs-built_in">int</span> i = msg.index<span class="hljs-constructor">Of(<span class="hljs-string">"->"</span>)</span>;<br> <span class="hljs-keyword">if</span> (i != -<span class="hljs-number">1</span>) {<br> label.set<span class="hljs-constructor">Foreground(<span class="hljs-params">new</span> Color(0, 102, 0)</span>);<br> <span class="hljs-keyword">if</span> (msg.substring(<span class="hljs-number">0</span>, i).equals(userName)) {<br> label.set<span class="hljs-constructor">Text(<span class="hljs-string">"You are talking only to ["</span> + <span class="hljs-params">msg</span>.<span class="hljs-params">substring</span>(<span class="hljs-params">i</span> + 2, <span class="hljs-params">msg</span>.<span class="hljs-params">indexOf</span>(<span class="hljs-string">":"</span>)</span>) + <span class="hljs-string">"]"</span>);<br> } <span class="hljs-keyword">else</span> {<br> label.set<span class="hljs-constructor">Text(<span class="hljs-string">"["</span> + <span class="hljs-params">msg</span>.<span class="hljs-params">substring</span>(0, <span class="hljs-params">i</span>)</span> + <span class="hljs-string">"] is talking only to you"</span>);<br> }<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (msg.contains(<span class="hljs-string">":"</span>)) {<br> String name = msg.substring(<span class="hljs-number">0</span>, msg.index<span class="hljs-constructor">Of(<span class="hljs-string">":"</span>)</span>);<br> label.set<span class="hljs-constructor">Foreground(Color.<span class="hljs-params">blue</span>)</span>;<br> <span class="hljs-keyword">if</span> (!name.equals(userName)) {<br> label.set<span class="hljs-constructor">Text(<span class="hljs-string">"["</span> + <span class="hljs-params">msg</span>.<span class="hljs-params">substring</span>(0, <span class="hljs-params">msg</span>.<span class="hljs-params">indexOf</span>(<span class="hljs-string">":"</span>)</span>) + <span class="hljs-string">"] is talking to everyone"</span>);<br> } <span class="hljs-keyword">else</span> {<br> label.set<span class="hljs-constructor">Text(<span class="hljs-string">"You are talking to everyone"</span>)</span>;<br> }<br> }<br> }<br> }<br> } catch (IOException e) {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Failed to receive msg from the server"</span>);<br> }<br> }<br> <span class="hljs-keyword">try</span> { <span class="hljs-comment">//after leaving the main loop we need to close all the sockets</span><br> input.close<span class="hljs-literal">()</span>;<br> output.close<span class="hljs-literal">()</span>;<br> mySocket.close<span class="hljs-literal">()</span>;<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>exit(<span class="hljs-number">0</span>);<br> } catch (Exception e) {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.println(<span class="hljs-string">"Failed to close socket"</span>);<br> }<br> }<br> }<br><br> <span class="hljs-comment">//another inner class that implements Runnable</span><br> <span class="hljs-keyword">class</span> checkUsers implements Runnable {<br> @Override<br> <span class="hljs-comment">//check the status of all the users every second</span><br> public void run<span class="hljs-literal">()</span> {<br> <span class="hljs-keyword">while</span> (running) {<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Thread</span>.</span></span>sleep(<span class="hljs-number">1000</span>);<br> } catch (InterruptedException e) {<br> }<br> output.println(<span class="hljs-string">"-list"</span>);<br> output.flush<span class="hljs-literal">()</span>;<br> }<br> }<br> }<br><br> <span class="hljs-comment">//****** Inner Classes for Action Listeners ****</span><br> <span class="hljs-comment">// send - send msg to server (also flush), then clear the JTextField</span><br> <span class="hljs-keyword">class</span> SendButtonListener implements ActionListener {<br> public void action<span class="hljs-constructor">Performed(ActionEvent <span class="hljs-params">event</span>)</span> {<br> <span class="hljs-comment">//Send a message to the client</span><br> msgArea.set<span class="hljs-constructor">CaretPosition(<span class="hljs-params">msgArea</span>.<span class="hljs-params">getText</span>()</span>.length<span class="hljs-literal">()</span>);<br> String userSelected = userList.get<span class="hljs-constructor">SelectedItem()</span> + <span class="hljs-string">""</span>;<br> <span class="hljs-keyword">if</span> (!userSelected.equals(<span class="hljs-string">"All"</span>)) {<br> <span class="hljs-comment">//sending a private massage</span><br> <span class="hljs-comment">/* added a space in the end because it's going to have an</span><br><span class="hljs-comment"> error when blank massage is sent privately*/</span><br> output.println(<span class="hljs-string">"-pm:"</span> + userSelected + <span class="hljs-string">":"</span> + typeField.get<span class="hljs-constructor">Text()</span> + <span class="hljs-string">" "</span>);<br> } <span class="hljs-keyword">else</span> {<br> output.println(typeField.get<span class="hljs-constructor">Text()</span>);<br> }<br> output.flush<span class="hljs-literal">()</span>;<br> typeField.set<span class="hljs-constructor">Text(<span class="hljs-string">""</span>)</span>;<br> }<br> }<br>}<span class="hljs-comment">//end ChatClient class</span><br><br></code></pre></td></tr></table></figure></p>]]></content>
<categories>
<category>RHHS</category>
</categories>
<tags>
<tag>java</tag>
</tags>
</entry>
<entry>
<title>Hexo 迁移|mac 到 windows</title>
<link href="/post/61834/"/>
<url>/post/61834/</url>
<content type="html"><![CDATA[<p>最近换电脑了嘛,就想着得把博客搬到这个电脑上,网上找了找,都是windows迁到mac上的,完全没有从mac到win的。。<span class="heimu" title="你知道的太多了">windows现在已经这么过气了吗?泪目</span></p><p>既然这样我就写一下步骤吧,虽然其实和别的系统差不多,但是毕竟我还是遇到了蛮多坑的。<img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/movingHexo/1.jpg" srcset="/img/loading.gif" lazyload width = "150" align=justify /></p><hr><h1 id="在旧电脑(mac)上应该做的事"><a href="#在旧电脑(mac)上应该做的事" class="headerlink" title="在旧电脑(mac)上应该做的事"></a>在旧电脑(mac)上应该做的事</h1><p>搞个u盘或者之类的东西,把以下这些文件复制一下</p><ul><li>source(文件夹)</li><li>themes/主题文件</li><li>_config.yml</li><li>package.json</li><li>如果你有下一些需要你配置文件的插件,把那些需要的东西也复制下<ul><li>比如说你有live2d的插件并且用的是自定义的模型,复制放模型的文件夹:live2d_models</li></ul></li><li>如果你有CNAME文件,复制它</li></ul><h1 id="在新电脑(win)上"><a href="#在新电脑(win)上" class="headerlink" title="在新电脑(win)上"></a>在新电脑(win)上</h1><h2 id="一、安装node-js"><a href="#一、安装node-js" class="headerlink" title="一、安装node.js"></a>一、安装node.js</h2><h3 id="1-下载nodejs"><a href="#1-下载nodejs" class="headerlink" title="1.下载nodejs"></a>1.下载nodejs</h3><p>建议手动下载,<a href="https://nodejs.org/en/download/">这是官网链接</a><br>LTS的这个<br><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/movingHexo/20201127232937.png" srcset="/img/loading.gif" lazyload alt=""></p><h3 id="2-安装"><a href="#2-安装" class="headerlink" title="2. 安装"></a>2. 安装</h3><p>安装就不用我教了吧,点就完事了<img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/emoji/tieba-17.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="二、下载git并向Github添加SSH-Key"><a href="#二、下载git并向Github添加SSH-Key" class="headerlink" title="二、下载git并向Github添加SSH Key"></a>二、下载git并向Github添加SSH Key</h2><h3 id="1-创建SSH-Key"><a href="#1-创建SSH-Key" class="headerlink" title="1. 创建SSH Key"></a>1. 创建SSH Key</h3><p>1) 打开Gitbash<br>2) 输入<br><code>ssh-keygen -t rsa -C "[email protected]"</code><br>这里得把你自己的邮箱地址替换上去<br>3) 一路回车<br>4) 在用户目录(user/xxx)下找到.ssh的文件夹<br>5) 找到<code>id_rsa.pub</code>的文件打开<strong>(一定要后缀是.pub的那个)</strong>,复制里面的东西</p><h3 id="2-添加SSH-Key"><a href="#2-添加SSH-Key" class="headerlink" title="2. 添加SSH Key"></a>2. 添加SSH Key</h3><p>1) 登录GitHub<br>2) 点头像<br>3) 点开Settings<br><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/movingHexo/20201128001321.png" srcset="/img/loading.gif" lazyload alt=""><br><span class="heimu" title="你知道的太多了">话说再次让我感叹一下QQ截图真他娘的好用</span><br>4)左侧栏找到SSH and GPG keys,点进去<br><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/movingHexo/20201128001610.png" srcset="/img/loading.gif" lazyload alt=""><br>5)点New SSH key然后把刚才从<code>id_rsa.pub</code>文件里复制的东西复制到Key的那一栏里,Title那栏随便写<br><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/movingHexo/20201128001721.png" srcset="/img/loading.gif" lazyload alt=""><br>6)点击Add key,完成</p><h2 id="三、以管理员模式打开cmd"><a href="#三、以管理员模式打开cmd" class="headerlink" title="三、以管理员模式打开cmd"></a>三、以管理员模式打开cmd</h2><p><strong>要管理员模式哈!!</strong></p><h3 id="1-先check一下node和npm有没有安装成功"><a href="#1-先check一下node和npm有没有安装成功" class="headerlink" title="1.先check一下node和npm有没有安装成功"></a>1.先check一下node和npm有没有安装成功</h3><p>分别输入<code>node -v</code>回车和<code>npm -v</code>回车,如果显示版本号,那就说明成功了</p><h3 id="2-国内npm可能很慢,可以先用npm来安装一下cnpm(不嫌慢的这步也可以跳过)"><a href="#2-国内npm可能很慢,可以先用npm来安装一下cnpm(不嫌慢的这步也可以跳过)" class="headerlink" title="2.国内npm可能很慢,可以先用npm来安装一下cnpm(不嫌慢的这步也可以跳过)"></a>2.国内npm可能很慢,可以先用npm来安装一下cnpm(不嫌慢的这步也可以跳过)</h3><p>输入<code>npm install -g cnpm --registry=https://registry.npm.taobao.org</code>回车</p><p>如果安装了cnpm,后面我用npm的时候请自行替换成cnpm</p><h2 id="四-安装和搭建Hexo"><a href="#四-安装和搭建Hexo" class="headerlink" title="四. 安装和搭建Hexo"></a>四. 安装和搭建Hexo</h2><h3 id="1-安装"><a href="#1-安装" class="headerlink" title="1. 安装"></a>1. 安装</h3><p>输入<code>npm install -g hexo-cli</code><br>可以用<code>hexo -v</code>验证一下是否成功。如果显示版本号,说明成功</p><h3 id="2-建立一个放博客的文件夹"><a href="#2-建立一个放博客的文件夹" class="headerlink" title="2. 建立一个放博客的文件夹"></a>2. 建立一个放博客的文件夹</h3><p>我是在C盘下面建的(因为我不喜欢分盘),你可以在D盘或者别的什么地方建都可以<br>1) cd到那个地方<code>mkdir blog</code><br>不叫blog也行,有的人喜欢叫hexo什么的<br>2) 建立好了以后<code>cd blog</code>进去执行<code>hexo init</code>建立一个新的Hexo目录<br>3) 将之前从旧电脑上复制的package.json复制到新的目录下,把原来的文件覆盖掉</p><p><strong>因为mac系统的原因,它会生成很多奇奇怪怪的隐藏文件,得先把那些.打头的文件删掉,所有文件夹里都看一遍,所有文件夹里的都得删除,否则会出现<code>hexo err: YAMLException: null byte is not allowed in input at line 1, column 1</code>等错误提示</strong></p><p>4) 执行<code>hexo install</code><br>把剩下的那些从旧电脑上复制的文件和文件夹放到对应的位置<br>6) <code>hexo g</code>然后<code>hexo s</code>,打开<a href="http://localhost:4000/">http://localhost:4000/</a><br>看看有没有生成好</p><h2 id="五、hexo-d一下看看能不能成功部署"><a href="#五、hexo-d一下看看能不能成功部署" class="headerlink" title="五、hexo d一下看看能不能成功部署"></a>五、hexo d一下看看能不能成功部署</h2><p>如果出现了<br><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs dockerfile">Please tell me who you are.<br><br><span class="hljs-keyword">Run</span><br><br><span class="bash">git config --global user.email <span class="hljs-string">"[email protected]"</span></span><br> git config --global <span class="hljs-keyword">user</span>.name <span class="hljs-string">"Your Name"</span><br></code></pre></td></tr></table></figure><br>1)输入<code>git config --global user.email "你的邮箱“</code>这个邮箱得是你在GitHub里用的那个<br>2)输入`git config —global user.name “你的名字”<br>这个名字随便起就行了</p><p>完事!!</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/movingHexo/%EF%BC%92.gif" srcset="/img/loading.gif" lazyload width = "200" alt="好耶" /></p>]]></content>
<tags>
<tag>Hexo</tag>
</tags>
</entry>
<entry>
<title>Grade 12 Chemistry(窗了)</title>
<link href="/post/3587/"/>
<url>/post/3587/</url>
<content type="html"><![CDATA[<p>懒得写了,遛了遛了<img src="https://imgsa.baidu.com/forum/w%3D580/sign=8568e233d888d43ff0a991fa4d1fd2aa/0fed89eef01f3a29549e90889725bc315d607c5f.jpg" srcset="/img/loading.gif" lazyload alt=""></p><hr><p>A note for my grade 12 chem class.</p><p><span class="heimu" title="你知道的太多了">因为这学科太tm恶心了,我怕我不认真搞会凉所以专门弄一篇呜呜呜</span></p><h1 id="Grade-9-11-Review"><a href="#Grade-9-11-Review" class="headerlink" title="Grade 9-11 Review"></a>Grade 9-11 Review</h1><h2 id="Significant-digit"><a href="#Significant-digit" class="headerlink" title="Significant digit"></a>Significant digit</h2><h3 id="Adding-and-Subtracting"><a href="#Adding-and-Subtracting" class="headerlink" title="Adding and Subtracting"></a>Adding and Subtracting</h3><p>小数点最少的那个</p><h3 id="Multiplying-and-Dividing"><a href="#Multiplying-and-Dividing" class="headerlink" title="Multiplying and Dividing"></a>Multiplying and Dividing</h3><p>significant digit最少的那个</p><h2 id="Nomenclature"><a href="#Nomenclature" class="headerlink" title="Nomenclature"></a>Nomenclature</h2><div class="table-container"><table><thead><tr><th>oxyacid</th><th>anion</th><th>anion name</th><th>oxyacid</th></tr></thead><tbody><tr><td>HClO</td><td>ClO<sup>-</sup></td><td>hypochlorite</td><td>hypochlorous acid</td></tr><tr><td>HClO<sub>2<sub></td><td>ClO<sub>2</sub><sup>-</sup></td><td>chlorite</td><td>chlorous acid</td></tr><tr><td>HClO<sub>3<sub></td><td>ClO<sub>3</sub><sup>-</sup></td><td>chlorate</td><td>chloric acid</td></tr><tr><td>HClO<sub>4<sub></td><td>ClO<sub>4</sub><sup>-</sup></td><td>perchlorate</td><td>perchloric acid</td></tr></tbody></table></div><hr><h3 id="1-ic-acid"><a href="#1-ic-acid" class="headerlink" title="1) -ic acid"></a>1) -ic acid</h3><p><strong>HNO<sub>3</sub></strong> nitric acid</p><p><strong>H<sub>2</sub>CO<sub>3</sub></strong> carbonic acid</p><p><strong>HClO<sub>3</sub></strong> chloric acid</p><p><strong>H<sub>3</sub>SO<sub>4</sub></strong> sulphuric acid</p><p><strong>H<sub>3</sub>PO<sub>4</sub></strong> phosphuric acid</p><h3 id="2-per-ic-acid-1-oxygen-from-ic"><a href="#2-per-ic-acid-1-oxygen-from-ic" class="headerlink" title="2)per-ic acid (+1 oxygen from -ic)"></a>2)per-ic acid (+1 oxygen from -ic)</h3><p><strong>HClO<sub>4</sub></strong> percholric acid</p><h3 id="3-ate-ion-1-2-3-H-from-ic-not-stable"><a href="#3-ate-ion-1-2-3-H-from-ic-not-stable" class="headerlink" title="3) -ate ion (-1/2/3 H from -ic)(not stable)"></a>3) -ate ion (-1/2/3 H from -ic)(not stable)</h3><p><strong>NO<sub>3</sub><sup>-</sup></strong> nitrate ion</p><p><strong>HCO<sub>3</sub><sup>-</sup></strong> hydrogen carbonate / bicarbonate</p><ul><li><strong>CO<sub>3</sub><sup>2-</sup></strong> carbonate</li></ul><p><strong>HClO<sub>2</sub><sup>-</sup></strong> chlorate</p><p><strong>HSO<sub>4</sub><sup>-</sup></strong> hydrogen sulphate / bisulphate</p><ul><li><strong>SO<sub>4</sub><sup>2-</sup></strong> sulphate</li></ul><p><strong>H<sub>2</sub>PO<sub>4</sub><sup>-</sup></strong> dihydrogen phosphate </p><ul><li><strong>HPO<sub>4</sub><sup>2-</sup></strong> hydrogen phosphate / biphosphate</li><li><strong>PO<sub>4</sub><sup>3-</sup></strong> phosphate</li></ul><p><strong>CH<sub>3</sub>COO</strong> acetate</p><h3 id="4-per-ate-ions-1-H-from-per-ic"><a href="#4-per-ate-ions-1-H-from-per-ic" class="headerlink" title="4) per-ate ions (-1 H from per-ic)"></a>4) per-ate ions (-1 H from per-ic)</h3><p><strong>ClO<sub>4</sub><sup>-</sup></strong> perchlorate ion</p><h3 id="5-ous-acid-1-O-from-ic"><a href="#5-ous-acid-1-O-from-ic" class="headerlink" title="5) -ous acid (-1 O from -ic)"></a>5) -ous acid (-1 O from -ic)</h3><p><strong>HNO<sub>2</sub></strong> nitrous acid</p><p><strong>HClO<sub>2</sub></strong> clorous acid</p><p><strong>H<sub>2</sub>SO<sub>3</sub></strong> sulphurous acid</p><p><strong>H<sub>3</sub>PO<sub>3</sub></strong> Phosphurous acid</p><h3 id="6-ite-ion-1-2-3-H-remove-from-ous"><a href="#6-ite-ion-1-2-3-H-remove-from-ous" class="headerlink" title="6) -ite ion (-1/2/3 H remove from -ous)"></a>6) -ite ion (-1/2/3 H remove from -ous)</h3><p><strong>NO<sub>2</sub><sup>-</sup></strong> nitrite ion</p><p><strong>ClO<sub>2</sub><sup>-</sup></strong> cholorite</p><p><strong>HSO<sub>3</sub><sup>-</sup></strong> hydrogen sulphite / bisulphite</p><ul><li><strong>SO<sub>3</sub><sup>2-</sup></strong> sulphite</li></ul><p><strong>H<sub>2</sub>PO<sub>3</sub><sup>-</sup></strong> dihydrogen phosphite </p><ul><li><strong>HPO<sub>3</sub><sup>2-</sup></strong> hydrogen phosphite / biphosphite</li><li><strong>PO<sub>3</sub><sup>3-</sup></strong> phosphite</li></ul><h3 id="7-hypo-ous-1-O-from-ous"><a href="#7-hypo-ous-1-O-from-ous" class="headerlink" title="7) hypo-ous (-1 O from -ous)"></a>7) hypo-ous (-1 O from -ous)</h3><p><strong>HClO</strong> hypochlorous acid (Halogens)</p><h3 id="8-hypo-ite-1-H-from-hypo-ous"><a href="#8-hypo-ite-1-H-from-hypo-ous" class="headerlink" title="8) hypo-ite (-1 H from hypo-ous)"></a>8) hypo-ite (-1 H from hypo-ous)</h3><p><strong>ClO<sup>-</sup></strong> hypochlorite acid</p><h2 id="Relating-Mass-to-Moles"><a href="#Relating-Mass-to-Moles" class="headerlink" title="Relating Mass to Moles"></a>Relating Mass to Moles</h2><p><strong>m</strong> = mass(g)</p><p><strong>n</strong> = number of moles</p><p><strong>Mm</strong> =molar mass(g)(Some people use MM as abbreviation</p><p>$n=\frac{m}{Mm}$ or $m=n\times Mn$</p><hr><p><strong>N</strong> = number of individual particle</p><p><strong>n</strong> = number of moles</p><p><strong>N<sub>AV</sub></strong> = Avogadro’s Number</p><p>$N=n\times N_{AV}$</p><hr><p>for solutions:</p><p>$n = c\times v$</p><hr><p>for gases:</p><p><strong>P</strong> = pressure(kPa)</p><p><strong>V</strong> = volumn(L)</p><p><strong>n</strong> = Number of moles of gas(mol)</p><p><strong>T</strong> = Temperature</p><p><strong>R</strong> = Gas constant = $\frac{8.31kPa\times L}{mol\times K}$</p><p>$PV=nRT$</p><p>$n=\frac{PV}{RT}$</p><h2 id="Types-of-Reactions"><a href="#Types-of-Reactions" class="headerlink" title="Types of Reactions"></a>Types of Reactions</h2><h3 id="Synthesis-Reaction"><a href="#Synthesis-Reaction" class="headerlink" title="Synthesis Reaction"></a>Synthesis Reaction</h3><p><strong>X + Y → XY</strong></p><h4 id="1-Simple-oxidation-reactions-heating-with-oxygen"><a href="#1-Simple-oxidation-reactions-heating-with-oxygen" class="headerlink" title="1) Simple oxidation reactions (heating with oxygen)"></a>1) Simple oxidation reactions (heating with oxygen)</h4><p>Metal or non-metal + oxygen → an oxide</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem1.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="2-Binary-compound-formation"><a href="#2-Binary-compound-formation" class="headerlink" title="2) Binary compound formation"></a>2) Binary compound formation</h4><p>Metal or non-metal + oxygen → binary compound</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem2.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="3-Acid-and-Base-formation"><a href="#3-Acid-and-Base-formation" class="headerlink" title="3) Acid and Base formation"></a>3) Acid and Base formation</h4><p>Non-metal oxide + water → nonmetal oxyacid</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem4.png" srcset="/img/loading.gif" lazyload alt=""></p><p>Metal oxide + water → the metal hydroxide</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem3.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="4-Metal-carbonate-formation"><a href="#4-Metal-carbonate-formation" class="headerlink" title="4) Metal carbonate formation"></a>4) Metal carbonate formation</h4><p>Metal oxide + carbon dioxide → metal carbonate</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem5.png" srcset="/img/loading.gif" lazyload alt=""></p><h3 id="Decomposition-Reactions"><a href="#Decomposition-Reactions" class="headerlink" title="Decomposition Reactions"></a>Decomposition Reactions</h3><p><strong>XY → X + Y ( + Z )</strong></p><h4 id="1-Binary-Compounds-decompose-into-two-elements"><a href="#1-Binary-Compounds-decompose-into-two-elements" class="headerlink" title="1) Binary Compounds decompose into two elements"></a>1) Binary Compounds decompose into two elements</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem6.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="2-Metal-carbonates-→-metal-oxide-carbon"><a href="#2-Metal-carbonates-→-metal-oxide-carbon" class="headerlink" title="2) Metal carbonates → metal oxide + carbon"></a>2) Metal carbonates → metal oxide + carbon</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem7.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="3-Metal-hydrogen-carbonates-bicarbonates-→-metal-carbonate-water-carbon-dioxide"><a href="#3-Metal-hydrogen-carbonates-bicarbonates-→-metal-carbonate-water-carbon-dioxide" class="headerlink" title="3) Metal hydrogen carbonates (bicarbonates) → metal carbonate + water+ carbon dioxide"></a>3) Metal hydrogen carbonates (bicarbonates) → metal carbonate + water+ carbon dioxide</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem8.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="4-Metal-nitrate-→-into-metal-nitrite-and-oxygen-gas"><a href="#4-Metal-nitrate-→-into-metal-nitrite-and-oxygen-gas" class="headerlink" title="4) Metal nitrate → into metal nitrite and oxygen gas"></a>4) Metal nitrate → into metal nitrite and oxygen gas</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem9.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="5-Metal-hydroxide-→-into-metal-oxide-and-water"><a href="#5-Metal-hydroxide-→-into-metal-oxide-and-water" class="headerlink" title="5) Metal hydroxide → into metal oxide and water"></a>5) Metal hydroxide → into metal oxide and water</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem10.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="Metal-chlorates-→-metal-chloride-oxygen-gas"><a href="#Metal-chlorates-→-metal-chloride-oxygen-gas" class="headerlink" title="Metal chlorates → metal chloride + oxygen gas"></a>Metal chlorates → metal chloride + oxygen gas</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem11.png" srcset="/img/loading.gif" lazyload alt=""></p><h3 id="Double-Displacement-Precipitation-Reactions"><a href="#Double-Displacement-Precipitation-Reactions" class="headerlink" title="Double Displacement Precipitation Reactions"></a>Double Displacement Precipitation Reactions</h3><ul><li>Must have percipitates</li><li>Need to use solubility table to predict if these reactions will or occur.</li></ul><p><strong>WX<sub>(aq)</sub> +YZ<sub>(aq)</sub> → WZ + YX</strong></p><h4 id="1-Double-Displacement-Neutralizaton-Reaction"><a href="#1-Double-Displacement-Neutralizaton-Reaction" class="headerlink" title="1) Double Displacement Neutralizaton Reaction"></a>1) Double Displacement Neutralizaton Reaction</h4><p>acid + base → salt +water</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/RHHS/chem/chem12.png" srcset="/img/loading.gif" lazyload alt=""></p><h4 id="2-Neutralization-–-Decomposition-Reactions-also-called-Double-Displacement-neutralization-reactions-producing-gas"><a href="#2-Neutralization-–-Decomposition-Reactions-also-called-Double-Displacement-neutralization-reactions-producing-gas" class="headerlink" title="2) Neutralization – Decomposition Reactions (also called Double Displacement neutralization reactions producing gas)"></a>2) Neutralization – Decomposition Reactions (also called Double Displacement neutralization reactions producing gas)</h4><ul><li>Acids mixed with carbonates or bicarbonates will undergo a double displacement reaction producing a salt and carbonic acid (H<sub>2</sub>CO<sub>3</sub>).</li><li>The carbonic acid decomposes<br>into water and carbon dioxide gas. The carbonic acid<br>intermediate is not usually written in the chemical<br>equation.</li></ul><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/emoji/alu/chem13.png" srcset="/img/loading.gif" lazyload alt=""></p><ul><li>Other reactions of this type include a sulphite or a hydrogen sulphite mixed with acid.</li></ul><h3 id="Singel-Displacement-Reaction"><a href="#Singel-Displacement-Reaction" class="headerlink" title="Singel Displacement Reaction"></a>Singel Displacement Reaction</h3><p><strong>X + YZ → XZ + Y</strong></p><ul><li>Some metals will react with water. These are indicated on the metal activity series. If a metal reacts with water the products are the metal hydroxide and hydrogen gas.</li></ul><p>Metal + water → metal hydroxide + hydrogen gas</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/emoji/alu/chem14.png" srcset="/img/loading.gif" lazyload alt=""></p><h3 id="Combustion-of-Organic-Compounds-Containing-only-C-and-H-or-only-C-H-and-O"><a href="#Combustion-of-Organic-Compounds-Containing-only-C-and-H-or-only-C-H-and-O" class="headerlink" title="Combustion of Organic Compounds Containing only C and H or only C, H and O"></a>Combustion of Organic Compounds Containing only C and H or only C, H and O</h3><p>If oxygen supply is limited, products are carbon monoxide and water; carbon and water; or carbon dioixde, carbon monoxide, carbon, and water</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/emoji/alu/chem15.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="Unit-1-Thermochemistry"><a href="#Unit-1-Thermochemistry" class="headerlink" title="Unit 1|Thermochemistry"></a>Unit 1|Thermochemistry</h1><details> <summary>course pack</summary><div class="row"><iframe src="https://drive.google.com/file/d/1zQ_aSPdv-nqYamR2SzauVYxZOJKlturU/preview" style="width:100%; height:550px"></iframe></div></details><details> <summary>thermo data table</summary><div class="row"><iframe src="https://drive.google.com/file/d/1K3Q0ZjB0ggTgmnzkNOUaRG0A2JyVersK/preview" style="width:100%; height:550px"></iframe></div></details><h2 id="Energy-Definitions"><a href="#Energy-Definitions" class="headerlink" title="Energy Definitions"></a>Energy Definitions</h2><p>low temperture = low movement</p><p>high temperture = high movement</p><p><img src="https://lh3.googleusercontent.com/qZQWfYPmcwbqm01DxYccX8FST12pGeFkjnHdOmbJlzKYUVJ0nt-sQa9WKnb0xqsh0vqiS0d9CyewLcK9gpyWBHc7VUk0uK6zrmaU1HNS99at13ewczSWUr2JKITaUYPc1-8GDHW7" srcset="/img/loading.gif" lazyload alt=""></p><p><strong>Specific Heat</strong> Specific heat is a physical property of matter. It is defined as the energy needed to raise the temperature of one gram of substance by one ℃</p><p>$Specific Heat =\frac{energy\ absorbed}{mass\ of\ sample\times temperture\ change\ in\ _{}^{o}\textrm{C}}$ or $c=\frac{q}{m\times \Delta T}$</p><p>Rearranging the equation $q=m\times c\times\Delta T$</p><p><strong>Molar heat capacity:</strong> is the energy required to raise the temperature of on mole of a substance by 1 ℃(J/mol×℃)</p><h2 id="Calorimetry"><a href="#Calorimetry" class="headerlink" title="Calorimetry"></a>Calorimetry</h2><p><img src="https://letstalkscience.ca/sites/default/files/styles/x_large/public/2020-06/system_surroundings_by_reaction_type.png?itok=NZXFzRPZ" srcset="/img/loading.gif" lazyload alt=""></p><ul><li>Exothermic q<sub>sys</sub> <0</li><li>Endothermic q<sub>sys</sub> >0 </li><li>q<sub>sys</sub> = -q<sub>surr</sub></li></ul><h2 id="Enthalpy-Changes"><a href="#Enthalpy-Changes" class="headerlink" title="Enthalpy Changes"></a>Enthalpy Changes</h2><ul><li><strong>q for the system is positive</strong> if energy goes into the system and the temperature of the surroundings decreases.</li><li><strong>q for the system is negative</strong> if the system loses heat to the surrounding and the temperature of the surroundings increases</li><li>the overall energy must be conserved <strong>q<sub>sys</sub> = -q<sub>surr</sub></strong></li></ul><hr><p>When a physical or chemical change occurs that releases or absorbs energy</p><ul><li>thermal energy from the surroundings is converted to bond energy for the system in endothermic reactions</li><li>bond energy from the system is converted to thermal energy in the surroundings in an exothermic reactions</li><li>The overall energy must be conseved <strong>ΔH<sub>system</sub> = -q<sub>surroundings</sub></strong><ul><li>ΔH is the transfer of energy in a reaction</li><li>The units of enthalpy are kilojoules <strong>(kJ)</strong></li></ul></li><li>If the amount of substance that reacted is given, the enthalpy can be expresses as a molar quantity of molar enthalpy <strong>(ΔH<sub>rxn</sub>)</strong>. <ul><li><strong>n × ΔH<sub>rxn</sub> = ΔH<sub>system</sub></strong></li><li>The units of molar enthalpy are kilojoules per mol <strong>(kJ/mol)</strong></li></ul></li></ul><h2 id="Writing-Thermochemical-Equations"><a href="#Writing-Thermochemical-Equations" class="headerlink" title="Writing Thermochemical Equations"></a>Writing Thermochemical Equations</h2><p>A thermochemical equation is a clear way of communicationg informations about the enthalpy change in a reaction</p><p>Ex. The synthesis of water from its elements is an exothermic reaction and can be represented by two thermochemical equations.</p><p><img src="https://latex.codecogs.com/gif.latex?H_{2(g)}+\frac{1}{2}O_2\rightarrow&space;H_{2}O_{(l)}+285kJ" srcset="/img/loading.gif" lazyload title="H_{2(g)}+\frac{1}{2}O_2\rightarrow H_{2}O_{(l)}+285kJ" /></p><p><img src="https://latex.codecogs.com/gif.latex?H_{2(g)}+\frac{1}{2}O_{2}\rightarrow&space;H_{2}O_{(l)}\quad\Delta&space;H=-285kJ" srcset="/img/loading.gif" lazyload title="H_{2(g)}+\frac{1}{2}O_{2}\rightarrow H_{2}O_{(l)}\quad\Delta H=-285kJ" /></p><h2 id="Hess’s-law"><a href="#Hess’s-law" class="headerlink" title="Hess’s law"></a>Hess’s law</h2><p>In going from a particular set of reactants to<br>a particular set of products, the change in enthalpy is the same whether the reaction takes place in one<br>step or in a series of steps.</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/Img/note/RHHS/chem/chem16.png" srcset="/img/loading.gif" lazyload alt=""></p><p>The first equation equals to the sum of the latter 2 equations.</p><h2 id="Standard-Enthalpies-of-Formation"><a href="#Standard-Enthalpies-of-Formation" class="headerlink" title="Standard Enthalpies of Formation"></a>Standard Enthalpies of Formation</h2><p><strong>Formation reactions</strong> are reactions in which a compound is formed from its element.</p><p>Ex.<br><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/Img/note/RHHS/chem/chem17.png" srcset="/img/loading.gif" lazyload alt=""></p><hr><p>The superscript <strong>°</strong>, refers to a specific set of conditions. Standard ambient temperature (in <strong>SATP</strong>) is <strong>25 °C = 298 K</strong>.</p><p><strong>For a compound:</strong></p><ul><li>for a gaseous substance is at a pressure of 1 atm or 101.3 kPa.</li><li>for non-gaseous pure substances, the standard state is pure liquid or solid</li><li>for a dissolved substance in solution, the standard state is at a concentration of exactly 1.0 M.</li></ul><p><strong>For an element:</strong></p><ul><li>the standard state of an element is the form in which the element exists under STAP conditions of 1 atm (101.3 kPa) and 25°C = 298K.</li></ul><hr><p><strong>Standard Enthalpy Change</strong>, ΔH°, is the enthalpy change that accompanies a reaction when the<br>reactants and products are in their standard states.</p><p><strong>Standard Enthalpy of Formation</strong>, ΔH°<sub>f</sub> , is the enthalpy change that results when one mole of the substance is formed from its elements with all substances in their standard states.</p><p>The standard enthalpies of formation of for any element already in its standard states is zero.</p><p><strong>Elements → 1Compound</strong></p><h3 id="Using-Standard-Heats-of-Formation-in-Hess’s-Law"><a href="#Using-Standard-Heats-of-Formation-in-Hess’s-Law" class="headerlink" title="Using Standard Heats of Formation in Hess’s Law"></a>Using Standard Heats of Formation in Hess’s Law</h3><ol><li><strong>reactants</strong> broken down → into their <strong>elements</strong> in standart state</li><li><strong>elements</strong> in standard state assembled → into the <strong>products</strong> in their standard states</li></ol><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem18.png" srcset="/img/loading.gif" lazyload alt=""></p><hr><p><strong>ΔH° = ∑nΔH°<sub>f</sub>products - ∑nΔH°<sub>f</sub>reactants</strong></p><hr><h2 id="Calculating-ΔH-using-Bond-Energies"><a href="#Calculating-ΔH-using-Bond-Energies" class="headerlink" title="Calculating ΔH using Bond Energies"></a>Calculating ΔH using Bond Energies</h2><p>Bond energy is the <strong>average</strong> energy needed to break a given type of bond.</p><hr><p><strong>ΔH° = ∑n × D(bonds broken) - ∑n × D(bonds formed)</strong></p><hr><p><em>D</em> = bond energy per mole of bonds</p><p><em>n</em> = moles (based on the equation coefficients</p><hr><h2 id="Thermodynamics-Entropy-and-Gibb’s-Free-Energy"><a href="#Thermodynamics-Entropy-and-Gibb’s-Free-Energy" class="headerlink" title="Thermodynamics, Entropy and Gibb’s Free Energy"></a>Thermodynamics, Entropy and Gibb’s Free Energy</h2><p><strong>Entropy</strong> - Molecular randomness or disorder</p><p>The symbol of <strong>entropy</strong> if ΔS (Unit: J/mol·K</p><ul><li>ΔS is (+) when randonmness or disorder of a system increases</li><li>ΔS is (-) when randonmness or disorder of a system decreases</li></ul><hr><p><strong>ΔS° = ∑n×ΔS°<sub>f(products)</sub> - ∑n×ΔS°<sub>f(reactants)</sub></strong></p><hr><p>The value ΔG is a measure of the maximum amount of work a system can do as it approaches the end of reaction.</p><hr><p><strong>ΔG°=ΔH°-TΔS°</strong></p><p><strong>ΔG<sub>rxn</sub>° = ∑n×ΔG°<sub>f(products)</sub> - ∑n×ΔG°<sub>f(reactants)</sub></strong></p><hr><p>ΔG° is negative (-) for spontaneous reaction</p><p>ΔG° is positive (+) for non-spontaneous reaction</p><p>ΔG° = 0 for a system that has both the forward and reverse reaction occuring at the same rate so the amount of products and reactants do not change</p><hr><h2 id="Reaction-Kinetics-Factors-Affecting-Rate"><a href="#Reaction-Kinetics-Factors-Affecting-Rate" class="headerlink" title="Reaction Kinetics-Factors Affecting Rate"></a>Reaction Kinetics-Factors Affecting Rate</h2><ol><li>Nature of the reactant</li><li>Concentration</li><li>Surface area</li><li>Temperature</li><li>Catalysts</li></ol><h2 id="Theories-of-Reaction-Rates"><a href="#Theories-of-Reaction-Rates" class="headerlink" title="Theories of Reaction Rates"></a>Theories of Reaction Rates</h2><h3 id="Factors-Influencing-Collision"><a href="#Factors-Influencing-Collision" class="headerlink" title="Factors Influencing Collision"></a>Factors Influencing Collision</h3><p><strong>1) Orientation</strong></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem19.png" srcset="/img/loading.gif" lazyload alt=""></p><p><strong>2) Energy of colliding molecules</strong></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem20.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="Activation-Energies-and-Transition-States"><a href="#Activation-Energies-and-Transition-States" class="headerlink" title="Activation Energies and Transition States"></a>Activation Energies and Transition States</h2><p>An <strong>effective collision</strong> is one in which the<br>reactants collide with the correct orientation and energy to form an activated complex that leads to the<br>formation of products.</p><p><strong>1) Energy Diagram for an Exothermic Reaction</strong></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem21.png" srcset="/img/loading.gif" lazyload alt=""></p><p><strong>2) Energy Diagram for an Endothermic Reaction</strong></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem22.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="Catalysts"><a href="#Catalysts" class="headerlink" title="Catalysts"></a>Catalysts</h2><p>A catalyst is a substance that increases the reaction rate without increasing the number of collisions and without being consumed itself.</p><ul><li><strong>1<sup>st</sup> Kind</strong></li></ul><p>$A+B\overset{y}{\rightarrow}C+D$</p><p><strong>y</strong> is a catalyst (usually heterogeneous)</p><ul><li><strong>2<sup>nd</sup> Kind</strong></li></ul><p>$A+y\rightarrow Ay$ (Ay is an intermediate)</p><p>$Ay+B\rightarrow C+D+y$</p><p><strong>y</strong> is a catalyst (usually homogeneous)</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem23.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="Reaction-Mechanisms"><a href="#Reaction-Mechanisms" class="headerlink" title="Reaction Mechanisms"></a>Reaction Mechanisms</h2><p><strong>Reaction Mechanisms:</strong></p><p>Reactions can be classified as being either simple or complex. A complex reaction consists of a number of steps. Each of these steps involves one collision and is known as an elementary step. A simple reaction consists of one elementary step. The step or series of steps that make up a reaction is known as the mechanism of that reaction. From a reaction equation it is not possible to determine if it is simple or complex.</p><p><strong><em>Rate Determining Step:</em></strong></p><p>Every mechanism has a rate-determining step. This is the <strong>slowest step</strong> in the reaction. If the first elementary step of the mechanism is the rate-determining step, then we can say that the overall reaction rate depends on this initial step and on the concentrations of the species involved in this step. Any subsequent step is faster and does not affect the overall rate.</p><div class="table-container"><table><thead><tr><th>Elementary step</th><th>Elementary step</th></tr></thead><tbody><tr><td>A → products</td><td>Rate = k[A]</td></tr><tr><td>A + A → products</td><td>Rate = k[A]<sup>2</sup></td></tr><tr><td>A + B → products</td><td>Rate = k[A][B]</td></tr></tbody></table></div><h1 id="Unit-2-Atomic-Structure"><a href="#Unit-2-Atomic-Structure" class="headerlink" title="Unit 2|Atomic Structure"></a>Unit 2|Atomic Structure</h1><details> <summary>course pack|Part 1</summary><div class="row"><iframe src="https://drive.google.com/file/d/1yfdNaXFm54y_Px4nVGoJkKy6YcMMxjnn/preview" style="width:100%; height:550px"></iframe></div></details><details> <summary>course pack|Part 2</summary><div class="row"><iframe src="https://drive.google.com/file/d/1nkM79KGTwcToKF9Ld9YBDnTvmjfgGjNv/preview" style="width:100%; height:550px"></iframe></div></details><h2 id="Orbital-Shapes"><a href="#Orbital-Shapes" class="headerlink" title="Orbital Shapes"></a>Orbital Shapes</h2><p>The shapes of the orbitals are determined by the angular momentum<br>quantum number l and the corresponding letter designations s, p, d and f.</p><p><img src="https://study.com/cimages/videopreview/videopreview-full/screen_shot_2015-11-23_at_8.49.38_am_117391.jpg" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="Electron-Configurations"><a href="#Electron-Configurations" class="headerlink" title="Electron Configurations"></a>Electron Configurations</h2><p><img src="https://ktharpesaachemistry.weebly.com/uploads/2/2/9/5/22951434/5168270_orig.gif" srcset="/img/loading.gif" lazyload alt=""></p><p>Ex: <sub>32</sub>Ge</p><p>1s<sup>2</sup>2s<sup>2</sup>2p<sup>6</sup>3s<sup>2</sup>3p<sup>6</sup>4s<sup>2</sup>3d<sup>10</sup>4p<sup>2</sup>(filling order) is arranged to<br>1s<sup>2</sup>2s<sup>2</sup>2p<sup>6</sup>3s<sup>2</sup>3p<sup>6</sup>3d<sup>10</sup>4s<sup>2</sup>4p<sup>2</sup>(shell order)</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem24.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="Methods-of-Expressing-Electron-Configuration"><a href="#Methods-of-Expressing-Electron-Configuration" class="headerlink" title="Methods of Expressing Electron Configuration"></a>Methods of Expressing Electron Configuration</h2><h3 id="1-filling-order"><a href="#1-filling-order" class="headerlink" title="1) filling order"></a>1) filling order</h3><p>Ex: <sub>32</sub>Ge</p><p>1s<sup>2</sup>2s<sup>2</sup>2p<sup>6</sup>3s<sup>2</sup>3p<sup>6</sup>4s<sup>2</sup>3d<sup>10</sup>4p<sup>2</sup></p><h3 id="2-shorthand-electron-configuration"><a href="#2-shorthand-electron-configuration" class="headerlink" title="2) shorthand electron configuration"></a>2) shorthand electron configuration</h3><p>Ex: <sub>32</sub>Ge</p><p>[K] 4s<sup>2</sup>3d<sup>10</sup>4p<sup>2</sup></p><h3 id="3-orbital-diagram"><a href="#3-orbital-diagram" class="headerlink" title="3) orbital diagram"></a>3) orbital diagram</h3><p>Ex: <sub>32</sub>Ge</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem26.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="Orbital-Filling-Irregularities"><a href="#Orbital-Filling-Irregularities" class="headerlink" title="Orbital Filling Irregularities"></a>Orbital Filling Irregularities</h2><p>Since he energy levels of some orbitals are so close there are irregularities in the order of electron filling. For example with the transition metals Cr and Cu the decrease in energy from having an orbital with unpaired spins causes an unusually order of filling.</p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/note/RHHS/chem/chem25.png" srcset="/img/loading.gif" lazyload alt=""></p><details> <summary>之后的单元</summary># Unit 3|Equilibrum/# Unit 4|Electrochemistry/# Unit 5|Organic/</details>]]></content>
<categories>
<category>RHHS</category>
</categories>
</entry>
<entry>
<title>好用的油猴脚本推荐|持续更新</title>
<link href="/post/17599/"/>
<url>/post/17599/</url>
<content type="html"><![CDATA[<p>惊闻Edge出了新版,火速去试了试,没想到比safari和chrome好用了不止一点。立马转战Edge。重新下插件的时候正好又看了看油猴脚本,就想着最近反正也不咋更新了,要不就出一期油猴脚本的推荐(会持续更新)。</p><p><del>因为到现在百度还没收录我的网址,所以这次就不迫害百度了。</del></p><h1 id="一、Search-By-Image"><a href="#一、Search-By-Image" class="headerlink" title="一、Search By Image"></a>一、Search By Image</h1><p><a href="https://greasyfork.org/zh-CN/scripts/2998-search-by-image">Search By Image</a></p><p>以图搜图</p><p>按住ctrl键,同时点击右键,即可选择要用的搜图引擎。</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/tampermonkey/1.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="二、搜索引擎快捷跳转"><a href="#二、搜索引擎快捷跳转" class="headerlink" title="二、搜索引擎快捷跳转"></a>二、搜索引擎快捷跳转</h1><p><a href="https://greasyfork.org/zh-CN/scripts/27752-searchenginejump-%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E5%BF%AB%E6%8D%B7%E8%B7%B3%E8%BD%AC">searchEngineJump 搜索引擎快捷跳转</a></p><p>在网站的搜索框下面会出现一栏选择网站的地方,当你在某个网站搜不到你想要的东西,可以非常快速地切换搜索源,very 的 good。</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/tampermonkey/2.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="三、解除B站区域限制(不能用惹)"><a href="#三、解除B站区域限制(不能用惹)" class="headerlink" title="三、解除B站区域限制(不能用惹)"></a>三、<del>解除B站区域限制</del>(不能用惹)</h1><p><a href="https://greasyfork.org/zh-CN/scripts/25718-%E8%A7%A3%E9%99%A4b%E7%AB%99%E5%8C%BA%E5%9F%9F%E9%99%90%E5%88%B6">解除B站区域限制</a></p><p><del>这个脚本真的强</del></p><p>它是通过调用了 <a href="https://www.biliplus.com/">BiliPlus</a> 的API实现的,而非VPN或其他翻墙技术,所以适用于任何锁区(包括海外用户观看番剧时的锁区以及仅限港澳台的番剧)。</p><p><del>顺便推荐一下这图上的番,很好看!</del></p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/tampermonkey/4.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="四、Bilibili-Evolved"><a href="#四、Bilibili-Evolved" class="headerlink" title="四、Bilibili Evolved"></a>四、Bilibili Evolved</h1><p><a href="https://greasyfork.org/zh-CN/scripts/373563-bilibili-evolved">Bilibili Evolved</a></p><p>强大的哔哩哔哩增强脚本: 下载视频, 音乐, 封面, 弹幕 / 简化直播间, 评论区, 首页 / 自定义顶栏, 删除广告, 夜间模式 / 触屏设备支持等<del>(这段我直接复制他们简介的哈哈,因为强得不需多言)</del></p><p>点击网页左侧的悬浮球就可以操作了</p><p>p.s 当然,能下载的视频只能是你有权限观看的,如你不是大会员的话就不能下载需要大会员的视频,不在区域内的话,就不能下载锁区的视频(上面的解锁区域限制没用,开VPN可以)</p><p>p.p.s下载弹幕的话,要自己把txt的后缀改成xml或者ass</p><p>p.p.p.s下载的视频没经过原作者同意别乱传播啊,支持原创</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/tampermonkey/5.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="五、网页限制解除-改"><a href="#五、网页限制解除-改" class="headerlink" title="五、网页限制解除(改)"></a>五、网页限制解除(改)</h1><p><a href="https://greasyfork.org/zh-CN/scripts/28497-remove-web-limits-modified">网页限制解除(改)</a></p><p>有时候想从一篇文章里复制一段链接的时候,猛然发现这个网页限制了你复制的权限,然后你就得找个软件识别文字或者干脆一个字一个字地把那段很长的链接抄下来,非常麻烦。这个脚本就可以解决这种问题。<del>我这段介绍好像手工耿哈哈哈哈</del></p><p>把鼠标移到网页的最左边的上边一带的位置找一找,开关就会显示出来,点那个白色的小方块就可以开启插件了。</p><p>p.s 不要把它用来剽窃什么的啊,韩信带净化,支持原创</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/tampermonkey/3.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="六、能不能好好说话?"><a href="#六、能不能好好说话?" class="headerlink" title="六、能不能好好说话?"></a>六、能不能好好说话?</h1><p><a href="https://greasyfork.org/zh-CN/scripts/398555-%E8%83%BD%E4%B8%8D%E8%83%BD%E5%A5%BD%E5%A5%BD%E8%AF%B4%E8%AF%9D">能不能好好说话?</a></p><p>当在某些社交网站有看不懂的缩写时,划词,词的解释就会出现在网页的左上角。支持百度贴吧、bilibili和微博等。</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/tampermonkey/6.png" srcset="/img/loading.gif" lazyload alt=""></p><p>之前玩过它的 <a href="https://lab.magiconch.com/nbnhhsh/">网页版本</a>,脚本不支持的网页可以手动去这个网站上翻译</p><p><del>妈妈再也不用担心我聊天聊到一半打开百度去搜缩写啦</del></p><p> 本站也添加了它的脚本,不信你可以试试:qnmd</p><h1 id="七、Open-the-F-king-URL-Right-Now"><a href="#七、Open-the-F-king-URL-Right-Now" class="headerlink" title="七、Open the F**king URL Right Now"></a>七、Open the F**king URL Right Now</h1><p><a href="https://greasyfork.org/en/scripts/412612-open-the-f-king-url-right-now">Open the F**king URL Right Now</a></p><p>这个插件的名字非常儒雅啊草</p><p>对于很多平时不怎么用手机,用电脑比较多的人来说应该深有体会啊!现在的很多网站为了延长用户的停留时长无所不用其极,打开外链的时候tm分好几个步骤。<span class="heimu" title="你知道的太多了">简书,说的就是你!</span></p><p><img src="https://cdn.jsdelivr.net/gh/Trotyl15/blogImg/img/blog/img/note/tampermonkey/7.png" srcset="/img/loading.gif" lazyload alt=""></p><p>知乎其实还行,只要再点一下 <del>全靠同行衬托</del></p><hr><h1 id="后言"><a href="#后言" class="headerlink" title="后言"></a>后言</h1><p>因为我用的插件蛮多的,懒得都写,所以这里就推荐几个我认为比较好用和不磕碜的<del>懂得都懂</del>。</p><p>有别的推荐给我,或者疑问也可以留言告诉我。</p><p>有空的话可能写一个Edge插件的推荐,不过也不知道有没有人看,没人看就不想写了。。有人看请务必告诉我!!!<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/emoji/tieba-20.png" srcset="/img/loading.gif" lazyload alt=""></p>]]></content>
<categories>
<category>好用的xx推荐</category>
</categories>
<tags>
<tag>Tampermonkey</tag>
</tags>
</entry>
<entry>
<title>图|Graph</title>
<link href="/post/10412/"/>
<url>/post/10412/</url>
<content type="html"><![CDATA[<p>这是在看b站上的韩顺平老师的数据结构与算法<sup id="fnref:1" class="footnote-ref"><a href="#fn:1" rel="footnote"><span class="hint--top hint--rounded" aria-label="尚硅谷Java数据结构与java算法,韩顺平数据结构与算法">[1]</span></a></sup>时做的笔记。等我把后面的都更新完了以后会陆续把前面的补上。</p><hr><h1 id="一、基本介绍"><a href="#一、基本介绍" class="headerlink" title="一、基本介绍"></a>一、基本介绍</h1><h2 id="为什么要有图"><a href="#为什么要有图" class="headerlink" title="为什么要有图"></a>为什么要有图</h2><ol><li>前面我们学了线性表和树</li><li>线性表局限于一个前驱和一个后继的关系</li><li>树也只能有一个直接前驱也就是父结点</li><li>当我们需要表示多对多的关系时,这里我们就用到了图<br>图是一种数据结构,其中结点可以具有零个或者多个相邻元素。两个结点直接的链接称为边。结点也可以称为顶点。如图:<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G1.png" srcset="/img/loading.gif" lazyload alt=""></li></ol><h1 id="二、常用概念"><a href="#二、常用概念" class="headerlink" title="二、常用概念"></a>二、常用概念</h1><p><strong>1) 顶点|vertex</strong></p><p><strong>2) 边|edge</strong></p><p><strong>3) 路径|path</strong></p><p><strong>4)无向图|Undirected Graph(下图)</strong><br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G2.png" srcset="/img/loading.gif" lazyload alt=""></p><p>无向图:顶点之间的链接没有方向,比如A-B,既可以是A→B,也可以是B←A。</p><p>路径:比如D→C的路径有</p><ol><li>D→B→C</li><li>D→A→B→C</li></ol><p><strong>5) 有向图|Directed Graph(下图)</strong><br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G3.png" srcset="/img/loading.gif" lazyload alt=""><br>有向图:顶点之间的链接有方向,比如A-B,只能是A→B,不能是B←A。</p><p><strong>6)带权图|Weighted Graph(下图)</strong><br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G4.png" srcset="/img/loading.gif" lazyload alt=""><br>带权图:这种边带权值的图也叫网</p><h1 id="三、表示方式"><a href="#三、表示方式" class="headerlink" title="三、表示方式"></a>三、表示方式</h1><p>图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)。</p><h2 id="1-邻接矩阵"><a href="#1-邻接矩阵" class="headerlink" title="1. 邻接矩阵"></a>1. 邻接矩阵</h2><p>邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵的row和col表示的是1…n个点。<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G5.png" srcset="/img/loading.gif" lazyload alt=""></p><h2 id="2-邻接表"><a href="#2-邻接表" class="headerlink" title="2. 邻接表"></a>2. 邻接表</h2><p>1)邻接矩阵需要为每个顶点都分配n个边的空间,其实有很多边都是不存在,会造成空间的一定损失。</p><p>2)邻接表的实现只关心存在的边,不关心不存在的边。因此没有空间浪费,邻接表由数组+链表组成。<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G6.png" srcset="/img/loading.gif" lazyload alt=""></p><p><strong>说明:</strong></p><ol><li>标号为0的结点的相关联的结点为 1 2 3 4</li><li>标号为1的结点的相关联结点为0 4,</li><li>标号为2的结点相关联的结点为 0 4 5</li><li>….</li></ol><h1 id="四、快速入门案例"><a href="#四、快速入门案例" class="headerlink" title="四、快速入门案例"></a>四、快速入门案例</h1><h2 id="1-要求"><a href="#1-要求" class="headerlink" title="1. 要求"></a>1. 要求</h2><p>代码实现如下图结构。<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G2.png" srcset="/img/loading.gif" lazyload alt=""></p><figure class="highlight tap"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs tap"> A B C D E<br>A<span class="hljs-number"> 0 </span>1<span class="hljs-number"> 1 </span>0 0<br>B<span class="hljs-number"> 1 </span>0<span class="hljs-number"> 1 </span>1 1<br>C<span class="hljs-number"> 1 </span>1<span class="hljs-number"> 0 </span>0 0<br>D<span class="hljs-number"> 0 </span>1<span class="hljs-number"> 0 </span>0 0<br>E<span class="hljs-number"> 0 </span>1<span class="hljs-number"> 0 </span>0 0<br><br>//说明<br>//(1)1表示能直接链接<br>//(2)0表示不能直接链接<br><br></code></pre></td></tr></table></figure><h2 id="2-思路分析"><a href="#2-思路分析" class="headerlink" title="2. 思路分析"></a>2. 思路分析</h2><ol><li>存储顶点 String 使用 ArrayList</li><li>保存 int[][] edges</li></ol><h2 id="3-代码实现"><a href="#3-代码实现" class="headerlink" title="3.代码实现"></a>3.代码实现</h2><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br></pre></td><td class="code"><pre><code class="hljs arduino"><span class="hljs-keyword">import</span> java.util.ArrayList;<br><span class="hljs-keyword">import</span> java.util.Arrays;<br><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Graph</span> {</span><br><br><span class="hljs-keyword">private</span> ArrayList<<span class="hljs-keyword">String</span>> vertexList;<br><span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span>[][] edges;<br><span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> numOfEdges;<br><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(<span class="hljs-keyword">String</span>[] args)</span> </span>{<br><span class="hljs-keyword">int</span> n = <span class="hljs-number">5</span>;<span class="hljs-comment">// number of nodes</span><br><span class="hljs-keyword">String</span> vertices[] = { <span class="hljs-string">"A"</span>, <span class="hljs-string">"B"</span>, <span class="hljs-string">"C"</span>, <span class="hljs-string">"D"</span>, <span class="hljs-string">"E"</span> };<br>Graph graph = <span class="hljs-keyword">new</span> Graph(n);<br><span class="hljs-comment">// add nodes</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">String</span> vertex : vertices) {<br>graph.insertVertex(vertex);<br>}<br><span class="hljs-comment">// add edges</span><br><span class="hljs-comment">// A-B A-C B-C B-D B-E</span><br>graph.insertEdge(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>);<br>graph.insertEdge(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>);<br>graph.insertEdge(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>);<br>graph.insertEdge(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">1</span>);<br>graph.insertEdge(<span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">1</span>);<br><br>graph.showGraph();<br>}<br><br><span class="hljs-comment">// constructor</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Graph</span><span class="hljs-params">(<span class="hljs-keyword">int</span> n)</span> </span>{<br>edges = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[n][n];<br>vertexList = <span class="hljs-keyword">new</span> ArrayList<<span class="hljs-keyword">String</span>>(n);<br>numOfEdges = <span class="hljs-number">0</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showGraph</span><span class="hljs-params">()</span> </span>{<br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span>[] link : edges) {<br>System.out.<span class="hljs-built_in">println</span>(Arrays.toString(link));<br>}<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getNumOfVertex</span><span class="hljs-params">()</span> </span>{<br><span class="hljs-keyword">return</span> vertexList.<span class="hljs-built_in">size</span>();<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getNumOfEdges</span><span class="hljs-params">()</span> </span>{<br><span class="hljs-keyword">return</span> numOfEdges;<br>}<br><br><span class="hljs-comment">// 返回下标对应的数据 0->“A”</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">String</span> <span class="hljs-title">getValueByIndex</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i)</span> </span>{<br><span class="hljs-keyword">return</span> vertexList.<span class="hljs-built_in">get</span>(i);<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getWeight</span><span class="hljs-params">(<span class="hljs-keyword">int</span> v1, <span class="hljs-keyword">int</span> v2)</span> </span>{<br><span class="hljs-keyword">return</span> edges[v1][v2];<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">insertVertex</span><span class="hljs-params">(<span class="hljs-keyword">String</span> vertex)</span> </span>{<br>vertexList.add(vertex);<br>}<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * </span><br><span class="hljs-comment"> * @param v1 点的下标,以及是第几个顶点 “A”-“B” “A”->0 “B”->1</span><br><span class="hljs-comment"> * @param v2 第二个顶点对应的下标</span><br><span class="hljs-comment"> * @param weight 权值</span><br><span class="hljs-comment"> */</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">insertEdge</span><span class="hljs-params">(<span class="hljs-keyword">int</span> v1, <span class="hljs-keyword">int</span> v2, <span class="hljs-keyword">int</span> weight)</span> </span>{<br>edges[v1][v2] = weight;<br>edges[v2][v1] = weight;<br>}<br><br>}<br></code></pre></td></tr></table></figure><h3 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h3><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs json">[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]<br>[<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>]<br>[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]<br>[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]<br>[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]<br></code></pre></td></tr></table></figure><h1 id="五、图的遍历"><a href="#五、图的遍历" class="headerlink" title="五、图的遍历"></a>五、图的遍历</h1><p>所谓图的遍历,既是对结点的访问。一个图有那么多结点,如何遍历这些结点,需要特定策略,一般有两种访问策略:</p><ul><li>深度优先遍历|Depth First Search</li><li>广度优先遍历|Broad First Search</li></ul><h2 id="深度优先遍历|DFS"><a href="#深度优先遍历|DFS" class="headerlink" title="深度优先遍历|DFS"></a>深度优先遍历|DFS</h2><h3 id="1-基本思想"><a href="#1-基本思想" class="headerlink" title="1. 基本思想"></a>1. 基本思想</h3><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G7.gif" srcset="/img/loading.gif" lazyload alt=""><br>图的深度优先搜索</p><ol><li>深度优先遍历,从初始访问结点出发,初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接结点, 可以这样理解:每次都在访问完<strong>当前结点</strong>后首先访问<strong>当前结点的第一个邻接结点</strong>。</li><li>我们可以看到,这样的访问策略是优先往纵向挖掘深入,而不是对一个结点的所有邻接结点进行横向访问。</li><li>显然,深度优先搜索是一个递归的过程</li></ol><h3 id="2-算法步骤"><a href="#2-算法步骤" class="headerlink" title="2. 算法步骤"></a>2. 算法步骤</h3><ol><li>访问初始结点v,并标记结点v为已访问。</li><li>查找结点v的第一个邻接结点w。</li><li>若w存在,则继续执行4,如果w不存在,则回到第1步,将从v的下一个结点继续。</li><li>若w未被访问,对w进行深度优先遍历递归(即把w当做另一个v,然后进行步骤123)。</li><li>查找结点v的w邻接结点的下一个邻接结点,转到步骤3。 </li></ol><h3 id="3-代码实现-1"><a href="#3-代码实现-1" class="headerlink" title="3.代码实现"></a>3.代码实现</h3><h4 id="添加代码"><a href="#添加代码" class="headerlink" title="添加代码"></a>添加代码</h4><figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs angelscript"><span class="hljs-keyword">private</span> <span class="hljs-built_in">bool</span>ean[] isVisited;<br></code></pre></td></tr></table></figure><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs arduino"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * </span><br><span class="hljs-comment"> * @param index</span><br><span class="hljs-comment"> * @return 如果存在就返回对应的下标,否则返回-1</span><br><span class="hljs-comment"> */</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getFirstNeighbor</span><span class="hljs-params">(<span class="hljs-keyword">int</span> index)</span> </span>{<br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j < vertexList.<span class="hljs-built_in">size</span>(); j++) {<br><span class="hljs-keyword">if</span> (edges[index][j] > <span class="hljs-number">0</span>) {<br><span class="hljs-keyword">return</span> j;<br>}<br>}<br><span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;<br>}<br></code></pre></td></tr></table></figure><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs arduino"><span class="hljs-comment">// 根据前一个邻接结点的下标来获取下一个邻接结点</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getNextNeighbor</span><span class="hljs-params">(<span class="hljs-keyword">int</span> v1, <span class="hljs-keyword">int</span> v2)</span> </span>{<br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = v2 + <span class="hljs-number">1</span>; j < vertexList.<span class="hljs-built_in">size</span>(); j++) {<br><span class="hljs-keyword">if</span> (edges[v2][j] > <span class="hljs-number">0</span>) {<br><span class="hljs-keyword">return</span> j;<br>}<br>}<br><span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;<br>}<br></code></pre></td></tr></table></figure><figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs reasonml"><span class="hljs-comment">// DFS</span><br><span class="hljs-keyword">private</span> void dfs(boolean<span class="hljs-literal">[]</span> isVisited, <span class="hljs-built_in">int</span> i) {<br><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.print(get<span class="hljs-constructor">ValueByIndex(<span class="hljs-params">i</span>)</span> + <span class="hljs-string">"->"</span>);<br>isVisited<span class="hljs-literal">[<span class="hljs-identifier">i</span>]</span> = <span class="hljs-literal">true</span>;<br><span class="hljs-built_in">int</span> w = get<span class="hljs-constructor">FirstNeighbor(<span class="hljs-params">i</span>)</span>;<br><span class="hljs-keyword">while</span> (w != -<span class="hljs-number">1</span>) {<br><span class="hljs-keyword">if</span> (!isVisited<span class="hljs-literal">[<span class="hljs-identifier">w</span>]</span>) {<br>dfs(isVisited, w);<br>}<br>w = get<span class="hljs-constructor">NextNeighbor(<span class="hljs-params">i</span>, <span class="hljs-params">w</span>)</span>;<br>}<br>}<br></code></pre></td></tr></table></figure><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// 对dfs进行重载,因为要考虑不联通图的情况</span><br><span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">dfs</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">for</span> (int i = <span class="hljs-number">0</span>; i < getNumOfVertex(); i++) {<br><span class="hljs-keyword">if</span> (!isVisited[i]) {<br>dfs(isVisited, i);<br>}<br>}<br>}<br></code></pre></td></tr></table></figure><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs elixir">System.out.println(<span class="hljs-string">"DFS:"</span>);<br>graph.dfs();<span class="hljs-regexp">//</span> A->B->C->D->E<br></code></pre></td></tr></table></figure><h4 id="运行结果-1"><a href="#运行结果-1" class="headerlink" title="运行结果"></a>运行结果</h4><figure class="highlight accesslog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs accesslog"><span class="hljs-string">[0, 1, 1, 0, 0]</span><br><span class="hljs-string">[1, 0, 1, 1, 1]</span><br><span class="hljs-string">[1, 1, 0, 0, 0]</span><br><span class="hljs-string">[0, 1, 0, 0, 0]</span><br><span class="hljs-string">[0, 1, 0, 0, 0]</span><br>DFS:<br>A->B->C->D->E-><br></code></pre></td></tr></table></figure><h2 id="广度优先遍历|BFS"><a href="#广度优先遍历|BFS" class="headerlink" title="广度优先遍历|BFS"></a>广度优先遍历|BFS</h2><h3 id="1-基本思想-1"><a href="#1-基本思想-1" class="headerlink" title="1. 基本思想"></a>1. 基本思想</h3><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G8.gif" srcset="/img/loading.gif" lazyload alt=""><br>图的广度优先搜索</p><p>类似于一个分层搜索的过程,广度优先遍历需要使用一个队列保持访问过的结点的顺序,以便按照这个顺序来访问这些结点的邻接结点。</p><h3 id="2-算法步骤-1"><a href="#2-算法步骤-1" class="headerlink" title="2. 算法步骤"></a>2. 算法步骤</h3><ol><li>访问初始结点v并标记结点v为已访问。</li><li>结点v入队列</li><li>当队列非空时,继续执行,否则算法结束。</li><li>出队列,取得队头结点u。</li><li>查找结点u的第一个邻接结点w。</li><li>若结点u的邻接结点w不存在,则转到步骤3;否则循环执行以下三个步骤:<ol><li>若结点w尚未被访问,则访问结点w并标记为已访问。 </li><li>结点w入队列 </li><li>查找结点u的继w邻接结点后的下一个邻接结点w,转到步骤6。<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/G9.gif" srcset="/img/loading.gif" lazyload alt=""></li></ol></li></ol><h3 id="3-代码实现-2"><a href="#3-代码实现-2" class="headerlink" title="3. 代码实现"></a>3. 代码实现</h3><h4 id="添加代码-1"><a href="#添加代码-1" class="headerlink" title="添加代码"></a>添加代码</h4><figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs reasonml"><span class="hljs-keyword">private</span> void bfs(boolean<span class="hljs-literal">[]</span> isVisited, <span class="hljs-built_in">int</span> i) {<br><span class="hljs-built_in">int</span> u;<span class="hljs-comment">// head node's index</span><br><span class="hljs-built_in">int</span> w;<br>LinkedList queue = <span class="hljs-keyword">new</span> <span class="hljs-constructor">LinkedList()</span>;<br><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.print(get<span class="hljs-constructor">ValueByIndex(<span class="hljs-params">i</span>)</span> + <span class="hljs-string">"->"</span>);<br>isVisited<span class="hljs-literal">[<span class="hljs-identifier">i</span>]</span> = <span class="hljs-literal">true</span>;<br>queue.add<span class="hljs-constructor">Last(<span class="hljs-params">i</span>)</span>;<br><span class="hljs-keyword">while</span> (!queue.is<span class="hljs-constructor">Empty()</span>) {<br>u = (Integer) queue.remove<span class="hljs-constructor">First()</span>;<br>w = get<span class="hljs-constructor">FirstNeighbor(<span class="hljs-params">u</span>)</span>;<br><span class="hljs-keyword">while</span> (w != -<span class="hljs-number">1</span>) {<br><span class="hljs-keyword">if</span> (!isVisited<span class="hljs-literal">[<span class="hljs-identifier">w</span>]</span>) {<br><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">System</span>.</span></span>out.print(get<span class="hljs-constructor">ValueByIndex(<span class="hljs-params">w</span>)</span> + <span class="hljs-string">"->"</span>);<br>isVisited<span class="hljs-literal">[<span class="hljs-identifier">w</span>]</span> = <span class="hljs-literal">true</span>;<br>queue.add<span class="hljs-constructor">Last(<span class="hljs-params">w</span>)</span>;<br>}<br>w = get<span class="hljs-constructor">NextNeighbor(<span class="hljs-params">u</span>, <span class="hljs-params">w</span>)</span>;<br>}<br>}<br>}<br></code></pre></td></tr></table></figure><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">bfs</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">for</span> (int i = <span class="hljs-number">0</span>; i < getNumOfVertex(); i++) {<br><span class="hljs-keyword">if</span> (!isVisited[i]) {<br>bfs(isVisited, i);<br>}<br>}<br>}<br></code></pre></td></tr></table></figure><h4 id="运行结果-2"><a href="#运行结果-2" class="headerlink" title="运行结果"></a>运行结果</h4><figure class="highlight accesslog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs accesslog"><span class="hljs-string">[0, 1, 1, 0, 0]</span><br><span class="hljs-string">[1, 0, 1, 1, 1]</span><br><span class="hljs-string">[1, 1, 0, 0, 0]</span><br><span class="hljs-string">[0, 1, 0, 0, 0]</span><br><span class="hljs-string">[0, 1, 0, 0, 0]</span><br>BFS:<br>A->B->C->D->E-><br></code></pre></td></tr></table></figure><hr><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><section class="footnotes"><div class="footnote-list"><ol><li><span id="fn:1" class="footnote-text"><span><a href="https://www.bilibili.com/video/BV1E4411H73v?p=146">尚硅谷Java数据结构与java算法,韩顺平数据结构与算法</a><a href="#fnref:1" rev="footnote" class="footnote-backref"> ↩</a></span></span></li></ol></div></section>]]></content>
<categories>
<category>数据结构与算法</category>
<category>图</category>
</categories>
<tags>
<tag>java</tag>
</tags>
</entry>
<entry>
<title>多路查找树|Multi-Way Search Tree</title>
<link href="/post/35477/"/>
<url>/post/35477/</url>
<content type="html"><![CDATA[<p>这是在看b站上的韩顺平老师的数据结构与算法<sup id="fnref:1" class="footnote-ref"><a href="#fn:1" rel="footnote"><span class="hint--top hint--rounded" aria-label="尚硅谷Java数据结构与java算法,韩顺平数据结构与算法">[1]</span></a></sup>时做的笔记。等我把后面的都更新完了以后会陆续把前面的补上。</p><hr><h1 id="一、二叉树的问题分析"><a href="#一、二叉树的问题分析" class="headerlink" title="一、二叉树的问题分析"></a>一、二叉树的问题分析</h1><p>二叉树的操作效率较高,但是也存在在一些问题,请看下面的二叉树<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT1.png" srcset="/img/loading.gif" lazyload alt=""></p><ul><li>这是一颗 满二叉树,即它的高度有: $2^n-1 → 2^{5}-1→31$</li><li>二叉树需要加载到内存,如果二叉树的结点少,没有问题,但是如果二叉树的结点很多(比如1亿),就存在如下问题:</li></ul><ol><li>在构建二叉树时,需要多次进行i/o操作(海量数据存在数据库或文件中),结点海量,构建二叉树时,速度有影响</li><li>结点海量,也会造成二叉树的高度很大,会降低操作速度</li></ol><h1 id="二、基本介绍"><a href="#二、基本介绍" class="headerlink" title="二、基本介绍"></a>二、基本介绍</h1><h2 id="1-多叉树"><a href="#1-多叉树" class="headerlink" title="1. 多叉树"></a>1. 多叉树</h2><ol><li>在二叉树中,每个结点有数据项,最多两个子结点。如果允许每个结点可以有更多的数据项和更多的子结点,就是多叉树(multiway tree)</li><li>后面的2-3树,2-3-4树就是多叉树,多叉树通过重新组织结点,减少书的高度,能对二叉树进行优化</li><li>举例说明(下面2-3树就是一颗多叉树):<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT2.png" srcset="/img/loading.gif" lazyload alt=""></li></ol><h2 id="2-B树"><a href="#2-B树" class="headerlink" title="2. B树"></a>2. B树</h2><p>B树通过重新组织结点,降低树的高度,并且减少i/o读写次数来提升效率<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT3.png" srcset="/img/loading.gif" lazyload alt=""></p><ol><li>如图B树通过重新组织结点,降低了树的高度</li><li>文件系统及数据库系统的设计者利用了磁盘预读原理,将一个结点的大小设为等于一个页(页的大小通常为4k),这样每个结点只需要一次i/o就可以完全载入</li><li>将树的度M设置为1024,在600亿个元素中最多只需要4次i/o操作就可以读取到想要的元素。B树(B+)利用这个特性,广泛地应用于文件存储系统以及数据库系统中</li></ol><ul><li>结点的度 指的是一个结点下面子结点的个数</li><li>树的度 指的是一个树里最大的结点的度的值</li></ul><h2 id="3-2-3树"><a href="#3-2-3树" class="headerlink" title="3. 2-3树"></a>3. 2-3树</h2><p>2-3树是最简单的B树结构,具有如下特点:</p><ol><li>2-3树的所以叶子结点都在同一层。(只要是B树都满足这个条件)</li><li>有两个子结点的结点叫二结点,二结点要么没有子结点,要么有两个子结点,不能只有一个子结点。</li><li>有三个子结点的结点叫三结点,三结点要么没有子结点,要么有三个子结点,不能只有有一个或两个子结点。</li><li>2-3树是由二结点和三结点构成的树。</li></ol><h1 id="三、应用案例"><a href="#三、应用案例" class="headerlink" title="三、应用案例"></a>三、应用案例</h1><p>将数列 {16, 24, 12, 32, 14, 26, 34, 10, 8, 28, 38, 20} 构建成 2-3 树,并保证数据插入的大小顺序。(演示一下构建 2-3<br>树的过程.)</p><p><strong>插入规则:</strong></p><ol><li>2-3 树的所有叶子节点都在同一层.(只要是 B 树都满足这个条件)</li><li>有两个子节点的节点叫二节点,二节点要么没有子节点,要么有两个子节点.</li><li>有三个子节点的节点叫三节点,三节点要么没有子节点,要么有三个子节点</li><li>当按照规则插入一个数到某个节点时,不能满足上面三个要求,就需要拆,先向上拆,如果上层满,则拆本层,拆后仍然需要满足上面 3 个条件。</li><li>对于三节点的子树的值大小仍然遵守(BST 二叉排序树)的规则<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT4.png" srcset="/img/loading.gif" lazyload alt=""></li></ol><p>用<a href="https://www.cs.usfca.edu/~galles/visualization/BTree.html">这个网站</a>画的,<del>但是感觉这网站画出来的有亿丝丑。。。泪目</del></p><h1 id="四、其他说明"><a href="#四、其他说明" class="headerlink" title="四、其他说明"></a>四、其他说明</h1><p>除了2-3树,还有2-3-4树等,概念和2-3树类似,也是一种B树。如图:<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT5.png" srcset="/img/loading.gif" lazyload alt=""></p><h1 id="五、B树、B-树-和-B-树"><a href="#五、B树、B-树-和-B-树" class="headerlink" title="五、B树、B+树 和 B*树"></a>五、B树、B+树 和 B*树</h1><h2 id="1-B树的介绍"><a href="#1-B树的介绍" class="headerlink" title="1. B树的介绍"></a>1. B树的介绍</h2><p>B-树即B树,B即Balanced,平衡的意思。有人把B-tree翻译成B-树,容易让人产生误解。会以为B-树是一种树,而B树又是另一种树。实际上,B-tree就是指的B树。</p><p>前面已经介绍了2-3树和2-3-4树,他们就是B树|B-tree,这里我们再做一个说明,我们在学习Mysql时,经常听到说某种类似的索引时基于B树或者B+树的,如图:<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT7.png" srcset="/img/loading.gif" lazyload alt=""></p><h3 id="B树的说明"><a href="#B树的说明" class="headerlink" title="B树的说明:"></a>B树的说明:</h3><ol><li>B树的阶:节点的最多子节点个数。比如2-3树的阶是3,2-3-4树的阶是4</li><li>B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的子结点;重复,直到所对应的子指针为空,或已经是叶子结点</li><li>关键字集合分布在整颗树中, 即叶子节点和非叶子节点都存放数据.</li><li>搜索有可能在非叶子结点结束</li><li>其搜索性能等价于在关键字全集内做一次二分查找</li></ol><h2 id="2-B-树的介绍"><a href="#2-B-树的介绍" class="headerlink" title="2. B+树的介绍"></a>2. B+树的介绍</h2><p>B+树时B树的变体,也是一种多路搜索树。<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT6.png" srcset="/img/loading.gif" lazyload alt=""></p><h3 id="B-树的说明"><a href="#B-树的说明" class="headerlink" title="B+树的说明:"></a>B+树的说明:</h3><ol><li>B+树的搜索与B树也基本相同,区别是B+树只有达到叶子结点才命中(B树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找</li><li>所有<strong>关键字都出现在叶子结点的链表中</strong>(即数据只能在叶子节点【也叫稠密索引】),且链表中的关键字(数据)恰好是有序的。</li><li>不可能在非叶子结点命中</li><li>非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层</li><li>更适合文件索引系统</li><li>B树和B+树各有自己的应用场景,不能说B+树完全比B树好,反之亦然.</li></ol><h2 id="3-B-树的介绍"><a href="#3-B-树的介绍" class="headerlink" title="3. B*树的介绍"></a>3. B*树的介绍</h2><p>B*树是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针。<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BT8.png" srcset="/img/loading.gif" lazyload alt=""></p><h3 id="B-树的说明-1"><a href="#B-树的说明-1" class="headerlink" title="B*树的说明:"></a>B*树的说明:</h3><ol><li>B*树定义了非叶子结点关键字个数至少为(2/3)×M,即块的最低使用率为2/3,而B+树的块的最低使用率为B+树的1/2。</li><li>从第1个特点我们可以看出,B*树分配新结点的概率比B+树要低,空间使用率更高.</li></ol><hr><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><section class="footnotes"><div class="footnote-list"><ol><li><span id="fn:1" class="footnote-text"><span><a href="https://www.bilibili.com/video/BV1E4411H73v?p=142">尚硅谷Java数据结构与java算法,韩顺平数据结构与算法</a><a href="#fnref:1" rev="footnote" class="footnote-backref"> ↩</a></span></span></li></ol></div></section>]]></content>
<categories>
<category>数据结构与算法</category>
<category>多路查找树</category>
</categories>
<tags>
<tag>java</tag>
</tags>
</entry>
<entry>
<title>平衡二叉树|AVL Tree</title>
<link href="/post/8178/"/>
<url>/post/8178/</url>
<content type="html"><![CDATA[<p>这是在看b站上的韩顺平老师的数据结构与算法<sup id="fnref:1" class="footnote-ref"><a href="#fn:1" rel="footnote"><span class="hint--top hint--rounded" aria-label="尚硅谷Java数据结构与java算法,韩顺平数据结构与算法">[1]</span></a></sup>时做的笔记。等我把后面的都更新完了以后会陆续把前面的补上。</p><hr><h1 id="一、实际案例"><a href="#一、实际案例" class="headerlink" title="一、实际案例"></a>一、实际案例</h1><p>给你一个数列 {1, 2, 3, 4, 5, 6},要求创建一颗二叉排序树(BST),并分析问题所在。<br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/AVL1.png" srcset="/img/loading.gif" lazyload alt=""></p><p><strong>问题分析:</strong></p><ol><li>左子树全部为空,从形式上看,更像一个单链表</li><li>插入速度没有影响</li><li>查询速度明显降低(因为需要依次比较),不能发挥BST的优势,因为每次还需要比较左子树,其查询速度比单链表还慢</li><li>解决方案-平衡二叉树(AVL)</li></ol><h1 id="二、基本介绍"><a href="#二、基本介绍" class="headerlink" title="二、基本介绍"></a>二、基本介绍</h1><p>平衡二叉树又称平衡二叉搜索树(Self-balancing binary search tree),是<a href="http://blog.trotyl.xyz/2020/08/07/%E4%BA%8C%E5%8F%89%E6%8E%92%E5%BA%8F%E6%A0%91%EF%BD%9CBinary%20Sort%20Tree/">二叉排序树</a>的一类,又被称为AVL树,可以<strong>保持查询效率</strong>比较高。</p><p>具有一下特点:它是一颗空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL(算法,不是指AVL树)、替罪羊树、Treap、伸展树等。</p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/AVL2.png" srcset="/img/loading.gif" lazyload alt=""><br>上面的三个树只有左边两个是AVL树。</p><h1 id="三、应用案例"><a href="#三、应用案例" class="headerlink" title="三、应用案例"></a>三、应用案例</h1><h2 id="1-单旋转—左旋转"><a href="#1-单旋转—左旋转" class="headerlink" title="1. 单旋转—左旋转"></a>1. 单旋转—左旋转</h2><h3 id="1)要求"><a href="#1)要求" class="headerlink" title="1)要求"></a>1)要求</h3><p>给你一个数列,创建出对应的平衡二叉树 {4, 3, 6, 5, 7, 8}</p><h3 id="2)思路"><a href="#2)思路" class="headerlink" title="2)思路"></a>2)思路</h3><h4 id="问题:"><a href="#问题:" class="headerlink" title="问题:"></a>问题:</h4><p>当插入“8”时<code>rightHeight()-leftHeight()>1</code>成立,此时,不再是一颗AVL树了</p><h4 id="处理过程-进行左旋转:"><a href="#处理过程-进行左旋转:" class="headerlink" title="处理过程-进行左旋转:"></a>处理过程-进行左旋转:</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/AVL4.png" srcset="/img/loading.gif" lazyload alt=""></p><ol><li>创建新的结点,以当前根结点的值</li></ol><p><code>Node newNode = new Node(value);</code></p><ol><li>把新的结点的左子树设置成当前结点的左子树</li></ol><p><code>newNode.left = left;</code></p><ol><li>把新的结点的右子树设置成带你过去结点的右子树的左子树 </li></ol><p><code>newNode.right = right.left;</code></p><ol><li>把当前结点的值替换成右子结点的值</li></ol><p><code>value = right.value;</code></p><ol><li>把当前结点的右子树设置成当前结点右子树的右子树</li></ol><p><code>right = right.right;</code></p><ol><li>把当前结点的左子树(左子结点)设置成新的结点</li></ol><p><code>left = newNode;</code></p><p>原来的那个“6”因为没有任何结点指向它,所以被系统当作垃圾回收掉了</p><h2 id="2-单旋转—右旋转"><a href="#2-单旋转—右旋转" class="headerlink" title="2. 单旋转—右旋转"></a>2. 单旋转—右旋转</h2><h3 id="1)要求-1"><a href="#1)要求-1" class="headerlink" title="1)要求"></a>1)要求</h3><p>给你一个数列,创建出对应的平衡二叉树 {10, 12, 8, 9, 7, 6}</p><h3 id="2)思路-1"><a href="#2)思路-1" class="headerlink" title="2)思路"></a>2)思路</h3><h4 id="问题:-1"><a href="#问题:-1" class="headerlink" title="问题:"></a>问题:</h4><p>当插入“6”时`leftHeight()-rightHeight()>1成立,此时,不再是一颗avl树了</p><h4 id="处理过程-进行右旋转"><a href="#处理过程-进行右旋转" class="headerlink" title="处理过程-进行右旋转"></a>处理过程-进行右旋转</h4><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/AVL5.png" srcset="/img/loading.gif" lazyload alt=""></p><ol><li>创建新的结点,以当前根结点的值</li></ol><p><code>Node newNode = new Node(value);</code></p><ol><li>把新的结点的右子树设置成当前节点的右子树</li></ol><p><code>newNode.right = right;</code></p><ol><li>把新的结点的左子树设置成带你过去结点的左子树的右子树 </li></ol><p><code>newNode.left = left.right;</code></p><ol><li>把当前结点的值替换成左子结点的值</li></ol><p><code>value = left.value;</code></p><ol><li>把当前结点的左子树设置成当前结点左子树的左子树</li></ol><p><code>left = left.left;</code></p><ol><li>把当前结点的右子树(右子结点)设置成新的结点</li></ol><p><code>right = newNode;</code></p><p>原来的那个“8”因为没有任何结点指向它,所以被系统当作垃圾回收掉了</p><h2 id="3-双旋转"><a href="#3-双旋转" class="headerlink" title="3. 双旋转"></a>3. 双旋转</h2><h3 id="1)要求-2"><a href="#1)要求-2" class="headerlink" title="1)要求"></a>1)要求</h3><p>给你一个数列,创建出对应的平衡二叉树 {10, 11, 7, 6, 8, 9}</p><h3 id="2)思路-2"><a href="#2)思路-2" class="headerlink" title="2)思路"></a>2)思路</h3><h4 id="问题:-2"><a href="#问题:-2" class="headerlink" title="问题:"></a>问题:</h4><p>当插入“9”时`leftHeight()-rightHeight()>1成立,此时,不再是一颗avl树了</p><p><strong>运行结果:</strong></p><blockquote><p>树的高度=4<br>左子树的高度=1<br>右子树的高度=3<br>Root=Node [value=7]</p></blockquote><p><strong>问题分析:</strong><br><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/AVL6.png" srcset="/img/loading.gif" lazyload alt=""></p><ol><li>当符合右旋转的条件时</li><li>如果它的左子树的右子树高度大于它的左子树的高度</li><li>需要先对当前这个结点的左结点进行左旋转</li><li>再对当前结点进行右旋转的操作即可</li></ol><h1 id="四、代码实现"><a href="#四、代码实现" class="headerlink" title="四、代码实现"></a>四、代码实现</h1><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AVLTreeDemo</span> </span>{<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">main</span>(<span class="hljs-params"><span class="hljs-built_in">String</span>[] args</span>)</span> {<br>int[] arr = { <span class="hljs-number">10</span>, <span class="hljs-number">11</span>, <span class="hljs-number">7</span>, <span class="hljs-number">6</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span> };<br>AVLTree avlTree = <span class="hljs-keyword">new</span> AVLTree();<br><span class="hljs-keyword">for</span> (int i = <span class="hljs-number">0</span>; i < arr.length; i++) {<br>avlTree.add(<span class="hljs-keyword">new</span> Node(arr[i]));<br>}<br>System.out.println(<span class="hljs-string">"树的高度="</span> + avlTree.getRoot().height());<span class="hljs-comment">//3</span><br>System.out.println(<span class="hljs-string">"左子树的高度="</span> + avlTree.getRoot().leftHeight());<span class="hljs-comment">//2</span><br>System.out.println(<span class="hljs-string">"右子树的高度="</span> + avlTree.getRoot().rightHeight());<span class="hljs-comment">//2</span><br>System.out.println(<span class="hljs-string">"根结点="</span> + avlTree.getRoot());<span class="hljs-comment">//8</span><br>System.out.println(<span class="hljs-string">"根结点的左子结点="</span> + avlTree.getRoot().left);<span class="hljs-comment">//7</span><br>}<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AVLTree</span> </span>{<br><span class="hljs-keyword">private</span> Node root;<br><br><span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">getRoot</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">return</span> root;<br>}<br><br><span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">search</span>(<span class="hljs-params">int value</span>)</span> {<br><span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">return</span> root.search(value);<br>}<br>}<br><br><span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">searchParent</span>(<span class="hljs-params">int value</span>)</span> {<br><span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">return</span> root.searchParent(value);<br>}<br>}<br><br><span class="hljs-keyword">public</span> int <span class="hljs-function"><span class="hljs-title">delRightTreeMin</span>(<span class="hljs-params">Node node</span>)</span> {<br>Node target = node;<br><span class="hljs-keyword">while</span> (target.left != <span class="hljs-literal">null</span>) {<br>target = target.left;<br>}<br><br>delNode(target.value);<br><span class="hljs-keyword">return</span> target.value;<br>}<br><br><span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">delNode</span>(<span class="hljs-params">int value</span>)</span> {<br><span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span>;<br>} <span class="hljs-keyword">else</span> {<br>Node targetNode = search(value);<br><span class="hljs-keyword">if</span> (targetNode == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span>;<br>}<br><span class="hljs-keyword">if</span> (root.left == <span class="hljs-literal">null</span> && root.right == <span class="hljs-literal">null</span>) {<br>root = <span class="hljs-literal">null</span>;<br><span class="hljs-keyword">return</span>;<br>}<br>Node parent = searchParent(value);<br><span class="hljs-keyword">if</span> (targetNode.left == <span class="hljs-literal">null</span> && targetNode.right == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">if</span> (parent.left != <span class="hljs-literal">null</span> && parent.left.value == value) {<br>parent.left = <span class="hljs-literal">null</span>;<br>} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (parent.right != <span class="hljs-literal">null</span> && parent.right.value == value) {<br>parent.right = <span class="hljs-literal">null</span>;<br>}<br>} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (targetNode.left != <span class="hljs-literal">null</span> && targetNode.right != <span class="hljs-literal">null</span>) {<br>int minVal = delRightTreeMin(targetNode.right);<br>targetNode.value = minVal;<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">if</span> (targetNode.left != <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">if</span> (parent != <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">if</span> (parent.left.value == value) {<br>parent.left = targetNode.left;<br>} <span class="hljs-keyword">else</span> {<br>parent.right = targetNode.left;<br>}<br>} <span class="hljs-keyword">else</span> {<br>root = targetNode.left;<br>}<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">if</span> (parent != <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">if</span> (parent.left.value == value) {<br>parent.left = targetNode.right;<br>} <span class="hljs-keyword">else</span> {<br>parent.right = targetNode.right;<br>}<br>} <span class="hljs-keyword">else</span> {<br>root = targetNode.right;<br>}<br>}<br>}<br>}<br>}<br><br><span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">add</span>(<span class="hljs-params">Node node</span>)</span> {<br><span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<span class="hljs-comment">// 如果是空树,直接让root指向node</span><br>root = node;<br>} <span class="hljs-keyword">else</span> {<br>root.add(node);<br>}<br>}<br><br><span class="hljs-comment">// 中序遍历</span><br><span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">infixOrder</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">if</span> (root != <span class="hljs-literal">null</span>) {<br>root.infixOrder();<br>} <span class="hljs-keyword">else</span> {<br>System.out.println(<span class="hljs-string">"Tree is Empty."</span>);<br>}<br>}<br>}<br><br><span class="hljs-comment">//创建Node节点</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{<br>int value;<br>Node left;<br>Node right;<br><br><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-title">Node</span>(<span class="hljs-params">int value</span>)</span> {<br><span class="hljs-built_in">this</span>.value = value;<br>}<br><br><span class="hljs-keyword">public</span> int <span class="hljs-function"><span class="hljs-title">leftHeight</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">if</span> (left == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br><span class="hljs-keyword">return</span> left.height();<br>}<br><br><span class="hljs-keyword">public</span> int <span class="hljs-function"><span class="hljs-title">rightHeight</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">if</span> (right == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br><span class="hljs-keyword">return</span> right.height();<br>}<br><br><span class="hljs-comment">// return Height of this node</span><br><span class="hljs-keyword">public</span> int <span class="hljs-function"><span class="hljs-title">height</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.max(left == <span class="hljs-literal">null</span> ? <span class="hljs-number">0</span> : left.height(), right == <span class="hljs-literal">null</span> ? <span class="hljs-number">0</span> : right.height()) + <span class="hljs-number">1</span>;<br><span class="hljs-comment">// A ? B:C ,意思就是如果A为真执行B,否则执行C</span><br>}<br><br><span class="hljs-comment">// 左旋转</span><br><span class="hljs-keyword">private</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">leftRotate</span>(<span class="hljs-params"></span>)</span> {<br>Node newNode = <span class="hljs-keyword">new</span> Node(value);<br>newNode.left = left;<br>newNode.right = right.left;<br>value = right.value;<br>right = right.right;<br>left = newNode;<br>}<br><br><span class="hljs-comment">// 右旋转</span><br><span class="hljs-keyword">private</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">rightRotate</span>(<span class="hljs-params"></span>)</span> {<br>Node newNode = <span class="hljs-keyword">new</span> Node(value);<br>newNode.right = right;<br>newNode.left = left.right;<br>value = left.value;<br>left = left.left;<br>right = newNode;<br>}<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * </span><br><span class="hljs-comment"> * <span class="hljs-doctag">@param </span>value 希望删除的值</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@return </span>如果找到返回该结点,否则返回null</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">search</span>(<span class="hljs-params">int value</span>)</span> {<br><span class="hljs-keyword">if</span> (value == <span class="hljs-built_in">this</span>.value) {<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;<br>} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value < <span class="hljs-built_in">this</span>.value) {<br><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.left == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>}<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.left.search(value);<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.right == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>}<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.right.search(value);<br>}<br>}<br><br><span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">searchParent</span>(<span class="hljs-params">int value</span>)</span> {<br><span class="hljs-keyword">if</span> ((<span class="hljs-built_in">this</span>.left != <span class="hljs-literal">null</span> && <span class="hljs-built_in">this</span>.left.value == value) || (<span class="hljs-built_in">this</span>.right != <span class="hljs-literal">null</span> && <span class="hljs-built_in">this</span>.right.value == value)) {<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">if</span> (value < <span class="hljs-built_in">this</span>.value && <span class="hljs-built_in">this</span>.left != <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.left.searchParent(value);<br>} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value >= <span class="hljs-built_in">this</span>.value && <span class="hljs-built_in">this</span>.right != <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.right.searchParent(value);<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>}<br>}<br><br>}<br><br><span class="hljs-meta">@Override</span><br><span class="hljs-keyword">public</span> <span class="hljs-built_in">String</span> <span class="hljs-function"><span class="hljs-title">toString</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">return</span> <span class="hljs-string">"Node [value="</span> + value + <span class="hljs-string">"]"</span>;<br>}<br><br><span class="hljs-comment">// 添加节点</span><br><span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">add</span>(<span class="hljs-params">Node node</span>)</span> {<br><span class="hljs-keyword">if</span> (node == <span class="hljs-literal">null</span>) {<br><span class="hljs-keyword">return</span>;<br>}<br><span class="hljs-keyword">if</span> (node.value < <span class="hljs-built_in">this</span>.value) {<br><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.left == <span class="hljs-literal">null</span>) {<br><span class="hljs-built_in">this</span>.left = node;<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-built_in">this</span>.left.add(node);<span class="hljs-comment">// 递归</span><br>}<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.right == <span class="hljs-literal">null</span>) {<br><span class="hljs-built_in">this</span>.right = node;<br>} <span class="hljs-keyword">else</span> {<br><span class="hljs-built_in">this</span>.right.add(node);<span class="hljs-comment">// 递归</span><br>}<br>}<br><span class="hljs-keyword">if</span> (rightHeight() - leftHeight() > <span class="hljs-number">1</span>) {<br><span class="hljs-keyword">if</span> (right != <span class="hljs-literal">null</span> && right.leftHeight() > right.rightHeight()) {<br>right.rightRotate();<br>}<br>leftRotate();<br><span class="hljs-keyword">return</span>;<br>}<br><span class="hljs-keyword">if</span> (leftHeight() - rightHeight() > <span class="hljs-number">1</span>) {<br><span class="hljs-keyword">if</span> (left != <span class="hljs-literal">null</span> && left.rightHeight() > left.leftHeight()) {<br>left.leftRotate();<br>}<br>rightRotate();<br>}<br>}<br><br><span class="hljs-comment">// 中序遍历</span><br><span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">infixOrder</span>(<span class="hljs-params"></span>)</span> {<br><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.left != <span class="hljs-literal">null</span>) {<br><span class="hljs-built_in">this</span>.left.infixOrder();<br>}<br>System.out.println(<span class="hljs-built_in">this</span>);<br><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.right != <span class="hljs-literal">null</span>) {<br><span class="hljs-built_in">this</span>.right.infixOrder();<br>}<br>}<br>}<br></code></pre></td></tr></table></figure><h2 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h2><figure class="highlight crmsh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs crmsh">树的高度=<span class="hljs-number">3</span><br>左子树的高度=<span class="hljs-number">2</span><br>右子树的高度=<span class="hljs-number">2</span><br>根结点=<span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">8</span>]<br>根结点的左子结点=<span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">7</span>]<br></code></pre></td></tr></table></figure><hr><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><section class="footnotes"><div class="footnote-list"><ol><li><span id="fn:1" class="footnote-text"><span><a href="https://www.bilibili.com/video/BV1E4411H73v?p=135">尚硅谷Java数据结构与java算法,韩顺平数据结构与算法</a><a href="#fnref:1" rev="footnote" class="footnote-backref"> ↩</a></span></span></li></ol></div></section>]]></content>
<categories>
<category>数据结构与算法</category>
<category>树结构的应用</category>
</categories>
<tags>
<tag>java</tag>
</tags>
</entry>
<entry>
<title>二叉排序树|Binary Sort Tree</title>
<link href="/post/29228/"/>
<url>/post/29228/</url>
<content type="html"><![CDATA[<p>这是在看b站上的韩顺平老师的数据结构与算法<sup id="fnref:1" class="footnote-ref"><a href="#fn:1" rel="footnote"><span class="hint--top hint--rounded" aria-label="尚硅谷Java数据结构与java算法,韩顺平数据结构与算法">[1]</span></a></sup>时做的笔记。等我把后面的都更新完了以后会陆续把前面的补上。</p><hr><h1 id="一、实际案例"><a href="#一、实际案例" class="headerlink" title="一、实际案例"></a>一、实际案例</h1><p>给你一个数列(7,3,10,12,5,1,9)要求能够高效地完成对数组的查找与添加</p><h1 id="二、解决方案"><a href="#二、解决方案" class="headerlink" title="二、解决方案"></a>二、解决方案</h1><ul><li>使用数组|ArrayList<ol><li>数组未排序时:<ul><li>优点:直接在尾部添加,速度快</li><li>缺点:查找速度慢</li></ul></li><li>数组排序时:<ul><li>优点:用二分查找时,查找速度快</li><li>缺点 :为了保证数组有序,添加新数据时速度慢</li></ul></li></ol></li><li>链式存储-链表|LinkedList<ul><li>优点:添加数据速度比数组快,因为不需要整体移动</li><li>缺点:查找速度慢</li></ul></li><li>二叉排序树|BST<ul><li>增删改查效率都比较高</li></ul></li></ul><h1 id="三、基本介绍"><a href="#三、基本介绍" class="headerlink" title="三、基本介绍"></a>三、基本介绍</h1><p><a href="http://btv.melezinek.cz/binary-search-tree.html">一个很好用的BST的可视化网站</a></p><p>二叉排序树:BST(Binary Sort(Search) Tree), 对于它的任何一个非叶子结点|leaf node,要求左子结点的值比当前结点的值小,有子结点的值比当前结点的值大。</p><p>特别说明:如有相同的值,可以将该结点放在左子结点或右子结点(最好避免相同的值)</p><h1 id="四、构建BST"><a href="#四、构建BST" class="headerlink" title="四、构建BST"></a>四、构建BST</h1><p>针对前面的数据(7,3,10,12,5,1,9),对应的二叉排序树为:</p><center>![](https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BST.png)</center><p>当插入结点“2”时,“2”应该放在“1”的右子结点</p><h1 id="五、删除结点的思路"><a href="#五、删除结点的思路" class="headerlink" title="五、删除结点的思路"></a>五、删除结点的思路</h1><h2 id="第一种情况"><a href="#第一种情况" class="headerlink" title="第一种情况"></a>第一种情况</h2><h3 id="——删除叶子结点(如:1,5,9,12)"><a href="#——删除叶子结点(如:1,5,9,12)" class="headerlink" title="——删除叶子结点(如:1,5,9,12)"></a>——删除叶子结点(如:1,5,9,12)</h3><p>1) 定位结点 targetNode</p><p>2)找到targetNode的父结点 parent</p><p>3)确定targetNode是parent的左子结点还是右子结点</p><p>4)根据前面的情况对应删除</p><p>左子结点:<code>parent.left = null</code>;</p><p>右子结点:<code>parent.right = =null</code>;</p><h2 id="第二种情况"><a href="#第二种情况" class="headerlink" title="第二种情况"></a>第二种情况</h2><h3 id="——删除只有一颗子树的结点(如:3)"><a href="#——删除只有一颗子树的结点(如:3)" class="headerlink" title="——删除只有一颗子树的结点(如:3)"></a>——删除只有一颗子树的结点(如:3)</h3><p>1) 定位结点 targetNode</p><p>2)找到targetNode的父结点 parent</p><p>3)确定targetNode的子结点是左结点还是右子结点</p><ul><li>如果targetNode有左子结点 <ol><li>targetNode是parent的左子结点<br><code>parent.left = targetNode.left ;</code></li><li>targetNode是parent的右子结点<br><code>parent.right = targetNode.left ;</code></li></ol></li><li>如果targetNode有右子结点<ol><li>targetNode是parent的左子结点<br><code>parent.left = targetNode.right ;</code></li><li>targetNode是parent的右子结点<br><code>parent.right = targetNode.right ;</code></li></ol></li></ul><h2 id="第三种情况"><a href="#第三种情况" class="headerlink" title="第三种情况"></a>第三种情况</h2><h3 id="——删除有两颗子树的结点(如:7,3,10)"><a href="#——删除有两颗子树的结点(如:7,3,10)" class="headerlink" title="——删除有两颗子树的结点(如:7,3,10)"></a>——删除有两颗子树的结点(如:7,3,10)</h3><ul><li>这里用“10”举例,并且假设“12”下面还有两个子结点</li></ul><p>1) 定位结点 targetNode</p><p>2)找到targetNode的父结点 parent</p><p>3)从targetNode的右子树找到最小的结点</p><p>4)用一个临时变量,将右子树最小的结点值保存 temp = 11</p><p>5)删除该最小结点</p><p>6)<code>targetNode.value = temp;</code> </p><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BST2.png" srcset="/img/loading.gif" lazyload alt=""></p><p><del>容我说一句:妙啊!</del></p><h1 id="六、代码实现"><a href="#六、代码实现" class="headerlink" title="六、代码实现"></a>六、代码实现</h1><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BinarySortTreeDemo</span> </span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">main</span>(<span class="hljs-params"><span class="hljs-built_in">String</span>[] args</span>)</span> {<br> int[] arr = { <span class="hljs-number">7</span>, <span class="hljs-number">3</span>, <span class="hljs-number">10</span>, <span class="hljs-number">12</span>, <span class="hljs-number">5</span>, <span class="hljs-number">1</span>, <span class="hljs-number">9</span>, <span class="hljs-number">2</span> };<br> BinarySortTree binarySortTree = <span class="hljs-keyword">new</span> BinarySortTree();<br> <span class="hljs-keyword">for</span> (int i = <span class="hljs-number">0</span>; i < arr.length; i++) {<br> binarySortTree.add(<span class="hljs-keyword">new</span> Node(arr[i]));<br> }<br> binarySortTree.infixOrder();<span class="hljs-comment">// 1, 2, 3, 5, 7, 9, 10, 12</span><br>binarySortTree.delNode(<span class="hljs-number">2</span>);<br>binarySortTree.delNode(<span class="hljs-number">5</span>);<br>binarySortTree.delNode(<span class="hljs-number">9</span>);<br>binarySortTree.delNode(<span class="hljs-number">12</span>);<br>binarySortTree.delNode(<span class="hljs-number">7</span>);<br>binarySortTree.delNode(<span class="hljs-number">3</span>);<br>binarySortTree.delNode(<span class="hljs-number">10</span>);<br>System.out.println(<span class="hljs-string">"After:"</span>);<br>binarySortTree.infixOrder();<br> }<br>}<br><br><span class="hljs-comment">// 创建树</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BinarySortTree</span> </span>{<br> <span class="hljs-keyword">private</span> Node root;<br><br> <span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">search</span>(<span class="hljs-params">int value</span>)</span> {<br> <span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">return</span> root.search(value);<br> }<br> }<br><br> <span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">searchParent</span>(<span class="hljs-params">int value</span>)</span> {<br> <span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">return</span> root.searchParent(value);<br> }<br> }<br><br> <span class="hljs-keyword">public</span> int <span class="hljs-function"><span class="hljs-title">delRightTreeMin</span>(<span class="hljs-params">Node node</span>)</span> {<br> Node target = node;<br> <span class="hljs-keyword">while</span> (target.left != <span class="hljs-literal">null</span>) {<br> target = target.left;<br> }<br><br> delNode(target.value);<br> <span class="hljs-keyword">return</span> target.value;<br> }<br><br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">delNode</span>(<span class="hljs-params">int value</span>)</span> {<br> <span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span>;<br> } <span class="hljs-keyword">else</span> {<br> Node targetNode = search(value);<br> <span class="hljs-keyword">if</span> (targetNode == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span>;<br> }<br> <span class="hljs-keyword">if</span> (root.left == <span class="hljs-literal">null</span> && root.right == <span class="hljs-literal">null</span>) {<br> root = <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">return</span>;<br> }<br> Node parent = searchParent(value);<br> <span class="hljs-keyword">if</span> (targetNode.left == <span class="hljs-literal">null</span> && targetNode.right == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">if</span> (parent.left != <span class="hljs-literal">null</span> && parent.left.value == value) {<br> parent.left = <span class="hljs-literal">null</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (parent.right != <span class="hljs-literal">null</span> && parent.right.value == value) {<br> parent.right = <span class="hljs-literal">null</span>;<br> }<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (targetNode.left != <span class="hljs-literal">null</span> && targetNode.right != <span class="hljs-literal">null</span>) {<br> int minVal = delRightTreeMin(targetNode.right);<br> targetNode.value = minVal;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">if</span> (targetNode.left != <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">if</span> (parent != <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">if</span> (parent.left.value == value) {<br> parent.left = targetNode.left;<br> } <span class="hljs-keyword">else</span> {<br> parent.right = targetNode.left;<br> }<br> } <span class="hljs-keyword">else</span> {<br> root = targetNode.left;<br> }<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">if</span> (parent != <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">if</span> (parent.left.value == value) {<br> parent.left = targetNode.right;<br> } <span class="hljs-keyword">else</span> {<br> parent.right = targetNode.right;<br> }<br> } <span class="hljs-keyword">else</span> {<br> root = targetNode.right;<br> }<br> }<br> }<br> }<br> }<br><br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">add</span>(<span class="hljs-params">Node node</span>)</span> {<br> <span class="hljs-keyword">if</span> (root == <span class="hljs-literal">null</span>) {<span class="hljs-comment">// 如果是空树,直接让root指向node</span><br> root = node;<br> } <span class="hljs-keyword">else</span> {<br> root.add(node);<br> }<br> }<br><br> <span class="hljs-comment">// 中序遍历</span><br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">infixOrder</span>(<span class="hljs-params"></span>)</span> {<br> <span class="hljs-keyword">if</span> (root != <span class="hljs-literal">null</span>) {<br> root.infixOrder();<br> } <span class="hljs-keyword">else</span> {<br> System.out.println(<span class="hljs-string">"Tree is Empty."</span>);<br> }<br> }<br>}<br><br><span class="hljs-comment">// 创建Node节点</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{<br> int value;<br> Node left;<br> Node right;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-title">Node</span>(<span class="hljs-params">int value</span>)</span> {<br> <span class="hljs-built_in">this</span>.value = value;<br> }<br><br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * </span><br><span class="hljs-comment"> * <span class="hljs-doctag">@param </span>value 希望删除的值</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@return </span>如果找到返回该结点,否则返回null</span><br><span class="hljs-comment"> */</span><br> <span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">search</span>(<span class="hljs-params">int value</span>)</span> {<br> <span class="hljs-keyword">if</span> (value == <span class="hljs-built_in">this</span>.value) {<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value < <span class="hljs-built_in">this</span>.value) {<br> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.left == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.left.search(value);<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.right == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.right.search(value);<br> }<br> }<br><br> <span class="hljs-keyword">public</span> Node <span class="hljs-function"><span class="hljs-title">searchParent</span>(<span class="hljs-params">int value</span>)</span> {<br> <span class="hljs-keyword">if</span> ((<span class="hljs-built_in">this</span>.left != <span class="hljs-literal">null</span> && <span class="hljs-built_in">this</span>.left.value == value) || (<span class="hljs-built_in">this</span>.right != <span class="hljs-literal">null</span> && <span class="hljs-built_in">this</span>.right.value == value)) {<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">if</span> (value < <span class="hljs-built_in">this</span>.value && <span class="hljs-built_in">this</span>.left != <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.left.searchParent(value);<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (value >= <span class="hljs-built_in">this</span>.value && <span class="hljs-built_in">this</span>.right != <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.right.searchParent(value);<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> }<br> }<br><br> }<br><br> <span class="hljs-meta">@Override</span><br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">String</span> <span class="hljs-function"><span class="hljs-title">toString</span>(<span class="hljs-params"></span>)</span> {<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Node [value="</span> + value + <span class="hljs-string">"]"</span>;<br> }<br><br> <span class="hljs-comment">// 添加节点</span><br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">add</span>(<span class="hljs-params">Node node</span>)</span> {<br> <span class="hljs-keyword">if</span> (node == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span>;<br> }<br> <span class="hljs-keyword">if</span> (node.value < <span class="hljs-built_in">this</span>.value) {<br> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.left == <span class="hljs-literal">null</span>) {<br> <span class="hljs-built_in">this</span>.left = node;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-built_in">this</span>.left.add(node);<span class="hljs-comment">// 递归</span><br> }<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.right == <span class="hljs-literal">null</span>) {<br> <span class="hljs-built_in">this</span>.right = node;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-built_in">this</span>.right.add(node);<span class="hljs-comment">// 递归</span><br> }<br> }<br> }<br><br> <span class="hljs-comment">// 中序遍历</span><br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">void</span> <span class="hljs-function"><span class="hljs-title">infixOrder</span>(<span class="hljs-params"></span>)</span> {<br> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.left != <span class="hljs-literal">null</span>) {<br> <span class="hljs-built_in">this</span>.left.infixOrder();<br> }<br> System.out.println(<span class="hljs-built_in">this</span>);<br> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.right != <span class="hljs-literal">null</span>) {<br> <span class="hljs-built_in">this</span>.right.infixOrder();<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><h2 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h2><figure class="highlight crmsh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs crmsh"><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">1</span>]<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">2</span>]<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">3</span>]<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">5</span>]<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">7</span>]<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">9</span>]<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">10</span>]<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">12</span>]<br>After:<br><span class="hljs-keyword">Node</span> <span class="hljs-title">[value</span>=<span class="hljs-number">1</span>]<br></code></pre></td></tr></table></figure><hr><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><section class="footnotes"><div class="footnote-list"><ol><li><span id="fn:1" class="footnote-text"><span><a href="https://www.bilibili.com/video/BV1E4411H73v?p=127">尚硅谷Java数据结构与java算法,韩顺平数据结构与算法</a><a href="#fnref:1" rev="footnote" class="footnote-backref"> ↩</a></span></span></li></ol></div></section>]]></content>
<categories>
<category>数据结构与算法</category>
<category>树结构的应用</category>
</categories>
<tags>
<tag>java</tag>
</tags>
</entry>
<entry>
<title>我的第一篇博客</title>
<link href="/post/63785/"/>
<url>/post/63785/</url>
<content type="html"><![CDATA[<p>这是用来练习markdown语法的一篇博客</p><hr><h1 id="第一章"><a href="#第一章" class="headerlink" title="第一章"></a>第一章</h1><h2 id="1-先来张图"><a href="#1-先来张图" class="headerlink" title="1. 先来张图"></a>1. 先来张图</h2><p><img src="https://gitee.com/Trotyl15/blogImage/raw/master/img/8161596514624_.pic.jpg" srcset="/img/loading.gif" lazyload alt="井盖" title="臭井盖"></p><p><del>其实我根本没玩过DNF</del></p><p>用的是picgo+gitee做的图床</p><h2 id="2-代码"><a href="#2-代码" class="headerlink" title="2. 代码"></a>2. 代码</h2><p><code>这是一小段代码</code></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">String</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"这是一大段很酷炫的代码"</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="3-链接"><a href="#3-链接" class="headerlink" title="3. 链接"></a>3. 链接</h2><p><a href="https://blog.trotyl.xyz">这是一个神秘链接</a></p><h2 id="4-萌娘百科的黑幕条"><a href="#4-萌娘百科的黑幕条" class="headerlink" title="4. 萌娘百科的黑幕条"></a>4. 萌娘百科的黑幕条</h2><p><span class="heimu" title="你知道的太多了">砸瓦鲁多!</span></p><h2 id="5-段落折叠"><a href="#5-段落折叠" class="headerlink" title="5. 段落折叠"></a>5. 段落折叠</h2><details> <summary>点击展开</summary> 你知道的太多了</details>]]></content>
<tags>
<tag>杂七杂八</tag>
</tags>
</entry>
</search>