要实现整个树,我们只要调用函数时用一个空字符串作为 $parent 和 $level = 0: display_children('',0); 函数返回了我们的食品店的树状图如下:

 

Food
Fruit
Red
Cherry
Yellow
Banana
Meat
Beef
Pork

注意如果你只想看一个子树,你可以告诉函数从另一个节点开始。例如,要显示“Fruit”子树,你只要display_children('Fruit',0);

The Path to a Node节点的路径

利用差不多的函数,我们也可以查询某个节点的路径如果你只知道这个节点的名字或者ID。例如,“Cherry”的路径是“Food”> “Fruit”>“Red”。要获得这个路径,我们的函数要获得这个路径,这个函数必须从最深的层次开始:“Cheery”。但后查找这个节点的父 节点,并添加到路径中。在我们的例子中,这个父节点是“Red”。如果我们知道“Red”是“Cherry”的父节点。

这个函数现在返回了指定节点的路径。他把路径作为数组返回,这样我们可以使用print_r(get_path('Cherry')); 来显示,其结果是:

Array
(
   [0] => Food
   [1] => Fruit
   [2] => Red)

 

不足

正如我们所见,这确实是一个很好的方法。他很容易理解,同时代码也很简单。但是邻接列表模型的缺点在哪里呢?在大多数编程语言中,他运行很慢,效率很差。这主要是“递归”造成的。我们每次查询节点都要访问数据库。

每次数据库查询都要花费一些时间,这让函数处理庞大的树时会十分慢。

造成这个函数不是太快的第二个原因可能是你使用的语言。不像Lisp这类语言,大多数语言不是针对递归函数设计的。对于每个节点,函数都要调用他自 己,产生新的实例。这样,对于一个4层的树,你可能同时要运行4个函数副本。对于每个函数都要占用一块内存并且需要一定的时间初始化,这样处理大树时递归 就很慢了。

改进前序遍历树

现在,让我们看另一种存储树的方法。递归可能会很慢,所以我们就尽量不使用递归函数。我们也想尽量减少数据库查询的次数。最好是每次只需要查询一次。

我们先把树按照水平方式摆开。从根节点开始(“Food”),然后他的左边写上1。然后按照树的顺序(从上到下)给“Fruit”的左边写上2。这 样,你沿着树的边界走啊走(这就是“遍历”),然后同时在每个节点的左边和右边写上数字。最后,我们回到了根节点“Food”在右边写上18。下面是标上 了数字的树,同时把遍历的顺序用箭头标出来了。

我们称这些数字为左值和右值(如,“Food”的左值是1,右值是18)。正如你所见,这些数字按时了每个节点之间的关系。因为“Red”有3和6 两个值,所以,它是有拥有1-18值的“Food”节点的后续。同样的,我们可以推断所有左值大于2并且右值小于11的节点,都是有2-11的 “Food”节点的后续。这样,树的结构就通过左值和右值储存下来了。这种数遍整棵树算节点的方法叫做“改进前序遍历树”算法。

 

在继续前,我们先看看我们的表格里的这些值:

注意单词“left”和“right”在SQL中有特殊的含义。因此,我们只能用“lft”和“rgt”来表示这两个列。(译注——其实Mysql 中可以用“`”来表示,如“`left`”,MSSQL中可以用“[]”括出,如“[left]”,这样就不会和关键词冲突了。)同样注意这里我们已经不需要“parent”列了。我们只需要使用lft和rgt就可以存储树的结构。

获取树

如果你要通过左值和右值来显示这个树的话,你要首先标识出你要获取的那些节点。例如,如果你想获得“Fruit”子树,你要选择那些左值在2到11的节点。用SQL语句表达:

SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;

这个会返回:

好吧,现在整个树都在一个查询中了。现在就要像前面的递归函数那样显示这个树,我们要加入一个ORDER BY子句在这个查询中。如果你从表中添加和删除行,你的表可能就顺序不对了,我们因此需要按照他们的左值来进行排序。

SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;

就只剩下缩进的问题了。

要显示树状结构,子节点应该比他们的父节点稍微缩进一些。我们可以通过保存一个右值的一个栈。每次你从一个节点的子节点开始时,你把这个节点的右值 添加到栈中。你也知道子节点的右值都比父节点的右值小,这样通过比较当前节点和栈中的前一个节点的右值,你可以判断你是不是在显示这个父节点的子节点。当 你显示完这个节点,你就要把他的右值从栈中删除。要获得当前节点的层数,只要数一下栈中的元素。

 

 

如果运行这段代码,你可以获得和上一部分讨论的递归函数一样的结果。而这个函数可能会更快一点:他不采用递归而且只是用了两个查询

节点的路径

有了新的算法,我们还要另找一种新的方法来获得指定节点的路径。这样,我们就需要这个节点的祖先的一个列表。

由于新的表结构,这不需要花太多功夫。你可以看一下,例如,4-5的“Cherry”节点,你会发现祖先的左值都小于4,同时右值都大于5。这样,我们就可以使用下面这个查询:

SELECT title FROM tree WHERE lft < 4 AND rgt > 5 ORDER BY lft ASC;

注意,就像前面的查询一样,我们必须使用一个ORDER BY子句来对节点排序。这个查询将返回:

+-------+
| title |
+-------+
| Food  |
| Fruit |
| Red   |
+-------+

我们现在只要把各行连起来,就可以得到“Cherry”的路径了。

有多少个后续节点?How Many Descendants

如果你给我一个节点的左值和右值,我就可以告诉你他有多少个后续节点,只要利用一点点数学知识。

因为每个后续节点依次会对这个节点的右值增加2,所以后续节点的数量可以这样计算:

descendants = (right – left - 1) / 2

利用这个简单的公式,我可以立刻告诉你2-11的“Fruit”节点有4个后续节点,8-9的“Banana”节点只是1个子节点,而不是父节点。

自动化树遍历

现在你对这个表做一些事情,我们应该学习如何自动的建立表了。这是一个不错的练习,首先用一个小的树,我们也需要一个脚本来帮我们完成对节点的计数。

让我们先写一个脚本用来把一个邻接列表转换成前序遍历树表格。

 

这是一个递归函数。你要从rebuild_tree('Food',1); 开始,这个函数就会获取所有的“Food”节点的子节点。

如果没有子节点,他就直接设置它的左值和右值。左值已经给出了,1,右值则是左值加1。如果有子节点,函数重复并且返回最后一个右值。这个右值用来作为“Food”的右值。

递归让这个函数有点复杂难于理解。然而,这个函数确实得到了同样的结果。他沿着树走,添加每一个他看见的节点。你运行了这个函数之后,你会发现左值和右值和预期的是一样的(一个快速检验的方法:根节点的右值应该是节点数量的两倍)。

添加一个节点

我们如何给这棵树添加一个节点?有两种方式:在表中保留“parent”列并且重新运行rebuild_tree() 函数——一个很简单但却不是很优雅的函数;或者你可以更新所有新节点右边的节点的左值和右值。

第一个想法比较简单。你使用邻接列表方法来更新,同时使用改进前序遍历树来查询。如果你想添加一个新的节点,你只需要把节点插入表格,并且设置好parent列。然后,你只需要重新运行rebuild_tree() 函数。这做起来很简单,但是对大的树效率不高。

第二种添加和删除节点的方法是更新新节点右边的所有节点。让我们看一下例子。我们要添加一种新的水果——“Strawberry”,作为“Red” 的最后一个子节点。首先,我们要腾出一个空间。“Red”的右值要从6变成8,7-10的“Yellow”节点要变成9-12,如此类推。更新“Red” 节点意味着我们要把所有左值和右值大于5的节点加上2。

我们用一下查询:

 

UPDATE tree SET rgt=rgt+2 WHERE rgt>5;
UPDATE tree SET lft=lft+2 WHERE lft>5;

现在我们可以添加一个新的节点“Strawberry”来填补这个新的空间。这个节点左值为6右值为7。

INSERT INTO tree SET lft=6, rgt=7, title='Strawberry';

如果我们运行display_tree() 函数,我们将发现我们新的“Strawberry”节点已经成功地插入了树中:

Food
 Fruit
   Red
     Cherry
     Strawberry
   Yellow
     Banana
 Meat
   Beef
   Pork

缺点

首先,改进前序遍历树算法看上去很难理解。它当然没有邻接列表方法简单。然而,一旦你习惯了左值和右值这两个属性,他就会变得清晰起来,你可以用这个技术来完成临街列表能完成的所有事情,同时改进前序遍历树算法更快。当然,更新树需要很多查询,要慢一点,但是取得节点却可以只用一个查询。

总结

你现在已经对两种在数据库存储树方式熟悉了吧。虽然在我这儿改进前序遍历树算法性能更好,但是也许在你特殊的情况下邻接列表方法可能表现更好一些。这个就留给你自己决定了

最后一点:就像我已经说得我部推荐你使用节点的标题来引用这个节点。你应该遵循数据库标准化的基本规则。我没有使用数字标识是因为用了之后例子就比较难读。

算法3

在MYSQL中,数据表大致上是
CREATE TABLE Table_Types
(
 id INTEGER NOT NULL AUTO_INCREMENT,
 parent_id INTEGER,
 node VARCHAR(255),
 PRIMARY KEY (id)
)
如上图,紫色的是数据记录的ID号,框内的数字是每条记录的node字段,记录了该记录的父ID和父ID的父ID和...
这样,假如我们要在ID为7的记录下,插入一条新ID为13的记录,新记录的node就是1,2,7,13
要找一个节点下的所有子节点,就无需用递归,只要一个SQL。
如“查ID为2记录下所有子节点”
select * from Table_Types where node like "1,2,%"
大家探讨一下,该算法的有效性和不足!
上次看到的左右值的算法,虽然在搜索方面很不错,但是如果是插入频繁的应用,性能就很差了,因为每次插入新节点都需要update该父节点以下 的所有记录。的右值。而上面这个算法,对插入操作尤其简单,只要找到父ID的根下来就可以了。搜索方面好像也还不错,都是避免了递归。

无论你要构建自己的论坛,在你的网站上发布消息还是书写自己的CMS程序,你都会遇到要在数据库中存储层次数据的情况。同时,除非你使用一种像XML的数据库,否则关系数据库中的表都不是层次结构的,他们只是一个平坦的列表。所以你必须找到一种把层次数据库转化的方法。

存储树形结构是一个很常见的问题,他有好几种解决方案。主要有两种方法:邻接列表模型和改进前序遍历树算法

在本文中,我们将探讨这两种保存层次数据的方法。我将举一个在线食品店树形图的例子。这个食品店通过类别、颜色和品种来组织食品。树形图如下:

本文包含了一些代码的例子来演示如何保存和获取数据。我选择PHP来写例子,因为我常用这个语言,而且很多人也都使用或者知道这个语言。你可以很方便地把它们翻译成你自己用的语言。

邻接列表模型(The Adjacency List Model)

我们要尝试的第一个——也是最优美的——方法称为“邻接列表模型”或称为“递归方法”。它是一个很优雅的方法因为你只需要一个简单的方法来在你的树中进行迭代。在我们的食品店中,邻接列表的表格如下:

如你所见,对每个节点保存一个“父”节点。我们可以看到“Pear”是“Green”的一个子节点,而后者又是“Fruit”的子节点,如此类推。 根节点,“Food”,则他的父节点没有值。为了简单,我只用了“title”值来标识每个节点。当然,在实际的数据库中,你要使用数字的ID。

显示树

现在我们已经把树放入数据库中了,得写一个显示函数了。这个函数将从根节点开始——没有父节点的节点——同时要显示这个节点所有的子节点。对于这些子节点,函数也要获取并显示这个子节点的子节点。然后,对于他们的子节点,函数还要再显示所有的子节点,然后依次类推。

也许你已经注意到了,这种函数的描述,有一种普遍的模式。我们可以简单地只写一个函数,用来获得特定节点的子节点。这个函数然后要对每个子节点调用自身来再次显示他们的子节点。这就是“递归”机制,因此称这种方法叫“递归方法”。

我最近一直在阅读一些关于Google Adsense技巧的论坛和博客,我觉得有必要将这些技巧都集中整理在一个地方,同时我也写了几个我自己的诀窍。我们开头先将一些基本的一般性常识,然后再逐步讨论一些更具体的主题。
建立一个帝国?当你决定成为一个网站广告发布者时,你会陷两个不同类型的怪圈:发布100个每天赚1美元的网站。发布1个每天赚100美元的网站。
目前的现实是,大部分人最终会成为这两者之一。拥有100个网站会让你忙于维护、管理以及内容建设。拥有1个网站会让你接受各种各样的波动和变化(搜索引擎算法变化、市场发展趋势变化等)。你可以制定适合你自己的计划,但必须是在刚开始确定方向的时候,而不是在快要结束的时候。
广泛还是专一
你可以围绕一些广泛或者专一的话题来建设你的网站,一般来说,内容专一的网站更适合Adsense.其次,专注某一焦点写作可以让你很自然的成为那个领域的专家,还有可能使你成为你所在领域的权威。
如果你是第一次尝试建立一个Adsense网站,那么做一些你喜欢的内容,这将使得整个过程变得容易得多,没有太多痛苦的任务。你还应该确保你的话题足够多,你的费用支出能控制在令你能够接受的水平。你可能很喜爱中世纪的民间舞蹈,但是使用这个主题的广告商实在太少(实际上为零)。
一旦你建立了一个运行AdSense的网站,你可能会想尝试一些高价关键字,甚至想要去购买一些高价关键字的列表。但某些危险可能就会随之而来。首先远离这种欺诈性的点击才能让你挣到大钱,其次,这种行为扭曲了条款上规定的供求关系。每个人都想要他们的网站上的广告点击高于每个点击35美元,但有多少广告客户愿意付出那么多呢,实在是相当有限。此外,这种流量的竞争将使得竞争加剧。所以,如果你赶不上强大的对手,那么就不要试图与其竞争。如果你已经足够强大,那样才会有机会。我已经使用了一个cashkeywords.com提供的高关键字报告,并对结果很满意。
新网站、文件和维护
当你新建一个网站的时候,请在网站完成之前不要放置AdSense.事实上,我自己做法是彻底,知道我的网站已经建立好了内部链接并且已经获得了流量,才开通AdSense.如果你架设一个内容不多的网站时,你的AdSense几乎肯定会显示和主题无关的广告,对于现有网站的新文件,特别是全新或不同的话题来说通常都是这样的,Google的爬虫大概要几天或者几周的时间才能重新访问你的网页并得到准确的针对性广告。提示:如果你能从不同的IP地址获得大量的流量,这个过程会加速。
我喜欢使用include文件的方式建立网站,我将页眉、页脚和导航放在公用文件中。这样的网站会变得易于管理和维护。我还喜欢将我的AdSense代码也放在include文件中,如果我想要修改我的AdSense代码,我只需要修改一个文件即可。提示:我还会通过程序来实现打开/关闭Adsense,我可以设置一个全局变量,通过修改其数值来决定我的AdSense广告是显示还是消失。
管理URL渠道
AdSense渠道是一个用于方便统计的区域。你可以设置URL渠道来比较不同网站,你也可以为每个URL设置子渠道。最后你设置的渠道会是这样子的:
domain1.com - 728 横幅
domain1.com - 336 矩形
domain1.com - 文本连接
domain2.com - 728 横幅
domain2.com - 图片横幅
domain2.com - 336 矩形
domain3.com - 300 矩形
虽然渠道可以让你知道哪些人点击了哪里,但是它的报告有点靠不住,你的总数永远是正确的,但是如果你以渠道的方式查看报告会发现有些数据会显示多次,但是累加起来的总数对不上。这使得情况变得很混乱,所以你还是要考虑一下是否真的需要这种情况的详细报告。提示:至少,你想知道某个网站是否产生了收入,请务必将其输入URL渠道。
网站设计和集成

一旦你决定将AdSense放到你的网站上,你就必须考虑一下如何放置。如果这是一个新站点,那还简单一些,如果是一个现有的网站,那会比较麻烦。虽然有些人做不到这一点,但大多数情况下我会说,如果你只是将AdSense代码复制到网站,你得到的将是一个怪胎。虽然每个网站的风格都是不同的,但是Google已经发布了一些图示表明最佳的优化地点。毫无疑问,页面的中心和左边是最佳点,现在,我已经将广告放在了正确的位置,但是你还应该知道,为什么要放在那里,如果效果不好,如何进行修改调整。
Google还发布了一些具有较高性能的广告大小方案:
336 × 280大矩形
300 × 250内嵌矩形
160 × 600摩天大楼
在我的网站上,我使用336的矩形和160的摩天大楼。我的另一个表现最好的广告尺寸是728的横幅,我并不常使用300的矩形广告。所以,你只要能将广告更好的集成到你的网站就最好,位置的变化有时能产生戏剧性的效果。提示:对于新站点或者新布局来说,你应该对每个广告位置建立自己的渠道,同时不断观察用户的习惯和行为。
另一个提高点击率的技巧是将Adsense广告融合到内容中去。例如,你内容的颜色是黑色,那么去掉AdSense广告边框并使得标题、文字和链接都是黑色。提示:尝试改变一下你网页超级链接为一个高对比度的颜色(例如深红或者深蓝),然后将AdSense广告的标题也修改为同样的颜色。
有一个地方,我发现混淆广告和内容不起作用,那就是论坛,特别对于那种具有较高粘性的论坛。一个小技巧是将广告的颜色甚至位置进行随即变换,正确处理广告位置和颜色是一门学问,你要知道如何配置广告同时还不能让访问者厌烦,记住最好是500个用户产生1%的点击率,千万不要50个用户产生5%的点击率。提示:对于论坛来说请尝试将广告放在第一个主帖的下方。
使用图片
另一个最新的“诀窍”是使用图片,将图片放在AdSense的上面或者下面的位置(译者注:这种方法可能违反了最新的AdSense计划政策),使用这种方法曾经在某些论坛上讨论过,很多人谈到点击率翻了两翻。最基本的设置是将你的AdSense广告和图像基本上成为直线。这是否属于欺诈或诱骗点击有一定争议,显然如果使用四个闪烁的箭头放在广告旁将是“引诱用户点击”,违反了AdSense条款,然而如果使用笔记本电脑图片搭配笔记本电脑广告是不是欺诈呢?这需要你自己来判断,Google和广告商的看法也是很重要的,如果你不能确定广告形式是否有问题,那么最好发邮件给Google让他们来看一下。
使用图片的方法我已经用了,而且可以告诉你这挺有用,如果你的图片和广告匹配的很好,那么你能得到最好的效果。例如,如果你的广告是关于苹果派的,那么就要使用一个新鲜出炉的苹果派照片而不是奶酪、苹果电脑、红衣女郎或者红色苹果等等。提示:不要将自己限制在固定大小的广告单元上,应该在其他大小的广告上也可以用,例如336矩形。(补充,在这个问题上我得到了一些批评,我也不能确认我说的是否能实现,不过最好不要使用很容易识别品牌或者产品的图片,使用一些具有通用特性的图片可能更合适一些)。
多个广告单元
另一种增加广告收入的方法是使用多个广告单元。根据Google的计划政策,你可以在一个页面放置不超过三个广告单元。类似标准的搜索结果一样,最高价的广告单元将首先显示,其次是价格较低的。如果你有足够的广告位,那么就将三个广告单元全用上。不过,你要注意把握收益率,假设当前你能得到60%的收入(按照每个0.05美元的点击你获得0.03美元计算),如果来自第三个广告单元的广告仅仅让你得到3到5美分,你应该将其从网页上删除。因为这个地方不能让你的广告单元体现价值。如果一个广告单元有很高的点击率和点击流量,你应该确保最高价的广告在那里显示。提示:使用CSS定位的方式可以让最高价格的广告显示在顶部。
RSS中的Adsense
随着博客和RSS的普及,你会发现Adsense在feed中出现,不过这并没有什么用,理由如下:
你只能放置一个广告单元。你没法控制广告单元的好位置。这些广告的匹配通常都非常差(会越来越好的)。有人开发出屏蔽广告的软件。
我知道人们喜欢在阅读器中阅读全文的feed,并且至少有十多个理由表明全文输出更能讨好手机和离线用户,这些道理的确是正确的,但是如果你的网站需要依靠AdSense得到收入并生存下去,那么就应该摘要输出,将用户带到你的网站,给他们看广告。
广告代理联盟
将Adsense放在广告代理联盟的网站是个好主意。如果你正在代理销售10美元、20美元、30美元的商品而获得1美元的回扣,如果你发现转化率很低,那么绝对应该试试AdSense.我喜欢将AdSense放在我的文章页面,例如你有一个网站正在卖鞋,那么你应该需要一些相关的文章来充实这个网站,在这些内容上放置Adsense是最合适的。当然,这些可能不会让你富起来,但是通常会提供一个稳定的小额收入可以弥补支付类似托管费用的支出。提示:如果你发现你的页面能够得到每月超过50个点击,那么就尝试多写一些类似的话题,并将其链接到一个页面,检查你的日志看看别人是通过搜索什么关键字访问你的网站。
PPC套利
这是一个危险的项目,我自己通常不会冒险涉及。基本上,你可以出很低的成本在某个关键字上,然后设置一个引导页包含高价广告或者相关话题,你就可以在AdWords和AdSense之间的差价获得收益,比如你付出0.1美元的点击,获得1美元的点击,这样你就获得了每个点击0.9美元的收益,要让你的adsense广告被批准,你需要增加一些有价值的东西到上面,这可能会导致你被K,因此在尝试之前你要知道自己是在做什么。
好了,你还有没有什么其他的技巧、诀窍和秘密,那么就发邮件或者留言让我知道吧。
Tags:
这个页面是wangyeba.com用来介绍如何申请 Google(GG)Adsnse 广告的帮助文件,希望广大站长不要作弊,维护一个干净的大环境.
现在正规渠道申请GG广告已经很难了,所以大家要珍惜这个机会.别作弊.别用软件点,那样肯定是会被K的.好了不多说了,开始.

第一步:

浏览器登陆 http://www.flixya.com/ 见图1
Tags:
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]