﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-海阔天空-文章分类-DS &amp; Alg</title><link>http://www.blogjava.net/shiliqiang/category/40762.html</link><description>I'm on my way!</description><language>zh-cn</language><lastBuildDate>Sat, 22 Aug 2009 22:05:51 GMT</lastBuildDate><pubDate>Sat, 22 Aug 2009 22:05:51 GMT</pubDate><ttl>60</ttl><item><title>java中关于优先级队列的实现</title><link>http://www.blogjava.net/shiliqiang/articles/291276.html</link><dc:creator>石头@</dc:creator><author>石头@</author><pubDate>Sat, 15 Aug 2009 09:25:00 GMT</pubDate><guid>http://www.blogjava.net/shiliqiang/articles/291276.html</guid><wfw:comment>http://www.blogjava.net/shiliqiang/comments/291276.html</wfw:comment><comments>http://www.blogjava.net/shiliqiang/articles/291276.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shiliqiang/comments/commentRss/291276.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shiliqiang/services/trackbacks/291276.html</trackback:ping><description><![CDATA[<div>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
这几天一直在搞关于优先级队列的实现,因为要考虑到线程的安全,所以PriorityQueue就不适用了。一个非常简单的实现方
法，那就是把优先级比较好的插入一个队列，优先级低的插入另一个队列，取数的时候先在优先级高的队列上取数。这有个缺点就是如果优先级别越多的话，队列就
越多。</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为要线程安全，队列采用ConcurrentLinkedQueue这个线程安全的，而api文档上说ConcurrentLinkedQueue采用了有效的&#8220;无等待 (wait-free)&#8221;算法，所以它的吞吐量是很不错的！</div>
<div>&nbsp;&nbsp; &nbsp;简单代码如下：</div>
<ol class="highlighter-j">
    <li><span class="keyword">package</span><span>&nbsp;test;</span><br />
    </li>
    <li class="alt"><br />
    </li>
    <li><span class="keyword">import</span><span>&nbsp;java.util.concurrent.ConcurrentLinkedQueue;</span></li>
    <li class="alt"><br />
    </li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;PriorityQueueTest&nbsp;{</span></li>
    <li class="alt"><br />
    </li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ConcurrentLinkedQueue&lt;String&gt;&nbsp;highPriority&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ConcurrentLinkedQueue&lt;String&gt;();&nbsp;</span><span class="comment">//高优先级</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ConcurrentLinkedQueue&lt;String&gt;&nbsp;lowPriority&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ConcurrentLinkedQueue&lt;String&gt;(); &nbsp;</span><span class="comment">//低优先级</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;highPriority.add(</span><span class="string">"aaa"</span><span>);</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;highPriority.add(</span><span class="string">"bbb"</span><span>);</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;highPriority.add(</span><span class="string">"111"</span><span>);</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowPriority.add(</span><span class="string">"ccc"</span><span>);</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowPriority.add(</span><span class="string">"ddd"</span><span>);</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowPriority.add(</span><span class="string">"222"</span><span>);</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>&nbsp;,j&nbsp;=&nbsp;</span><span class="number">0</span><span>,&nbsp;k=</span><span class="number">0</span><span>;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>(</span><span class="keyword">true</span><span>){</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>(</span><span class="keyword">true</span><span>){</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(!highPriority.isEmpty()){</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(highPriority.remove());</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k++;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">",&nbsp;i&nbsp;=&nbsp;"</span><span>+i+</span><span class="string">",&nbsp;k="</span><span>+k);</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">break</span><span>;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(!lowPriority.isEmpty()){</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(lowPriority.remove());</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j++;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k++;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">",&nbsp;j&nbsp;=&nbsp;"</span><span>+j+</span><span class="string">",&nbsp;k="</span><span>+k);</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">break</span><span>;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">break</span><span>;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span class="number">100</span><span>);</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(InterruptedException&nbsp;e)&nbsp;{</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li><span>}</span></li>
</ol>
<div><span class="Apple-style-span" style="color: #000000; line-height: 14px;"><br />
</span></div>
<div><span class="Apple-style-span" style="color: #000000; line-height: 14px;">&nbsp;&nbsp;&nbsp; <br />
</span></div>
<div><span class="Apple-style-span" style="color: #000000; line-height: 14px;">&nbsp;<br />
</span></div>
<div><span class="Apple-style-span" style="color: #000000; line-height: 14px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span></div>
<div><span class="Apple-style-span" style="color: #000000; line-height: 14px;">&nbsp;&nbsp; &nbsp; &nbsp;还有一种是，通过继承<span class="Apple-style-span" style="color: #333333; line-height: normal;"><span class="Apple-style-span" style="color: #000000; line-height: 14px;">PriorityQueue</span><span class="Apple-style-span" style="color: #000000; line-height: 14px;">并实现<span class="Apple-style-span" style="color: #333333; line-height: normal;">Comparable接口，然后自已重写过compareTo方法就能实现很强大的优先级队列了，不过缺点是线程不安全的！</span></span></span></span></div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;代码如下：</div>
<div class="highlighter">
<ol class="highlighter-j">
    <li><span class="keyword">package</span><span>&nbsp;test;</span></li>
    <li class="alt"><br />
    </li>
    <li><span class="keyword">import</span><span>&nbsp;java.util.PriorityQueue;</span></li>
    <li class="alt"><br />
    </li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;PriorityTest&nbsp;</span><span class="keyword">extends</span><span>&nbsp;PriorityQueue&lt;PriorityTest.Test&gt;{</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Test&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Comparable&lt;Test&gt;{</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;packet;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;priotity;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;Test(String&nbsp;packet,&nbsp;</span><span class="keyword">int</span><span>&nbsp;priotity)&nbsp;{</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.packet&nbsp;=&nbsp;packet;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.priotity&nbsp;=&nbsp;priotity;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;compareTo(Test&nbsp;arg)&nbsp;{&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(priotity&nbsp;&lt;&nbsp;arg.priotity)</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="number">1</span><span>;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">else</span><span>&nbsp;</span><span class="keyword">if</span><span>(priotity&nbsp;&gt;&nbsp;arg.priotity)</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;-</span><span class="number">1</span><span>;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">else</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="number">0</span><span>;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;toString(){</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;packet;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;add(String&nbsp;str,&nbsp;</span><span class="keyword">int</span><span>&nbsp;priority){</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">super</span><span>.add(</span><span class="keyword">new</span><span>&nbsp;Test(str,priority));</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String&nbsp;args[]){</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PriorityTest&nbsp;pTest&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;PriorityTest();</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pTest.add(</span><span class="string">"aaa"</span><span>,</span><span class="number">3</span><span>); &nbsp;<span class="Apple-style-span" style="color: #008200;">//优先级最高</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pTest.add(</span><span class="string">"bbb"</span><span>,</span><span class="number">2</span><span>);</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pTest.add(</span><span class="string">"ccc"</span><span>,</span><span class="number">1</span><span>);</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>(!pTest.isEmpty()){</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(pTest.remove());</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}</span></li>
    <li><span>}</span></li>
    <li class="alt"><br />
    </li>
</ol>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
摘自：http://blog.csdn.net/liuzhengkang/archive/2009/01/05/3714047.aspx<br />
</div>
<img src ="http://www.blogjava.net/shiliqiang/aggbug/291276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shiliqiang/" target="_blank">石头@</a> 2009-08-15 17:25 <a href="http://www.blogjava.net/shiliqiang/articles/291276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>蛇阵算法</title><link>http://www.blogjava.net/shiliqiang/articles/288421.html</link><dc:creator>石头@</dc:creator><author>石头@</author><pubDate>Sun, 26 Jul 2009 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/shiliqiang/articles/288421.html</guid><wfw:comment>http://www.blogjava.net/shiliqiang/comments/288421.html</wfw:comment><comments>http://www.blogjava.net/shiliqiang/articles/288421.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shiliqiang/comments/commentRss/288421.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shiliqiang/services/trackbacks/288421.html</trackback:ping><description><![CDATA[转自：http://www.blogjava.net/nokiaguy/archive/2009/07/24/288163.html<br />
<br />
&nbsp;&nbsp; 在描述算法之前，先看看下面的5*5的表格：<br />
<br />
<table border="0" cellpadding="2" cellspacing="2" height="134" width="160">
    <tbody>
        <tr>
            <td>&nbsp;1</td>
            <td>&nbsp;3</td>
            <td>&nbsp;4</td>
            <td>&nbsp;10</td>
            <td>&nbsp;11</td>
        </tr>
        <tr>
            <td>&nbsp;2</td>
            <td>&nbsp;5</td>
            <td>&nbsp;9</td>
            <td>&nbsp;12 <br />
            </td>
            <td>&nbsp;19 <br />
            </td>
        </tr>
        <tr>
            <td>&nbsp;6</td>
            <td>&nbsp;8</td>
            <td>&nbsp;13</td>
            <td>&nbsp;18</td>
            <td>&nbsp;20</td>
        </tr>
        <tr>
            <td>&nbsp;7</td>
            <td>&nbsp;14</td>
            <td>&nbsp;17</td>
            <td>&nbsp;21</td>
            <td>&nbsp;24</td>
        </tr>
        <tr>
            <td>&nbsp;15</td>
            <td>&nbsp;16</td>
            <td>&nbsp;22</td>
            <td>&nbsp;23</td>
            <td>&nbsp;25</td>
        </tr>
    </tbody>
</table>
<br />
&nbsp;&nbsp;&nbsp; 上面的表格很容易看出规律。就是从左上角第一个格开始（起始为1），然后延右上角到左下角的斜线。先从下到上，再从上到下。开始按数字递增排列。也就是说每一个斜线上分别有如下几组数字：<br />
<br />
1&nbsp;&nbsp;&nbsp; 2 3&nbsp;&nbsp;&nbsp;&nbsp; 4 5 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7 8 9 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11 12 13 14 15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16 17 18 19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20 21 22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 23 24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25<br />
<br />
&nbsp;&nbsp;&nbsp; 由于是先从上到下（1可以看做是从上到下），再从下到上，很象一条蛇，因此，该数字表格也可称为蛇形矩阵。现在要与一个方法（或函数），方法的参数是一个int类型，表示n，方法返回一个二维数组，表示要获得的往返接力数字表格。<br />
&nbsp;&nbsp;&nbsp; 实际上，这个算法并不复杂，只需要从分别获得1至n^2中每个数字对应的二维数组的坐标就可以了。先拿这个5行5列的表格来说，求出上面每组数组对应的坐标（起始位置为0）。<br />
<br />
<table height="82" width="625">
    <tbody>
        <tr>
            <td>
            第0组<br />
            第1组<br />
            第2组<br />
            第3组<br />
            第4组<br />
            第5组<br />
            第6组<br />
            第7组<br />
            第8组<br />
            </td>
            <td>
            1&nbsp;&nbsp;&nbsp;&nbsp; <br />
            2 3<br />
            4 5 6<br />
            7 8 9 10<br />
            11 12 13 14 15<br />
            16 17 18 19 <br />
            20 21 22<br />
            23 24<br />
            25<br />
            </td>
            <td>(0,0)<br />
            (1,0)&nbsp;&nbsp; (0,1)<br />
            (0,2) &nbsp; (1,1)&nbsp;&nbsp; (2,0)<br />
            (3,0)&nbsp;&nbsp; (2,1)&nbsp;&nbsp; (1,2)&nbsp;&nbsp; (0,3)<br />
            (0,4)&nbsp;&nbsp; (1,3)&nbsp;&nbsp; (2,2)&nbsp;&nbsp; (3,1)&nbsp;&nbsp; (4,0)<br />
            (4,1)&nbsp;&nbsp; (3,2)&nbsp;&nbsp; (2,3)&nbsp;&nbsp; (1,4)<br />
            (2,4)&nbsp;&nbsp; (3,3) &nbsp; (4,2)<br />
            (4,3)&nbsp;&nbsp; (3,4)<br />
            (4,4)<br />
            </td>
        </tr>
    </tbody>
</table>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 从上面的从标可以看出一个规律。&nbsp; 左上角的半个表格（以对角线分界）的横坐标和纵坐标从0开始，每一组增1，直到增至表格的边界（n -
1），而且是交替的，也就是说，偶数行是列增，行减小，行+列=组的索引。而右下角的4组数字虽然行、列也是交替增长的，但递减的行或列总是从(n -
1)开始（对于本例，是从4开始），而递增的行或列总是从index - n +
1开始，其中index表示组的索引。这就可以得出一个算法。实现代码如下：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;getGrid(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;array&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[n][n];<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;row&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;m&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;用于控制奇偶组，false表示偶组，true表示奇组</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;isRow&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;i表示当前组的索引，从0开始</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">2</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(row&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;((i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;n)&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;:&nbsp;i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;如果处理的是右下角表格中的数字，行或列最大不能超过n-1</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(row&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;(n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;row;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(isRow)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[row][col]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;将row变成列，将col变成行</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[col][row]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;切换奇偶组</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isRow&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">isRow;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;array;<br />
}</span></div>
<br />
<strong>&nbsp;&nbsp; 改进算法</strong><br />
<br />
&nbsp;&nbsp;
上面实现的算法需要循环N*N次才可以生成蛇形矩阵。但仔细分析一下，还可以继续简化算法，使循环次数减小至N*N/2，也就是说，效率可以提高一倍。我
们上学时曾学过用高斯的方法计算1+2+3+...+100， &nbsp; 1 + 100 = 101，2 + 99 = 101，...，50+51 =
101，因此，结果是101 * 50 =
5050。很方便。我们这个算法也可采用类似的方法。仔细观察上面5*5的数字表格发现，算出左上角的矩阵中每一个数字后，都可以直接获得右下角度某个位
置的数字。例如在(0,0)位置的1，可以向到(4,4)位置的25，(1,2)位置的9可以得到(3,2)位置的17。我们发现，每一对数之和都为
26。而且它们坐标的关系是(row,col)，(n - row - 1, n - col -
1)。因此，只要得到左上角的半个矩阵，就可以得出右下角的另外半个矩阵。如果n为奇数，对角线中间的一个数（在5*5的矩阵中是13）与之对应的数是其
自身。好，我们看看改进的算法的实现：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;getGrid1(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;array&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[n][n];<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;row&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;m&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;number1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;&nbsp;(n&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">%</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;number2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;isRow&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;number1表示要计算的蛇形矩阵中最大的数字，对于5*5矩阵来说该数是13</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;m&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;number1;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(row&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;row;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(isRow)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[row][col]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;填充与m对应的另外一个数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;row&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;col&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;number2&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;m;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[col][row]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;填充与m对应的另外一个数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;col&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;row&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;number2&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;m;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
</span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if</span><span style="color: #000000;">(m&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;number1)&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;</span><br />
<span style="color: #000000;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isRow&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">isRow;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;array;<br />
}<br />
</span></div>
<br />
&nbsp;&nbsp; 如果想输出n=10的数字表格，可以使用int[][] grid = getGrid(10)或int[][] grid1 = getGrid1(10)，会得到同样的结果。输出grid和grid1，看看是不是下面的结果：<br />
<br />
<br />
<table>
    <tbody>
        <tr>
            <td>1</td>
            <td>3</td>
            <td>4</td>
            <td>10</td>
            <td>11</td>
            <td>21</td>
            <td>22</td>
            <td>36</td>
            <td>37</td>
            <td>55</td>
        </tr>
        <tr>
            <td>2</td>
            <td>5</td>
            <td>9</td>
            <td>12</td>
            <td>20</td>
            <td>23</td>
            <td>35</td>
            <td>38</td>
            <td>54</td>
            <td>56</td>
        </tr>
        <tr>
            <td>6</td>
            <td>8</td>
            <td>13</td>
            <td>19</td>
            <td>24</td>
            <td>34</td>
            <td>39</td>
            <td>53</td>
            <td>57</td>
            <td>72</td>
        </tr>
        <tr>
            <td>7</td>
            <td>14</td>
            <td>18</td>
            <td>25</td>
            <td>33</td>
            <td>40</td>
            <td>52</td>
            <td>58</td>
            <td>71</td>
            <td>73</td>
        </tr>
        <tr>
            <td>15</td>
            <td>17</td>
            <td>26</td>
            <td>32</td>
            <td>41</td>
            <td>51</td>
            <td>59</td>
            <td>70</td>
            <td>74</td>
            <td>85</td>
        </tr>
        <tr>
            <td>16</td>
            <td>27</td>
            <td>31</td>
            <td>42</td>
            <td>50</td>
            <td>60</td>
            <td>69</td>
            <td>75</td>
            <td>84</td>
            <td>86</td>
        </tr>
        <tr>
            <td>28</td>
            <td>30</td>
            <td>43</td>
            <td>49</td>
            <td>61</td>
            <td>68</td>
            <td>76</td>
            <td>83</td>
            <td>87</td>
            <td>94</td>
        </tr>
        <tr>
            <td>29</td>
            <td>44</td>
            <td>48</td>
            <td>62</td>
            <td>67</td>
            <td>77</td>
            <td>82</td>
            <td>88</td>
            <td>93</td>
            <td>95</td>
        </tr>
        <tr>
            <td>45</td>
            <td>47</td>
            <td>63</td>
            <td>66</td>
            <td>78</td>
            <td>81</td>
            <td>89</td>
            <td>92</td>
            <td>96</td>
            <td>99<br />
            </td>
        </tr>
        <tr>
            <td>46</td>
            <td>64</td>
            <td>65</td>
            <td>79</td>
            <td>80</td>
            <td>90</td>
            <td>91</td>
            <td>97</td>
            <td>98</td>
            <td>100<br />
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/shiliqiang/aggbug/288421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shiliqiang/" target="_blank">石头@</a> 2009-07-26 09:39 <a href="http://www.blogjava.net/shiliqiang/articles/288421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>五子棋AI算法</title><link>http://www.blogjava.net/shiliqiang/articles/286605.html</link><dc:creator>石头@</dc:creator><author>石头@</author><pubDate>Mon, 13 Jul 2009 10:46:00 GMT</pubDate><guid>http://www.blogjava.net/shiliqiang/articles/286605.html</guid><wfw:comment>http://www.blogjava.net/shiliqiang/comments/286605.html</wfw:comment><comments>http://www.blogjava.net/shiliqiang/articles/286605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shiliqiang/comments/commentRss/286605.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shiliqiang/services/trackbacks/286605.html</trackback:ping><description><![CDATA[<div class="tit">五子棋的核心算法</div>
<div class="date">2009年04月22日 星期三 17:55</div>
<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt" id="blog_text">
            <div style="margin: 15px">五子棋是一种受大众广泛喜爱的游戏，其规则简单，变化多端，非常富有趣味性和消遣性。这里设计和实现了一个人机对下的五子棋程序，采用了博弈树的方法，应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <p>一、相关的数据结构 <br />
            &nbsp;&nbsp;&nbsp; 关于盘面情况的表示，以链表形式表示当前盘面的情况，目的是可以允许用户进行悔棋、回退等操作。 <br />
            &nbsp;&nbsp;&nbsp; CList StepList; <br />
            &nbsp;&nbsp;&nbsp; 其中Step结构的表示为：</p>
            <p>&nbsp;&nbsp;&nbsp; struct Step <br />
            &nbsp;&nbsp;&nbsp; { <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m; //m,n表示两个坐标值 <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int n; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char side; //side表示下子方 <br />
            &nbsp;&nbsp;&nbsp; }; <br />
            以数组形式保存当前盘面的情况， <br />
            目的是为了在显示当前盘面情况时使用： <br />
            char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];</p>
            <p>&nbsp;&nbsp;&nbsp; 其中FIVE_MAX_LINE表示盘面最大的行数。</p>
            <p>&nbsp;&nbsp;&nbsp; 同时由于需要在递归搜索的过程中考虑时间和空间有效性，只找出就当前情况来说相对比较好的几个盘面，而不是对所有的可下子的位置都进行搜索，这里用变量CountList来表示当前搜索中可以选择的所有新的盘面情况对象的集合：</p>
            <p>CList CountList; <br />
            &nbsp;&nbsp;&nbsp; 其中类CBoardSituiton为: <br />
            class CBoardSituation <br />
            { <br />
            CList StepList; //每一步的列表 <br />
            char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE]; <br />
            struct Step machineStep;&nbsp;&nbsp;&nbsp; //机器所下的那一步 <br />
            double value; //该种盘面状态所得到的分数 <br />
            }</p>
            <p>二、评分规则 <br />
            &nbsp;&nbsp;&nbsp; 对于下子的重要性评分，需要从六个位置来考虑当前棋局的情况，分别为：-,&amp;brvbar;,/,,//,\</p>
            <p><br />
            &nbsp;&nbsp;&nbsp; 实际上需要考虑在这六个位置上某一方所形成的子的布局的情况，对于在还没有子的地方落子以后的当前局面的评分，主要是为了说明在这个地方下子的重要性程度，设定了一个简单的规则来表示当前棋面对机器方的分数。</p>
            <p>&nbsp;&nbsp;&nbsp; 基本的规则如下：</p>
            <p>判断是否能成5, 如果是机器方的话给予100000分，如果是人方的话给予－100000 分； <br />
            判断是否能成活4或者是双死4或者是死4活3，如果是机器方的话给予10000分，如果是人方的话给予－10000分； <br />
            判断是否已成双活3，如果是机器方的话给予5000分，如果是人方的话给予－5000 分； <br />
            判断是否成死3活3，如果是机器方的话给予1000分，如果是人方的话给予－1000 分； <br />
            判断是否能成死4，如果是机器方的话给予500分，如果是人方的话给予－500分； <br />
            判断是否能成单活3，如果是机器方的话给予200分，如果是人方的话给予－200分； <br />
            判断是否已成双活2，如果是机器方的话给予100分，如果是人方的话给予－100分； <br />
            判断是否能成死3，如果是机器方的话给予50分，如果是人方的话给予－50分； <br />
            判断是否能成双活2，如果是机器方的话给予10分，如果是人方的话给予－10分； <br />
            判断是否能成活2，如果是机器方的话给予5分，如果是人方的话给予－5分； <br />
            判断是否能成死2，如果是机器方的话给予3分，如果是人方的话给予－3分。</p>
            <p>&nbsp;&nbsp;&nbsp; 实际上对当前的局面按照上面的规则的顺序进行比较，如果满足某一条规则的话，就给该局面打分并保存，然后退出规则的匹配。注意这里的规则是根据一般的下棋规律的一个总结，在实际运行的时候，用户可以添加规则和对评分机制加以修正。</p>
            <p>三、胜负判断 <br />
            &nbsp;&nbsp;&nbsp; 实际上，是根据当前最后一个落子的情况来判断胜负的。实际上需要从四个位置判断，以该子为出发点的水平，竖直和两条分别为 45度角和135度角的线，目的是看在这四个方向是否最后落子的一方构成连续五个的棋子，如果是的话，就表示该盘棋局已经分出胜负。具体见下面的图示：</p>
            <p><br />
            四、搜索算法实现描述 <br />
            &nbsp;&nbsp;&nbsp; 注意下面的核心的算法中的变量currentBoardSituation，表示当前机器最新的盘面情况, CountList表示第一层子节点可以选择的较好的盘面的集合。核心的算法如下： <br />
            void MainDealFunction() <br />
            { <br />
            value=－MAXINT; //对初始根节点的value赋值 <br />
            CalSeveralGoodPlace(currentBoardSituation,CountList); <br />
            //该函数是根据当前的盘面情况来比较得到比较好的可以考虑的几个盘面的情况，可以根据实际的得分情况选取分数比较高的几个盘面，也就是说在第一层节点选择的时候采用贪婪算法，直接找出相对分数比较高的几个形成第一层节点，目的是为了提高搜索速度和防止堆栈溢出。 <br />
            pos=CountList.GetHeadPosition(); <br />
            CBoardSituation＊ pBoard; <br />
            for(i=0;ivalue=Search(pBoard,min,value,0); <br />
            Value=Select(value,pBoard－&gt;value,max); <br />
            //取value和pBoard－&gt;value中大的赋给根节点 <br />
            } <br />
            for(i=0;ivalue) <br />
            //找出那一个得到最高分的盘面 <br />
            { <br />
            &nbsp;&nbsp;&nbsp; currentBoardSituation=pBoard; <br />
            &nbsp;&nbsp;&nbsp; PlayerMode=min; //当前下子方改为人 <br />
            &nbsp;&nbsp;&nbsp; Break; <br />
            } <br />
            }</p>
            <p>&nbsp;&nbsp;&nbsp; 其中对于Search函数的表示如下：实际上核心的算法是一个剪枝过程，其中在这个搜索过程中相关的四个参数为：（1）当前棋局情况；（2）当前的下子方，可以是机器(max)或者是人(min)；（3）父节点的值oldValue；（4）当前的搜索深度depth。</p>
            <p>double Search(CBoardSituation＆ <br />
            board,int mode,double oldvalue,int depth) <br />
            { <br />
            CList m_DeepList; <br />
            if(deptholdvalue))==&nbsp;&nbsp;&nbsp; TRUE) <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(mode==max) <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value=select(value,search(successor <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Board,min,value,depth＋1),max); <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value=select(value,search(successor <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Board,max,value,depth＋1),min); <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return value; <br />
            } <br />
            else <br />
            { <br />
            if ( goal(board)&lt;&gt;0) <br />
            //这里goal(board)&lt;&gt;0表示已经可以分出胜负 <br />
            return goal(board); <br />
            else <br />
            return evlation(board); <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
            &nbsp;&nbsp;&nbsp; }</p>
            <p>&nbsp;&nbsp;&nbsp; 注意这里的goal(board)函数是用来判断当前盘面是否可以分出胜负，而evlation(board)是对当前的盘面从机器的角度进行打分。</p>
            <p>&nbsp;&nbsp;&nbsp; 下面是Select函数的介绍，这个函数的主要目的是根据 PlayerMode情况，即是机器还是用户来返回节点的应有的值。</p>
            <p>double Select(double a,double b,int mode) <br />
            { <br />
            if(a&gt;b ＆＆ mode==max)&amp;brvbar;&amp;brvbar; (a&lt; b ＆＆ mode==min) <br />
            return a; <br />
            else <br />
            return b; <br />
            }</p>
            <p>五、小结 <br />
            &nbsp;&nbsp;&nbsp; 在Windows操作系统下，用VC＋＋实现了这个人机对战的五子棋程序。和国内许多只是采用规则或者只是采用简单递归而没有剪枝的那些程序相比，在智力上和时间有效性上都要好于这些程序。同时所讨论的方法和设计过程为用户设计其他的游戏（如象棋和围棋等）提供了一个参考</p>
            </div>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/shiliqiang/aggbug/286605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shiliqiang/" target="_blank">石头@</a> 2009-07-13 18:46 <a href="http://www.blogjava.net/shiliqiang/articles/286605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>