﻿<?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-Tinysun-随笔分类-Algorithm and Data Structure</title><link>http://www.blogjava.net/tinysun/category/37795.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 05 Oct 2010 17:52:59 GMT</lastBuildDate><pubDate>Tue, 05 Oct 2010 17:52:59 GMT</pubDate><ttl>60</ttl><item><title> 跳跃表</title><link>http://www.blogjava.net/tinysun/archive/2010/10/04/333722.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Mon, 04 Oct 2010 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2010/10/04/333722.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/333722.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2010/10/04/333722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/333722.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/333722.html</trackback:ping><description><![CDATA[<p><font style="background-color: #cde9d1">本文将总结一种数据结构：跳跃表。前半部分跳跃表性质和操作的介绍直接摘自《让算法的效率跳起来--浅谈&#8220;跳跃表&#8221;的相关操作及其应用》上海市华东师范大学第二附属中学 魏冉。之后将附上跳跃表的源代码，以及本人对其的了解。难免有错误之处，希望指正，共同进步。谢谢。</font></p>
<p><font style="background-color: #cde9d1">&nbsp;&nbsp;&nbsp; 跳跃表（Skip List）是1987年才诞生的一种崭新的数据结构，它在进行查找、插入、删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领。而且最重要的一点，就是它的编程复杂度较同类的AVL树，红黑树等要低得多，这使得其无论是在理解还是在推广性上，都有着十分明显的优势。</font></p>
<p><font style="background-color: #cde9d1">&nbsp;&nbsp;&nbsp; 首先，我们来看一下跳跃表的结构</font></p>
<p><font style="background-color: #cde9d1"></font>&nbsp;</p>
<p><font style="background-color: #cde9d1">&nbsp;&nbsp; 跳跃表由多条链构成（S0，S1，S2 &#8230;&#8230;，Sh），且满足如下三个条件：</font></p>
<p><font style="background-color: #cde9d1">每条链必须包含两个特殊元素：+&#8734; 和 -&#8734;(其实不需要)<br />
S0包含所有的元素，并且所有链中的元素按照升序排列。<br />
每条链中的元素集合必须包含于序数较小的链的元素集合。<br />
&nbsp;&nbsp; 操作</font></p>
<p><font style="background-color: #cde9d1">&nbsp;&nbsp; 一、查找<br />
&nbsp;&nbsp; 目的：在跳跃表中查找一个元素x<br />
&nbsp;&nbsp; 在跳跃表中查找一个元素x，按照如下几个步骤进行：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 从最上层的链（Sh）的开头开始<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. 假设当前位置为p，它向右指向的节点为q（p与q不一定相邻），且q的值为y。将y与x作比较<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) x=y&nbsp; 输出查询成功及相关信息<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) x&gt;y&nbsp; 从p向右移动到q的位置<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) x&lt;y&nbsp; 从p向下移动一格</font></p>
<p><font style="background-color: #cde9d1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. 如果当前位置在最底层的链中（S0），且还要往下移动的话，则输出查询失败</font></p>
<p><font style="background-color: #cde9d1"></font>&nbsp;</p>
<p><font style="background-color: #cde9d1">&nbsp;&nbsp;&nbsp; 二、插入<br />
&nbsp;&nbsp;&nbsp;&nbsp; 目的：向跳跃表中插入一个元素x<br />
&nbsp;&nbsp;&nbsp;&nbsp; 首先明确，向跳跃表中插入一个元素，相当于在表中插入一列从S0中某一位置出发向上的连续一段元素。有两个参数需要确定，即插入列的位置以及它的&#8220;高度&#8221;。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 关于插入的位置，我们先利用跳跃表的查找功能，找到比x小的最大的数y。根据跳跃表中所有链均是递增序列的原则，x必然就插在y的后面。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 而插入列的&#8220;高度&#8221;较前者来说显得更加重要，也更加难以确定。由于它的不确定性，使得不同的决策可能会导致截然不同的算法效率。为了使插入数据之后，保持该数据结构进行各种操作均为O(logn)复杂度的性质，我们引入随机化算法（Randomized Algorithms）。</font></p>
<p><font style="background-color: #cde9d1">&nbsp;&nbsp;&nbsp;&nbsp; 我们定义一个随机决策模块，它的大致内容如下：</font></p>
<p><font style="background-color: #cde9d1">&nbsp;产生一个0到1的随机数r&nbsp;&nbsp;&nbsp;&nbsp; r &#8592; random() <br />
如果r小于一个常数p，则执行方案A，&nbsp; if&nbsp; r&lt;p then do A <br />
否则，执行方案B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else do B <br />
&nbsp;&nbsp;&nbsp;&nbsp; 初始时列高为1。插入元素时，不停地执行随机决策模块。如果要求执行的是A操作，则将列的高度加1，并且继续反复执行随机决策模块。直到第i次，模块要求执行的是B操作，我们结束决策，并向跳跃表中插入一个高度为i的列。</font></p>
<font style="background-color: #cde9d1">
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp; 我们来看一个例子：<br />
&nbsp;&nbsp;&nbsp;&nbsp; 假设当前我们要插入元素&#8220;40&#8221;，且在执行了随机决策模块后得到高度为4<br />
&nbsp;&nbsp;&nbsp;&nbsp; 步骤一：找到表中比40小的最大的数，确定插入位置</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 步骤二：插入高度为4的列，并维护跳跃表的结构</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 三、删除</p>
<p>&nbsp;&nbsp;&nbsp; 目的：从跳跃表中删除一个元素x<br />
&nbsp;&nbsp;&nbsp; 删除操作分为以下三个步骤：</p>
<p>在跳跃表中查找到这个元素的位置，如果未找到，则退出 <br />
将该元素所在整列从表中删除 <br />
将多余的&#8220;空链&#8221;删除&nbsp; </p>
<p><br />
&nbsp;&nbsp;&nbsp; 我们来看一下跳跃表的相关复杂度：<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 空间复杂度： O(n)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （期望）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 跳跃表高度： O(logn)&nbsp; （期望）</p>
<p><br />
&nbsp;&nbsp;&nbsp; 相关操作的时间复杂度：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查找：&nbsp; O(logn)&nbsp;&nbsp;&nbsp; （期望）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插入：&nbsp; O(logn)&nbsp;&nbsp;&nbsp; （期望）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除：&nbsp; O(logn)&nbsp;&nbsp; （期望）<br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; 之所以在每一项后面都加一个&#8220;期望&#8221;，是因为跳跃表的复杂度分析是基于概率论的。有可能会产生最坏情况，不过这种概率极其微小。</p>
<p>&nbsp;</p>
<p>--------------------------------------------------------------------------------</p>
<p><br />
&nbsp;&nbsp;&nbsp; 以下是自己学习时碰到的一些问题</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 首先分配一个链表，用list.hdr指向，长度为跳跃表规定的最高层，说是链表，在以下代码中只是分配了一段连续的空间，用来指向每一层的开始位置。我们看到结构体nodeType中，有一个key,一个rec(用户数据)，还有一个指向结构体的指针数组。</p>
<p><br />
&nbsp;&nbsp;&nbsp; 一开始的那些图容易给人误解。如上图所示，例如每个节点的forward[2]，就认为是跳跃表的第3层。List.hdr的forward[2]指向11，11的forward[2]指向30，30的forward[2]指向53。这就是跳跃表的第3层：11---30-----53。（准确的说每个forward都指向新节点，新节点的同层forward又指向另一个节点，从而构成一个链表，而数据只有一个，并不是像开始途中所画的那样有N个副本）。本人天资愚钝，看了挺长时间才把它在内存里的结构看清楚了，呵呵。&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; 以下是在网上搜到的一个实现代码</p>
<p><br />
&nbsp;&nbsp;&nbsp; 代码中主要注释了insert函数，剩下的两个函数差不多，就不一一注释了</p>
<p>&nbsp;&nbsp;&nbsp; </p>
<p><br />
view plaincopy to clipboardprint?<br />
/* skip list */&nbsp; <br />
&nbsp; <br />
#include &lt;stdio.h&gt;&nbsp;&nbsp; <br />
#include &lt;stdlib.h&gt;&nbsp;&nbsp; <br />
&nbsp; <br />
/* implementation dependent declarations */&nbsp; <br />
typedef enum {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; STATUS_OK,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; STATUS_MEM_EXHAUSTED,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; STATUS_DUPLICATE_KEY,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; STATUS_KEY_NOT_FOUND&nbsp;&nbsp; <br />
} statusEnum;&nbsp;&nbsp; <br />
&nbsp; <br />
typedef int keyType;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* type of key */&nbsp; <br />
&nbsp; <br />
/* user data stored in tree */&nbsp; <br />
typedef struct {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; int stuff;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* optional related data */&nbsp; <br />
} recType;&nbsp;&nbsp; <br />
&nbsp; <br />
#define compLT(a,b) (a &lt; b)&nbsp;&nbsp; <br />
#define compEQ(a,b) (a == b)&nbsp;&nbsp; <br />
&nbsp; <br />
/* levels range from (0 .. MAXLEVEL) */&nbsp; <br />
#define MAXLEVEL 15&nbsp;&nbsp; <br />
&nbsp; <br />
typedef struct nodeTag {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; keyType key;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* key used for searching */&nbsp; <br />
&nbsp;&nbsp;&nbsp; recType rec;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* user data */&nbsp; <br />
&nbsp;&nbsp;&nbsp; struct nodeTag *forward[1]; /* skip list forward pointer */&nbsp; <br />
} nodeType;&nbsp;&nbsp; <br />
&nbsp; <br />
/* implementation independent declarations */&nbsp; <br />
typedef struct {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; nodeType *hdr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* list Header */&nbsp; <br />
&nbsp;&nbsp;&nbsp; int listLevel;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* current level of list */&nbsp; <br />
} SkipList;&nbsp;&nbsp; <br />
&nbsp; <br />
SkipList list;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* skip list information */&nbsp; <br />
&nbsp; <br />
#define NIL list.hdr&nbsp;&nbsp; <br />
static int count = 0;&nbsp;&nbsp; <br />
statusEnum insert(keyType key, recType *rec) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; int i, newLevel;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; nodeType *update[MAXLEVEL+1];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; nodeType *x;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; count++;&nbsp;&nbsp; <br />
&nbsp;&nbsp; /***********************************************&nbsp; <br />
&nbsp;&nbsp;&nbsp; *&nbsp; allocate node for data and insert in list&nbsp; *&nbsp; <br />
&nbsp;&nbsp;&nbsp; ***********************************************/&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; /* find where key belongs */&nbsp; <br />
&nbsp;&nbsp;&nbsp; /*从高层一直向下寻找，直到这层指针为NIL，也就是说&nbsp; <br />
&nbsp;&nbsp;&nbsp; 后面没有数据了，到头了，并且这个值不再小于要插入的值。&nbsp; <br />
&nbsp;&nbsp;&nbsp; 记录这个位置，留着向其后面插入数据*/&nbsp; <br />
&nbsp;&nbsp;&nbsp; x = list.hdr;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = list.listLevel; i &gt;= 0; i--) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (x-&gt;forward[i] != NIL&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; compLT(x-&gt;forward[i]-&gt;key, key))&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = x-&gt;forward[i];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update[i] = x;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; /*现在让X指向第0层的X的后一个节点*/&nbsp; <br />
&nbsp;&nbsp;&nbsp; x = x-&gt;forward[0];&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; /*如果相等就不用插入了*/&nbsp; <br />
&nbsp;&nbsp;&nbsp; if (x != NIL &amp;&amp; compEQ(x-&gt;key, key))&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return STATUS_DUPLICATE_KEY;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp; /*随机的计算要插入的值的最高level*/&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newLevel = 0;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rand() &lt; RAND_MAX/2 &amp;&amp; newLevel &lt; MAXLEVEL;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newLevel++);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; /*如果大于当前的level，则更新update数组并更新当前level*/&nbsp; <br />
&nbsp;&nbsp;&nbsp; if (newLevel &gt; list.listLevel) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = list.listLevel + 1; i &lt;= newLevel; i++)&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update[i] = NIL;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.listLevel = newLevel;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; /* 给新节点分配空间，分配newLevel个指针，则这个&nbsp; <br />
&nbsp;&nbsp;&nbsp; 节点的高度就固定了，只有newLevel。更高的层次将&nbsp; <br />
&nbsp;&nbsp;&nbsp; 不会再有这个值*/&nbsp; <br />
&nbsp;&nbsp;&nbsp; if ((x = malloc(sizeof(nodeType) + newLevel*sizeof(nodeType *))) == 0)&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return STATUS_MEM_EXHAUSTED;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; x-&gt;key = key;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; x-&gt;rec = *rec;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; /* 给每层都加上这个值，相当于往链表中插入一个数*/&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt;= newLevel; i++) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x-&gt;forward[i] = update[i]-&gt;forward[i];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update[i]-&gt;forward[i] = x;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; return STATUS_OK;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
&nbsp; <br />
statusEnum delete(keyType key) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; int i;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; nodeType *update[MAXLEVEL+1], *x;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp; /*******************************************&nbsp; <br />
&nbsp;&nbsp;&nbsp; *&nbsp; delete node containing data from list&nbsp; *&nbsp; <br />
&nbsp;&nbsp;&nbsp; *******************************************/&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; /* find where data belongs */&nbsp; <br />
&nbsp;&nbsp;&nbsp; x = list.hdr;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = list.listLevel; i &gt;= 0; i--) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (x-&gt;forward[i] != NIL&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; compLT(x-&gt;forward[i]-&gt;key, key))&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = x-&gt;forward[i];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update[i] = x;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; x = x-&gt;forward[0];&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; if (x == NIL || !compEQ(x-&gt;key, key)) return STATUS_KEY_NOT_FOUND;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; /* adjust forward pointers */&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt;= list.listLevel; i++) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (update[i]-&gt;forward[i] != x) break;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update[i]-&gt;forward[i] = x-&gt;forward[i];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; free (x);&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; /* adjust header level */&nbsp; <br />
&nbsp;&nbsp;&nbsp; while ((list.listLevel &gt; 0)&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &amp;&amp; (list.hdr-&gt;forward[list.listLevel] == NIL))&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.listLevel--;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; return STATUS_OK;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
&nbsp; <br />
statusEnum find(keyType key, recType *rec) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; int i;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; nodeType *x = list.hdr;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp; /*******************************&nbsp; <br />
&nbsp;&nbsp;&nbsp; *&nbsp; find node containing data&nbsp; *&nbsp; <br />
&nbsp;&nbsp;&nbsp; *******************************/&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = list.listLevel; i &gt;= 0; i--) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (x-&gt;forward[i] != NIL&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; compLT(x-&gt;forward[i]-&gt;key, key))&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = x-&gt;forward[i];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; x = x-&gt;forward[0];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; if (x != NIL &amp;&amp; compEQ(x-&gt;key, key)) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *rec = x-&gt;rec;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return STATUS_OK;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; return STATUS_KEY_NOT_FOUND;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
&nbsp; <br />
void initList() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; int i;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp; /**************************&nbsp; <br />
&nbsp;&nbsp;&nbsp; *&nbsp; initialize skip list&nbsp; *&nbsp; <br />
&nbsp;&nbsp;&nbsp; **************************/&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; if ((list.hdr = malloc(&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(nodeType) + MAXLEVEL*sizeof(nodeType *))) == 0) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf ("insufficient memory (initList)\n");&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt;= MAXLEVEL; i++)&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.hdr-&gt;forward[i] = NIL;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; list.listLevel = 0;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
&nbsp; <br />
int main(int argc, char **argv) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; int i, maxnum, random;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; recType *rec;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; keyType *key;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; statusEnum status;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; /* command-line:&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; skl maxnum [random]&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; skl 2000&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; process 2000 sequential records&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; skl 4000 r&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; process 4000 random records&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; maxnum = 20;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; random = argc &gt; 2;&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; initList();&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; if ((rec = malloc(maxnum * sizeof(recType))) == 0) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf (stderr, "insufficient memory (rec)\n");&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; if ((key = malloc(maxnum * sizeof(keyType))) == 0) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf (stderr, "insufficient memory (key)\n");&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; if (random) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* fill "a" with unique random numbers */&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; maxnum; i++) key[i] = rand();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf ("ran, %d items\n", maxnum);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; } else {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; maxnum; i++) key[i] = i;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf ("seq, %d items\n", maxnum);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; maxnum; i++) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = insert(key[i], &amp;rec[i]);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status) printf("pt1: error = %d\n", status);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = maxnum-1; i &gt;= 0; i--) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = find(key[i], &amp;rec[i]);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status) printf("pt2: error = %d\n", status);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; for (i = maxnum-1; i &gt;= 0; i--) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = delete(key[i]);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status) printf("pt3: error = %d\n", status);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp; <br />
}&nbsp; </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/topcoder1234/archive/2010/08/26/5841119.aspx</font></p>
<img src ="http://www.blogjava.net/tinysun/aggbug/333722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2010-10-04 10:33 <a href="http://www.blogjava.net/tinysun/archive/2010/10/04/333722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>small or big edian</title><link>http://www.blogjava.net/tinysun/archive/2010/08/23/329623.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Mon, 23 Aug 2010 02:13:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2010/08/23/329623.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/329623.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2010/08/23/329623.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/329623.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/329623.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">short</span><span style="color: #000000;">&nbsp;s;<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;c[</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">short</span><span style="color: #000000;">)];<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}un;<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;un.s</span><span style="color: #000000;">=</span><span style="color: #000000;">0x0102</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(un.c[</span><span style="color: #000000;">0</span><span style="color: #000000;">]</span><span style="color: #000000;">==</span><span style="color: #000000;">0x01</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">big&nbsp;edian!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(un.c[</span><span style="color: #000000;">1</span><span style="color: #000000;">]</span><span style="color: #000000;">==</span><span style="color: #000000;">0x02</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">small&nbsp;edian!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">}</span></div>
<img src ="http://www.blogjava.net/tinysun/aggbug/329623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2010-08-23 10:13 <a href="http://www.blogjava.net/tinysun/archive/2010/08/23/329623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数组溢出，导致死循环</title><link>http://www.blogjava.net/tinysun/archive/2010/06/03/322612.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Thu, 03 Jun 2010 05:06:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2010/06/03/322612.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/322612.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2010/06/03/322612.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/322612.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/322612.html</trackback:ping><description><![CDATA[<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">#include</span><span style="color: #000000">&lt;</span><span style="color: #000000">stdio.h</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main()&nbsp;<br />
<img id="Codehighlighter1_31_143_Open_Image" onclick="this.style.display='none'; Codehighlighter1_31_143_Open_Text.style.display='none'; Codehighlighter1_31_143_Closed_Image.style.display='inline'; Codehighlighter1_31_143_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_31_143_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_31_143_Closed_Text.style.display='none'; Codehighlighter1_31_143_Open_Image.style.display='inline'; Codehighlighter1_31_143_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_31_143_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_31_143_Open_Text"><span style="color: #000000">{&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;x,y,z;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;a[</span><span style="color: #000000">16</span><span style="color: #000000">];&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(i</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;=</span><span style="color: #000000">16</span><span style="color: #000000">;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;<br />
<img id="Codehighlighter1_94_128_Open_Image" onclick="this.style.display='none'; Codehighlighter1_94_128_Open_Text.style.display='none'; Codehighlighter1_94_128_Closed_Image.style.display='inline'; Codehighlighter1_94_128_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_94_128_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_94_128_Closed_Text.style.display='none'; Codehighlighter1_94_128_Open_Image.style.display='inline'; Codehighlighter1_94_128_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_94_128_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_94_128_Open_Text"><span style="color: #000000">{&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[i]</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">1\n</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
由于函数内部的局部变量是从栈的高地址向低地址分配.<br />
i=16时，数组下标溢出，a[i]引用的其实是i变量，这样，上述循环成为一个死循环。
<img src ="http://www.blogjava.net/tinysun/aggbug/322612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2010-06-03 13:06 <a href="http://www.blogjava.net/tinysun/archive/2010/06/03/322612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一道笔试题。。。</title><link>http://www.blogjava.net/tinysun/archive/2010/06/01/322479.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Tue, 01 Jun 2010 12:07:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2010/06/01/322479.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/322479.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2010/06/01/322479.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/322479.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/322479.html</trackback:ping><description><![CDATA[题目大意：<br />
如果整数大于0则输出1；<br />
等于0则输出0；<br />
小于0则输出1；<br />
要求不能用任何形式的判断语句。<br />
<br />
思路：<br />
设整数N，符号位可以通过如下宏得到：<br />
<font style="background-color: #cde9d1">#define SIGN(N) (N&gt;&gt;(sizeof(N)*8-1)&amp;0x01)</font><br />
那么如果N&gt;0，符号位为0；<br />
如果N=0，符号位为0；<br />
N&lt;0,符号位为1；<br />
这样没有办法区分正数和0！<br />
<br />
如果N&gt;0,N和N-1的符号位之和为0；<br />
N=0，N和N-1的符号位之和为1<br />
N&lt;0,N和N-1的符号位之和为2<br />
这样可以通过查表得到输出了。<br />
<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">stdio.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #008000">//</span><span style="color: #008000">取得符号位</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #008000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">#define</span><span style="color: #000000">&nbsp;SIGN(N)&nbsp;(N&gt;&gt;(sizeof(N)*8-1)&amp;0x01)</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img id="Codehighlighter1_79_86_Open_Image" onclick="this.style.display='none'; Codehighlighter1_79_86_Open_Text.style.display='none'; Codehighlighter1_79_86_Closed_Image.style.display='inline'; Codehighlighter1_79_86_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_79_86_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_79_86_Closed_Text.style.display='none'; Codehighlighter1_79_86_Open_Image.style.display='inline'; Codehighlighter1_79_86_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;T[]</span><span style="color: #000000">=</span><span id="Codehighlighter1_79_86_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_79_86_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">1</span><span style="color: #000000">,</span><span style="color: #000000">0</span><span style="color: #000000">,</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;sign(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x)<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img id="Codehighlighter1_106_178_Open_Image" onclick="this.style.display='none'; Codehighlighter1_106_178_Open_Text.style.display='none'; Codehighlighter1_106_178_Closed_Image.style.display='inline'; Codehighlighter1_106_178_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_106_178_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_106_178_Closed_Text.style.display='none'; Codehighlighter1_106_178_Open_Image.style.display='inline'; Codehighlighter1_106_178_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_106_178_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_106_178_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;index1</span><span style="color: #000000">=</span><span style="color: #000000">SIGN(x);<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;index2</span><span style="color: #000000">=</span><span style="color: #000000">SIGN(x</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">);<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;T[index1</span><span style="color: #000000">+</span><span style="color: #000000">index2];<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main()<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img id="Codehighlighter1_191_243_Open_Image" onclick="this.style.display='none'; Codehighlighter1_191_243_Open_Text.style.display='none'; Codehighlighter1_191_243_Closed_Image.style.display='inline'; Codehighlighter1_191_243_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_191_243_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_191_243_Closed_Text.style.display='none'; Codehighlighter1_191_243_Open_Image.style.display='inline'; Codehighlighter1_191_243_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_191_243_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_191_243_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x</span><span style="color: #000000">=-</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">%d\n</span><span style="color: #000000">"</span><span style="color: #000000">,sign(x));<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
<br />
<img src ="http://www.blogjava.net/tinysun/aggbug/322479.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2010-06-01 20:07 <a href="http://www.blogjava.net/tinysun/archive/2010/06/01/322479.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RMQ问题</title><link>http://www.blogjava.net/tinysun/archive/2010/05/19/321370.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Wed, 19 May 2010 06:35:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2010/05/19/321370.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/321370.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2010/05/19/321370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/321370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/321370.html</trackback:ping><description><![CDATA[<font style="background-color: #cde9d1">http://kmplayer.javaeye.com/blog/575725</font>
<img src ="http://www.blogjava.net/tinysun/aggbug/321370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2010-05-19 14:35 <a href="http://www.blogjava.net/tinysun/archive/2010/05/19/321370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>树状数组 </title><link>http://www.blogjava.net/tinysun/archive/2010/05/08/320371.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Sat, 08 May 2010 12:22:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2010/05/08/320371.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/320371.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2010/05/08/320371.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/320371.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/320371.html</trackback:ping><description><![CDATA[<p>问题提出：已知数组a[],元素个数为n,现在更改a中的元素,要求得新的a数组中i到j区间内的和(1&lt;=i&lt;=j&lt;=n).</p>
<p>思考：对于这个问题,我们可以暴力地来解决,从a[i]一直累加到a[j],最坏的情况下复杂度为O(n),对于m次change&amp;querry,合起来的复杂度为O(m*n),在n或m很大的情况下,这样的复杂度是让人无法忍受的.另外,如果没有元素的变更,我们完全可以存储sum[1,k](k=1,2,&#8230;&#8230;),然后对任意给定的查找区间[i,j],都可以方便的用ans=sum[1,j]-sum[1,i-1],当然这只是没有元素改变的情况下的比较优化的解法.那么对于有元素变更的问题是否有更高效的方法呢?(废话!没有我还写啥?!)可以想一下,每次更改的元素是比较少的,有时候甚至每次只改变一个元素,但是在用暴力方法求区间和的时候,却对区间内所有的元素都累加了一遍,这样其实造成了许多无谓的运算.这时候也许会想到如果能把一些结果存起来会不会减少很多运算?答案是肯定的,但问题是怎么存,存什么?如果存任意区间的话,n比较大的时候不但内存吃不消,而且存储的量太大,不易更改,反而得不偿失;那么也许可以考虑存储特定的一些区间(比如说线段树,其实现在讨论的问题用线段树完全可以解,以后再详细写线段树).那么现在重新回过头来,看下这个问题,我们已经确定了要存储一些特定区间sum的想法,接下来我们要解决的无非是两个问题:1、减少更改元素后对这些区间里的sum值的更改时间.2、减少查找的时间.</p>
<p>好了废话了这么半天,无非是想让自己以及看到的人明白为什么要用树状数组.</p>
<p>接下来正式入题.</p>
<p>首先我们可以借鉴元素不变更问题的优化方法,先得到前i-1项之和and前j项之和,以s[i]表示前i项之和,那么sum[i,j]=s[j]-s[i-1].那么现在的问题已经转化为求前i项之和了.另外,我们已经确定要存储一些特定区间的和,现在就要来揭示这些特定的区间究竟指什么.</p>
<p>在文字说明之前先引入一个非常经典的,在网上找到的树状数组文章里几乎都要出现的一个图片</p>
<p><img height="244" alt="" src="http://images.cnblogs.com/cnblogs_com/yykkciwei/TArry.jpg" width="503" border="0" /></p>
<p>从图中不难发现,c[k]存储的实际上是从k开始向前数k的二进制表示中右边第一个1所代表的数字个元素的和(这么说可能有点拗口,令lowbit为k的二进制表示中右边第一个1所代表的数字,然后c[k]里存的就是从a[k]开始向前数lowbit个元素之和)这么存有什么好处呢?无论是树状数组还是线段树,都用到了分块的思想,而树状数组采用这样的存储结构我想最主要的还是这样方便计算,我们可以用位运算轻松地算出lowbit.分析一下这样做的复杂度:对于更改元素来说,如果第i个元素被修改了,因为我们最终还是要求和,所以可以直接在c数组里面进行相应的更改,如图中的例子,假设更改的元素是a[2],那么它影响到得c数组中的元素只有c[2],c[4],c[8],我们只需一层一层往上修改就可以了,这个过程的最坏的复杂度也不过O(logN);对于查找来说,如查找s[k],只需查找k的二进制表示中1的个数次就能得到最终结果,比如查找s[7],7的二进制表示中有3个1,也就是要查找3次,到底是不是呢,我们来看上图,s[7]=c[7]+c[6]+c[4],可能你还不知道怎么实现这个过程.</p>
<p>还以7为例,二进制为0111,右边第一个1出现在第0位上,也就是说要从a[7]开始向前数1个元素(只有a[7]),即c[7];</p>
<p>然后将这个1舍掉,得到6,二进制表示为0110,右边第一个1出现在第1位上,也就是说要从a[6]开始向前数2个元素(a[6],a[5]),即c[6];</p>
<p>然后舍掉用过的1,得到4,二进制表示为0100,右边第一个1出现在第2位上,也就是说要从a[4]开始向前数4个元素(a[4],a[3],a[2],a[1]),即c[4].</p>
<p>&nbsp;</p>
<p>代码实现:</p>
<div class="cnblogs_code"><img id="Code_Closed_Image_001504" style="display: none" onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_001504').style.display='none'; document.getElementById('Code_Open_Image_001504').style.display='inline'; document.getElementById('Code_Open_Text_001504').style.display='inline';" height="16" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_001504" style="display: inline" onclick="this.style.display='none'; document.getElementById('Code_Open_Text_001504').style.display='none'; getElementById('Code_Closed_Image_001504').style.display='inline'; getElementById('Code_Closed_Text_001504').style.display='inline';" height="16" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span class="cnblogs_code_Collapse" id="Code_Closed_Text_001504" style="display: none">Code</span><span id="Code_Open_Text_001504" style="display: inline"><br />
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;lowbit(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x)</span><span style="color: #008000">//</span><span style="color: #008000">计算lowbit</span><span style="color: #008000"><br />
<img id="Codehighlighter1_28_47_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_28_47_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_28_47_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_28_47_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_28_47_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_28_47_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_28_47_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_28_47_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_28_47_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_28_47_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;x</span><span style="color: #000000">&amp;</span><span style="color: #000000">(</span><span style="color: #000000">-</span><span style="color: #000000">x);<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;add(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i,</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;val)</span><span style="color: #008000">//</span><span style="color: #008000">将第i个元素更改为val</span><span style="color: #008000"><br />
<img id="Codehighlighter1_86_137_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_86_137_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_86_137_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_86_137_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_86_137_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_86_137_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_86_137_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_86_137_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_86_137_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_86_137_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(i</span><span style="color: #000000">&lt;=</span><span style="color: #000000">n)<br />
<img id="Codehighlighter1_102_135_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_102_135_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_102_135_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_102_135_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_102_135_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_102_135_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_102_135_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_102_135_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_102_135_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_102_135_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c[i]</span><span style="color: #000000">+=</span><span style="color: #000000">val;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="color: #000000">+=</span><span style="color: #000000">lowbit(i);<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;sum(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i)</span><span style="color: #008000">//</span><span style="color: #008000">求前i项和</span><span style="color: #008000"><br />
<img id="Codehighlighter1_160_229_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_160_229_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_160_229_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_160_229_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_160_229_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_160_229_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_160_229_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_160_229_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_160_229_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_160_229_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;s</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(i</span><span style="color: #000000">&gt;</span><span style="color: #800080">0</span><span style="color: #000000">)<br />
<img id="Codehighlighter1_185_216_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_185_216_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_185_216_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_185_216_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_185_216_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_185_216_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_185_216_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_185_216_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_185_216_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_185_216_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s</span><span style="color: #000000">+=</span><span style="color: #000000">c[i];<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="color: #000000">-=</span><span style="color: #000000">lowbit(i);<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;s;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}<br />
<br />
<font style="background-color: #cde9d1">http://www.cnblogs.com/yykkciwei/archive/2009/05/08/1452889.html</font></span></span></span></div>
<img src ="http://www.blogjava.net/tinysun/aggbug/320371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2010-05-08 20:22 <a href="http://www.blogjava.net/tinysun/archive/2010/05/08/320371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Trie—单词查找树 转</title><link>http://www.blogjava.net/tinysun/archive/2010/05/02/319881.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Sun, 02 May 2010 03:35:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2010/05/02/319881.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/319881.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2010/05/02/319881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/319881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/319881.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;简介Trie，又称单词查找树、前缀树，是&nbsp;简介 Trie，又称单词查找树、前缀树，是一种哈希树的变种。应用于字符串的统计与排序，经常被搜索引擎系统用于文本词频统计。含有单词&#8220;tea&#8221;&#8220;tree&#8221;&#8220;A&#8221;&#8220;ZSU&#8221;的一棵Trie。l&nbsp;性质n&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/tinysun/archive/2010/05/02/319881.html'>阅读全文</a><img src ="http://www.blogjava.net/tinysun/aggbug/319881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2010-05-02 11:35 <a href="http://www.blogjava.net/tinysun/archive/2010/05/02/319881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构小结</title><link>http://www.blogjava.net/tinysun/archive/2009/12/13/305780.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Sun, 13 Dec 2009 05:15:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2009/12/13/305780.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/305780.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2009/12/13/305780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/305780.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/305780.html</trackback:ping><description><![CDATA[<p><font style="background-color: #cce8cf">数据结构和算法到底有什么用？</font></p>
<p><font style="background-color: #cce8cf">数据结构是对在计算机内存中（有时在磁盘中）的数据的一种安排。数据结构包括数组、链表、栈、二叉树、哈希表等等。算法对这些结构中的数据进行各种处理。例如，查找一条特殊的数据项或对数据进行排序。</font></p>
<p><font style="background-color: #cce8cf">掌握这些知识以后可以解决哪些问题呢？</font></p>
<p><font style="background-color: #cce8cf">现实世界数据存储</font></p>
<p><font style="background-color: #cce8cf">程序员的工具</font></p>
<p><font style="background-color: #cce8cf">建模</font></p>
<p><font style="background-color: #cce8cf">数据结构的特性：</font></p>
<p><font style="background-color: #cce8cf">数组：优点是插入快，如果知道下标，可以非常快地存取。缺点是查找慢，删除慢，大小固定。</font></p>
<p><font style="background-color: #cce8cf">有序数组：优点是比无序的数据查找快。缺点是删除和插入慢，大小固定。</font></p>
<p><font style="background-color: #cce8cf">栈：优点是提供后进先出方式的存取。缺点是存取其他项很慢。</font></p>
<p><font style="background-color: #cce8cf">队列：提供先进先出方式的存取。缺点是存取其他项很慢。</font></p>
<p><font style="background-color: #cce8cf">链表：优点是插入快，删除快。缺点是查找慢。</font></p>
<p><font style="background-color: #cce8cf">二叉树：优点是查找、插入、删除都快（如果树保持平衡）。缺点是删除算法复杂。</font></p>
<p><font style="background-color: #cce8cf">红－黑树：查找、插入、删除都快。树总是平衡的。缺点是算法复杂。</font></p>
<p><font style="background-color: #cce8cf">2-3-4树：优点是查找、插入、删除都快。树总是平衡的。类似的树对磁盘存储有用。缺点是算法复杂。</font></p>
<p><font style="background-color: #cce8cf">哈希表：优点是如果关键字已知则存取极快。插入快。缺点是删除慢，如果不知道关键字则存取很慢，对存储空间使用不充分。</font></p>
<p><font style="background-color: #cce8cf">堆：优点是插入、删除快，对最大数据项的存取很快。缺点是对其他数据项存取慢。</font></p>
<p><font style="background-color: #cce8cf">图：优点是对现实世界建模。缺点是有些算法且复杂。</font></p>
<p><font style="background-color: #cce8cf">对于大多数数据结构来说，都需要知道如何插入一条新的数据项，如何寻找某一特定的数据项，如何删除某一特定的数据项，还需要知道如何迭代地访问某一数据结构中的各数据项，以便进行显示或其他操作。另一种重要的算法范畴是排序。</font></p>
<p><font style="background-color: #cce8cf">&nbsp;</font></p>
<p><font style="background-color: #cce8cf">&nbsp;</font></p>
<p><font style="background-color: #cce8cf">&nbsp;</font></p>
<p><font style="background-color: #cce8cf">一、通用数据结构：数组，链表，树，哈希表</font></p>
<p><font style="background-color: #cce8cf">它们被称之为通用的数据结构是因为它们通过关键字的值来存储并查找数据，这一点在通用数据库程序中常见到（栈等特殊结构正好相反，它们只允许存取一定的数据项）。</font></p>
<p><font style="background-color: #cce8cf">通用数据结构可以完全按照速度的快慢来分类：</font></p>
<p><font style="background-color: #cce8cf">数组和链表是最慢的，树相对较快，哈希表是最快的。</font></p>
<p><font style="background-color: #cce8cf">但并不是使用最快的结构永远是最好的方案。这些最快的结构也有缺陷，首先，它们的程序在不同程度上比数组和链表的复杂;其次，哈希表要求预先知道要存储多少数据，数据对存储空间的利用率也不是非常高。普通的二叉树对顺序的数据来说，会变成缓慢的O(N)级操作;而平衡树虽然避免了上述的问题，但是它的程序编制起来却比较困难。</font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">数组在下列情况下很有用：</font></p>
<p><font style="background-color: #cce8cf">数据量较小</font></p>
<p><font style="background-color: #cce8cf">数据量的大小事先可预测</font></p>
<p><font style="background-color: #cce8cf">如果存储空间足够大的话，可以放松第二条，创建一个足够大的数组来应付所有可以预见的数据输入。</font></p>
<p><font style="background-color: #cce8cf">如果插入速度很重要的话，使用无序数组。如果查找速度很重要的话，使用有序数组，并用二分查找。数组元素的删除总是很慢，这是由于为了填充空出来的单元，平均半数以上的数组元素要被移动。在有序数组中的遍历是很快的，而在无序的数组不支持这种功能。</font></p>
<p><font style="background-color: #cce8cf">向量（如Java中的向量类）是一种当数据太满时可以自己扩充空间的数组。向量可以应用于数据量不可预知的情况下。然而，在向量扩充时，要将旧的数据拷入一个新的空间中，这一过程会造成程序明显的周期性暂停。</font></p>
<p><font style="background-color: #cce8cf">如果需要存储的数据量不能预知或者需要频繁地插入删除数据元素时，考虑使用链表。当有新的元素加入时，链表就开辟新的所需要的空间，所以它甚至可以占满全部可用内存;在删除过程中没有必要像数组那样添补&#8220;空洞&#8221;。</font></p>
<p><font style="background-color: #cce8cf">&nbsp;</font></p>
<p><font style="background-color: #cce8cf">&nbsp;</font></p>
<p><font style="background-color: #cce8cf">二、专用数据结构：栈，队列，优先级队列</font></p>
<p><font style="background-color: #cce8cf">三、排序：插入排序，希尔排序，快速排序，归并排序，堆排序</font></p>
<p><font style="background-color: #cce8cf">四、图：邻接矩阵，邻接表</font></p>
<p><font style="background-color: #cce8cf">五、外部存储：顺序存储，索引文件，B-树，哈希方法</font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/adcxf/archive/2008/08/06/2775636.aspx</font></p>
<img src ="http://www.blogjava.net/tinysun/aggbug/305780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2009-12-13 13:15 <a href="http://www.blogjava.net/tinysun/archive/2009/12/13/305780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用牛顿迭代法求平方根(转)</title><link>http://www.blogjava.net/tinysun/archive/2008/11/23/242126.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Sun, 23 Nov 2008 10:32:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2008/11/23/242126.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/242126.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2008/11/23/242126.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/242126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/242126.html</trackback:ping><description><![CDATA[<p>求n的平方根，先假设一猜测值<code class="math">X<sub>0</sub> = 1</code>，然后根据以下公式求出<code class="math">X<sub>1</sub></code>，再将<code class="math">X<sub>1</sub></code>代入公式右边，继续求出<code class="math">X<sub>2</sub></code>&#8230;通过有效次迭代后即可求出n的平方根，<code class="math">X<sub>k+1</sub></code></p>
<p class="center"><img height="37" alt=" x_(k+1)=1/2(x_k+n/(x_k))" src="http://pic.yupoo.com/punkid/5286852a16f4/chsf3aqv.jpg" width="111" border="0" /></p>
<p>先让我们来验证下这个巧妙的方法准确性，来算下2的平方根 (Computed by Mathomatic)<br />
</p>
<pre>1-&gt; x_new = ( x_old + y/x_old )/2
y
(x_old + -----)
x_old
#1: x_new = ---------------
2
1-&gt; calculate x_old 1
Enter y: 2
Enter initial x_old: 1
<strong class="red"> x_new = 1.5</strong>
1-&gt; calculate x_old 2
Enter y: 2
Enter initial x_old: 1
<strong class="red"> x_new = 1.4166666666667</strong>
1-&gt; calculate x_old 3
Enter y: 2
Enter initial x_old: 1
<strong class="red"> x_new = 1.4142156862745</strong>
1-&gt; calculate x_old 10
Enter y: 2
Enter initial x_old: 1
Convergence reached after 6 iterations.
<strong class="red"> x_new = 1.4142135623731</strong>
...
</pre>
<p>可见，随着迭代次数的增加，运算值会愈发接近真实值。很神奇的算法，可是怎么来的呢? 查了下<a title="Wikipedia: Newton's method" href="http://en.wikipedia.org/wiki/Newton%27s_method">wikipedia</a>和<a title="Wolfram: Newton's Iteration" href="http://mathworld.wolfram.com/NewtonsIteration.html">wolfram</a>，原来算法的名字叫Newton&#8217;s Iteration (牛顿迭代法)。</p>
<p>下面是极其<span lang="ja" xml:lang="ja">つまらない</span>(boring)的数理介绍，不喜欢数学的言下之意也就是绝大部分人可以略过了。</p>
<h3>简单推导</h3>
<p>假设<code class="math">f(x)</code>是关于<code class="math">X</code>的函数:</p>
<p><img height="247" alt="An illustration of one iteration of Newton's method" src="http://pic.yupoo.com/punkid/1773352a25d8/9lcgjzet.jpg" width="300" border="0" /></p>
<p>求出<code class="math">f(x)</code>的一阶导，即斜率:</p>
<p class="center"><img height="48" alt="f'(x_{n}) = \frac{ \mathrm{rise} }{ \mathrm{run} } = \frac{ \mathrm{\Delta y} }{ \mathrm{\Delta x} } = \frac{ f( x_{n} ) - 0 }{ x_{n} - x_{n+1} } = \frac{0 - f(x_{n})}{(x_{n+1} - x_{n})}\,\!" src="http://pic.yupoo.com/punkid/1847652a26a3/zcbz5a4b.jpg" width="409" border="0" /></p>
<p>简化等式得到:</p>
<p class="center"><img height="37" alt=" x_(n+1)=x_n-(f(x_n))/(f^'(x_n)) " src="http://pic.yupoo.com/punkid/0290752a2462/t4yu9w45.jpg" width="108" border="0" /></p>
<p>然后利用得到的最终式进行迭代运算直至求到一个比较精确的满意值，为什么可以用迭代法呢?理由是中值定理(Intermediate Value Theorem):</p>
<blockquote>
<p>如果<code class="math">f</code>函数在闭区间<code class="math">[a,b]</code>内连续，必存在一点<code class="math">x</code>使得<code class="math">f(x) = c</code>，<code class="math">c</code>是函数<code class="math">f</code>在闭区间<code class="math">[a,b]</code>内的一点 </p>
</blockquote>
<p>我们先猜测一<code class="math">X</code>初始值，例如1，当然地球人都知道除了1本身之外任何数的平方根都不会是1。然后代入初始值，通过迭代运算不断推进，逐步靠近精确值，直到得到我们主观认为比较满意的值为止。例如要求768的平方根，因为<code class="math">25<sup>2</sup> = 625</code>，而<code class="math">30<sup>2</sup> = 900</code>，我们可先代入一猜测值26，然后迭代运算，得到较精确值:27.7128。</p>
<p>回到我们最开始的那个&#8221;莫名其妙&#8221;的公式，我们要求的是<code class="math">N</code>的平方根，令<code class="math">x<sup>2</sup> = n</code>，假设一关于<code class="math">X</code>的函数<code class="math">f(x)</code>为:</p>
<p class="center"><code class="math">f(X) = X<sup>2</sup> - n</code></p>
<p>求<code class="math">f(X)</code>的一阶导为:</p>
<p class="center"><code class="math">f'(X) = 2X</code></p>
<p>代入前面求到的最终式中:</p>
<p class="center"><code class="math">X<sub>k+1</sub> = X<sub>k</sub> - (X<sub>k</sub><sup>2</sup> - n)/2X<sub>k</sub></code></p>
<p>化简即得到我们最初提到的那个求平方根的神奇公式了:</p>
<p class="center"><img height="37" alt=" x_(k+1)=1/2(x_k+n/(x_k))" src="http://pic.yupoo.com/punkid/5286852a16f4/chsf3aqv.jpg" width="111" border="0" /></p>
<h3>用泰勒公式推导</h3>
<p>我之前介绍过在<em>The Art and Science of C</em>一书中有用到<a title="The Art and Science of C  阅读笔记 II" href="http://blog.punkid.cn/2007/07/19/the-art-and-science-of-c-note-two/">泰勒公式求平方根的算法</a>，其实牛顿迭代法也可以看作是泰勒公式(Taylor Series)的简化，先回顾下泰勒公式:</p>
<p class="center"><img height="23" alt="f(x_0+epsilon)=f(x_0)+f^'(x_0)epsilon+1/2f^('')(x_0)epsilon^2+.... " src="http://pic.yupoo.com/punkid/1697952a1ea6/0k7gu191.jpg" width="269" border="0" /></p>
<p>仅保留等式右边前两项:</p>
<p class="center"><img height="16" alt="f(x_0+epsilon) approx f(x_0)+f^'(x_0)epsilon." src="http://pic.yupoo.com/punkid/5762152a1f4e/y8nndhdy.jpg" width="160" border="0" /></p>
<p>令<code class="math">f(X<sub>0</sub>+&#949;) = 0</code>，得到:</p>
<p class="center"><img height="37" alt="epsilon_0=-(f(x_0))/(f^'(x_0))" src="http://pic.yupoo.com/punkid/3476952a2106/n7gfjyvw.jpg" width="82" border="0" /></p>
<p>再令<code class="math">X<sub>1</sub> = X<sub>0</sub> + &#949;<sub>0</sub></code>，得到<code class="math">&#949;<sub>1</sub></code>&#8230;依此类推可知:</p>
<p class="center"><img height="37" alt="epsilon_n=-(f(x_n))/(f^'(x_n))" src="http://pic.yupoo.com/punkid/3903852a21fb/kwl644nf.jpg" width="82" border="0" /></p>
<p>转化为:</p>
<p class="center"><img height="37" alt=" x_(n+1)=x_n-(f(x_n))/(f^'(x_n)) " src="http://pic.yupoo.com/punkid/0290752a2462/t4yu9w45.jpg" width="108" border="0" /></p>
<h3>引申</h3>
<p>从推导来看，其实牛顿迭代法不仅可以用来求平方根，还可以求立方根，甚至更复杂的运算。</p>
<p>同样，我们还可以利用C语言来实现下那个最简单的求平方根的公式(尽管我们可以直接用<code>sqrt()</code>完成)</p>
<pre>#include &lt;stdio.h&gt;
#include &lt;math.h&gt;
#define N 768
main() {
float x=1;
int i;
for (i=1;i&lt;=1000;i++) {  // recursion times : 1000
x = (x + N/x)/2;
}
printf("The square root of %d is %f\n",N,x);
}
</pre>
 <img src ="http://www.blogjava.net/tinysun/aggbug/242126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2008-11-23 18:32 <a href="http://www.blogjava.net/tinysun/archive/2008/11/23/242126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>