CN109992584B - 一种借鉴围棋布局的数据结构树的存储方法 - Google Patents

一种借鉴围棋布局的数据结构树的存储方法 Download PDF

Info

Publication number
CN109992584B
CN109992584B CN201910233077.6A CN201910233077A CN109992584B CN 109992584 B CN109992584 B CN 109992584B CN 201910233077 A CN201910233077 A CN 201910233077A CN 109992584 B CN109992584 B CN 109992584B
Authority
CN
China
Prior art keywords
node
tree
nodes
column
overflow
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
CN201910233077.6A
Other languages
English (en)
Other versions
CN109992584A (zh
Inventor
吕新民
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Individual
Original Assignee
Individual
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Individual filed Critical Individual
Priority to CN201910233077.6A priority Critical patent/CN109992584B/zh
Publication of CN109992584A publication Critical patent/CN109992584A/zh
Application granted granted Critical
Publication of CN109992584B publication Critical patent/CN109992584B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02DCLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
    • Y02D10/00Energy efficient computing, e.g. low power processors, power management or thermal management

Abstract

本发明公开一种借鉴围棋布局的数据结构树的存储方法,该方法中,使用围棋的行、列坐标来表达传统的树结构;包括:将围棋棋盘的规格从19*19扩展为m*n,其中,m和n都是正整数;将树节点标记为{RW,CL、OVCL、FRW、FCL、FOVCL、NDNAME,NDDATA};根节点设置在第一行第一列上;其它节点的行、列和溢出列的取值根据其父节点的行X、列Y和溢出列Z的值按照后面说明的规则产生。

Description

一种借鉴围棋布局的数据结构树的存储方法
技术领域
本发明涉及数据存储方法,特别是一种借鉴围棋布局的数据结构树的存储方法。
背景技术
围棋,大家都知道,是一种策略性两人棋类游戏,中国古时称“弈”,西方名称“Go”。流行于东亚国家(中、日、韩、朝),属琴棋书画四大艺术之一。围棋起源于中国,传为帝尧所作,春秋战国时期即有记载。隋唐时经朝鲜传入日本,流传到欧美各国。围棋蕴含着中华文化的丰富内涵,它是中国文化与文明的体现。
围棋使用方形格状棋盘及黑白二色圆形棋子进行对弈,棋盘上有纵横各19条线段将棋盘分成361(19*19)个交叉点,棋子走在交叉点上,双方交替行棋,落子后不能移动,以围地多者为胜。因为黑方先走占了便宜,所以人为规定黑方局终时要给白方贴子。中国古代围棋是黑白双方在对角星位处各摆放两子(对角星布局),为座子制,由白方先行。现代围棋由日本发展而来,取消了座子规则,黑先白后,使围棋的变化更加复杂多变。围棋也被认为是世界上最复杂的棋盘游戏。
树,计算机领域最重要的数据结构之一,是计算机操作系统、编译和运行经常使用的底层技术,是计算机技术、人工智能、大数据及机器人领域不可或缺的关键核心技术。数据结构算法的研究是与计算机的出现和发展同步进行的,人们一直在锲而不舍的研究数据结构,尤其是其中最复杂的结构之一,树,的各种算法,一直想方设法提高算法的效率,使同样处理能力的计算机能为人类做更多的工作,发挥更重要的贡献,以满足人们对各种物质和文化生活更高的要求。
树是一种层次化的数据结构,在层次化的数据元素(节点)之间有祖先和后代、上级和下属、整体和部分以及其它类似的关系。吴国国王孙坚的家族树可以用图1来表示。
从图1可以看出,孙坚处在树的最顶层,他的孩子(孙策、孙权、孙翊和孙匡)列在下一层,有一条边将孙坚与他的孩子联系起来。孙权当吴国国王时间比较长,因此有7个儿子,这7个孩子都列在孙权的下面,孙权和他的孩子之间都有一条边将他们联系起来。实际上,孙策、孙翊和孙匡都是有孩子的,因为版面的原因,我们在这里都没有列出了。从附图1的层次结构表示中,我们很容易找到孙策的兄弟姐妹、孙权的后代、孙霸的祖先,等等。
一棵树可以使用下面比较严格的条文来定义:一棵树T是一个非空的有限元素的集合,其中一个元素为根(Root),其余的元素(如果有的话)组成T的子树。
请注意,上面关于树的定义是递归的。下面来看这个定义与图1所示的孙坚的家族层次数据的例子之间有什么联系。在层次图中最高层次的元素是根,其直接下一级元素是子树的根。在孙坚的家谱例子中,数据集合是{孙坚,孙策,孙权,孙翊,孙匡,孙登,孙虑,孙和,孙霸,孙奋,孙休和孙亮},因此,集合的个数n=12,根是孙坚。余下的元素分成四个不相交的集合{孙策},{孙权,孙登,孙虑,孙和,孙霸,孙奋,孙休和孙亮},{孙翊}和{孙匡}。{孙策},{孙翊}和{孙匡}都是只有一个元素的集合,其根分别是孙策、孙翊、和孙匡。集合{孙权,孙登,孙虑,孙和,孙霸,孙奋,孙休和孙亮}共有8个元素,其根为孙权,剩余元素分成7个不相交的集合,分别是:{孙登},{孙虑},{孙和},{孙霸},{孙奋},{孙休}和{孙亮}。
在画一颗树时,每个元素都代表一个节点。树根画在上面,其子树画在下面。在根与子树的根(如果有子树)之间有一条边。同样的,每一颗子树也是根在上,其子树在下。在一棵树中,一个元素节点及其孩子节点之间用一条边连接。例如,在图1孙坚的家谱树中,孙策,孙权,孙翊和孙匡是孙坚的孩子,孙坚是它们的父母。有相同父母的孩子为兄弟。在图1中,孙策,孙权,孙翊和孙匡是兄弟,因为它们都是孙坚的孩子。类似地,在树的结构中,还有其它的术语,比如:孙子、祖父、祖先和后代等,这些关系直截了当,也是很容易理解的。在树中没有孩子的元素称为叶子,在图1中,孙登,孙虑,孙和,孙霸,孙奋,孙休和孙亮是树的叶子。树根是唯一没有父母的元素。
树的另一个术语为级。树根是1级,其孩子(如果有)是2级,孩子的孩子是3级,等等。在图1所示的结构中,孙坚是1级,孙权是2级,孙登是3级。
一颗树的高度或深度是树中级的个数。在图1的结构中,树的高度是3。一个元素的度,是指其孩子的个数,叶节点的度数为0,在图1的树中,孙权的度数为7,因为他有7个孩子。一棵树的度,是其元素度的最大值。
树在计算机内的常用表示方法为数组表示和链表表示。对于数组表示法,就是将树的元素按照一定的顺序存放在数组的相应位置,由于这种存放方法,当树的结构不规则时,非常浪费空间,因此,一般很少使用。
另外一种常用的表达方法,就是链表,即用指针把相关的节点关联起来。每个元素用一个节点表示,节点有几个指针域,用来指向其儿子,比如,在图1中,节点孙权会有7个指针,分别指向他的7个儿子,按照图1的树结构,节点孙策不需要指向其儿子的指针。当我们需要找到图1所示的树中的节点孙和时,我们首先从树根孙坚开始,找到他的儿子孙权,才能找到孙和。
这种一直沿用了50多年的树的表示方法的主要问题有:
1.树的结构非常呆板,每次对树的操作,都必须从根开始,按照指针的顺序,遍历整颗树,才能找到需要的节点,这样的查找效率是非常低的。
2.由于一个父亲可以有多个儿子,因此,每个节点的存储空间的大小就是不相同的,比如,在图1的树中,节点孙权需要7个指针域而节点孙坚不需要指针域,如何分配每个节点的指针域,如果按照最大的来分配,多少是最大,分配小了可能有溢出的问题,分配多了,又要浪费很多的空间;如果按照变长来处理又要增加算法的复杂性。
发明内容
本发明是针对目前用链表结构来表示树的结构所带来的不足,提供一种借鉴围棋布局的数据结构树的存储方法,将树中的每个节点,很方便地存放在围棋棋盘的交叉点上。
本发明为实现其技术目的所采用的技术方案是:一种借鉴围棋布局的数据结构树的存储方法,该方法中,使用围棋的行、列坐标来表达传统的树结构;包括:
S1、将围棋棋盘的规格从19*19扩展为m*n,其中,m和n都是正整数;
S2、将树节点标记为{RW,CL、OVCL、FRW、FCL、FOVCL、NDNAME,NDDATA},式中,RW为节点所在的行、CL节点所在的列、OVCL节点的溢出列,FRW为父节点的行,FCL父节点的列,FOVCL是父节点的溢出列,NDNAME是节点名,NDDATA节点数据;
S3、根节点设置在第一行第一列上,记着{1,1,0,0,0,0,NDNAME,NDDATA};NDNAME,NDDATA分别填写根节点名和根节点的数据;
S4、其它节点的行、列和溢出列的取值根据其父节点的行X、列Y和溢出列Z的值按照下面的规则产生:
a)左子节点的行数=X + 1,列数=Y*2 -1,如果Z=0,溢出列=0,否则,溢出列=介于1到最大溢出列随机数的正整数;
b)右子节点的行数=X + 1,列数=Y*2,如果Z=0,溢出列=0,否则,溢出列=介于1到最大溢出列随机数的正整数;
c)其它中间节点的行数=X + 1,列数=Y*2-1,溢出列=介于1到最大溢出列随机数的正整数;
d)在同一父节点的子节点中,溢出列是唯一的。
上面的符号{}与()没有实质的区别,只是为了符合有关规定。
本发明是中国古老智慧与现代计算机技术完美结合的成果,它的主要特点有:
1.借鉴围棋棋盘的布局,将数据结构中树的节点,像围棋的棋子一样有序地摆放到围棋棋盘上,从而达到使用坐标(行和列)来表达树的节点在树中相对位置的目的,解决了传统的树结构中使用数组或链表表示节点之间关系所带来的结构呆板、效率低下的老大难问题。
2.给出了完善的溢出处理机制,引进了溢出列的概念,提供了一个节点有多个子节点时,使用坐标(行和列)摆放节点的有效方法。
3.树的节点的坐标可以根据其父节点的坐标,按照围棋树的规则生成出来,简化了树的生成或节点删除操作所需调整节点坐标的工作,提高了树的操作的效率。
4.对于使用传统链表表示的数据结构,典型的如树和区块链,只能顺序存取的顽疾,提出了很好的解决方法,使得它们在某些应用场景,可以方便地使用直接存取的方法,从而大幅提高数据结构操作的效率。
5.围棋树可以采用现代成熟的数据库技术,将整颗树存放到关系数据库表中,从而方便地使用简便、快捷的SQL语句完成对树的操作。
6.给出了树的常见操作,比如,树的建立、删除、查找,的完整算法,并用实例验证了算法的可行性。
7.由于对树的绝大多数操作都是通过数据库的主索引来完成的,因此,比起传统的树的操作,算法的效率有了大幅的提高。
8.介绍了一般(普通)树的常用操作算法并特别给出了二分检索树(BinarySearch Tree – BST)的建立和删除的完整算法,限于篇幅,这里就不介绍二分检索树的完整程序及程序运行结果了。
下面结合附图和具体实施方式对本发明进行进一步的说明。
附图说明
附图1是吴国国王孙坚的家谱树。
附图2是借鉴围棋棋盘布局表达的树的示意图。
附图3是只有根节点的围棋树。
附图4是有根节点和二个子节点的围棋树。
附图5是有三层的围棋树,右边的圆框里面记录的是节点的行和列的值。
附图6是插入了中节点H的围棋树,右边的圆框里面记录的是节点的行、列和溢出列的值。
附图7是一种4层的围棋树,右边的圆框里面记录的是节点的行、列和溢出列的值。
附图8是一颗二叉树的例子。
附图9是由图8的二叉树变过来的二叉检索树及相关的投影集。
附图10是由图8的二叉树变过来的另一颗二叉检索树及相关的投影集。
附图11是三所大学组成的围棋树方法表示的二叉检索树。
附图12是18所大学组成的围棋树方法表示的二叉检索树。
附图13是范围检索遍历二叉检索树的轨迹。
具体实施方式
实施例1,如图2所示,是一个标准的围棋棋盘,它有19*19个交叉列,每一个交叉点可以使用行和列来表示,比如,(1,1)表示第一行的第一列,(1,19)表示第一行的最后一列,(5,5)表示第5行的第5列,以此类推,通过行和列的坐标,我们可以知道每个交叉点的位置。
如果将图1的孙坚的家族树放到围棋棋盘上,我们就可以看到,树中的每个节点,都是可以很方便地存放在围棋棋盘的交叉点上的,比如,节点孙坚我们就放到了交叉点(3,10)上,而节点孙权则放到了交叉点(6.6)上,类似地,可以通过将图1的树与图2的树的对比,很容易确定每个节点在围棋棋盘上的交叉点的位置。
将图1的树放到围棋棋盘后,如图2所示,能给我们带来下面的启示:
1.节点的位置可以通过节点所在的交叉点的位置决定,跟节点的内容无关;
2.如果按照从根节点由上往下的顺序排列,行数值较大的节点只能是行数值较小的节点的子孙,不可能反过来是它们的祖先;
3.如果规定父辈与儿子之间的行数间隔是相同的,那么,只有行数相同的节点才有可能是兄弟关系;
从上面的几点启示,我们可以看到,将传统的使用数组和指针链接来表示的树,实际上完全可以通过它们在围棋棋盘交叉点的位置来表示,这就是我们要引进本实施例的围棋树的由来!
通过更严格的定义,来达到使用坐标(行,列)来表达传统的树结构的目的。这些定义包括:
1.由于现实中的树的高度和宽度是没有限制的,因此,我们需要将围棋棋盘的规格从19*19扩展为m*n,其中,m和n都是正整数,m表示树的最大高度(行数),n表示树的最大宽度(列数)。按照下面的几条规则,我们可以知道,n=2(m-1)
2.树中的根节点的坐标总是为(1,1),即总是处于第一行第一列上。
3.根的儿子们的行坐标都是2(1+1),而第一个儿子(如果有的话)的列坐标为1(1*2-1),称之为左儿子或左子节点,第二个儿子(如果有的话)的列坐标为2(1*2),称之为右儿子或右子节点。
4.根的其它儿子可能有多个,我们统称为中儿子或中子节点,它们的行坐标都是2(1+1),列坐标介于1和2之间,具体的取值,会在后面插入中子节点时做详细的说明。
5.类似地,根的第x代孙(为了描述的方便性,我们假定根的儿子们为根的第1代孙)的行的取值为x+1,第x代孙的第1个孙子(左孙子)列的取值为1,第2个孙子(右孙子)的列的取值为2,其它孙子的列的取值可以参考规则4,根据其父辈的列的取值来决定。同样地,具体的算法,我们也会在后面插入中子节点时做详细的说明。
6.每个节点通过存放其父节点的坐标(行,列)的值而达到指向其父节点的目的,并不真的需要一个指向父节点的指针。而父节点则不需要任何指向子节点的指针,更不需要为留多少个指针伤透脑筋!根节点指向父节点的指针值为空,即根节点的父节点的坐标为(0,0)。
我们这里是用数据库的表来表示树的结构的,这样的做法只是为了方便算法的介绍,并不是必须使用数据库的表才能实现的。
实际上,计算机操作系统自带的索引文件系统是完全有能力满足本实施例的算法的需要的。这里之所以要特别说明这一点,是因为,基础的数据结构(包括树)的算法,是广泛应用于计算机的底层的操作系统、编译和运行单元的调用中的,如果一个数据结构算法,必须借助于数据库系统的功能才能运作,那么,它的应用范围就要大打折扣了。
下面给出的是对围棋树的数据库表的定义,每个字段的含义都写在字段后面的括号中:
000050 CREATE TABLE IBMUSER.TREE1
000060 ( RW INT NOT NULL, 【行号】
000070 CL INT NOT NULL, 【列号】
000080 OVCL INT NOT NULL, 【溢出列号】
000090 FRW INT NOT NULL, 【父节点行号】
000100 FCL INT NOT NULL, 【父节点列号】
000200 FOVCL INT NOT NULL, 【父节点的溢出列号】
000300 NDNAME CHAR(10) NOT NULL, 【节点名字】
000310 NDDATA CHAR(30) NOT NULL, 【节点详细内容】
000400 PRIMARY KEY (RW,CL,OVCL)) 【主键】
000500 IN DATABASE DSNDB04;
000700 CREATE UNIQUE INDEX IBMUSER.XTREE1 【主键索引】
000800 ON IBMUSER.TREE1
000900 (RW,CL,OVCL)
000901 USING STOGROUP PUBSG001
000902 BUFFERPOOL BP1
000903 CLOSE YES;
000912 CREATE UNIQUE INDEX IBMUSER.XTREE2 【节点名字作为单独的索引】
000913 ON IBMUSER.TREE1
000914 (NDNAME)
000915 USING STOGROUP PUBSG001
000916 BUFFERPOOL BP1
000920 CLOSE YES;
创建围棋树的过程如下,首先创建的是根节点:
000100 INSERT INTO IBMUSER.TREE1
000101 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000102 VALUES(1,1,0,0,0,0,'A','ROOT');
插入完成后,查看数据库表中根节点的数据:
000200 SELECT * FROM IBMUSER.TREE1;
命令执行后,显示的数据库表中根节点的内容为:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
-+-------+-------+-------+-------+-------+-------+------+------+-----
1 1 0 0 0 0 A ROOT
对应的树如图3所示。
其次再插入二个子节点作为根节点的儿子:
000100 INSERT INTO IBMUSER.TREE1
000101 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000102 VALUES(2,1,0,1,1,0,'B','2ND LEVEL - LEFT');
000103 INSERT INTO IBMUSER.TREE1
000104 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000105 VALUES(2,2,0,1,1,0,'C','2ND LEVEL - RIGHT');
查看数据库表中根节点的数据:
SELECT * FROM IBMUSER.TREE1;
命令执行后,显示的数据库表中各节点的内容为:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
------+------+-----+------+-----+----+------+----+------+------+-----
1 1 0 0 0 0 A ROOT
2 1 0 1 1 0 B 2ND LEVEL - LEFT
2 2 0 1 1 0 C 2ND LEVEL - RIGHT
对应的树如图4所示。然后,在节点B下插入节点D和E,在节点C下插入节点F和G,这种做法与上面的做法基本一致,可以使用下面的SQL INSERT语句来完成:
000100 INSERT INTO IBMUSER.TREE1
000101 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000102 VALUES(3,1,0,2,1,0,'D','3RD LEVEL - 1LEFT');
000103 INSERT INTO IBMUSER.TREE1
000104 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000105 VALUES(3,2,0,2,1,0,'E','3RD LEVEL - 1RIGHT');
000106 INSERT INTO IBMUSER.TREE1
000107 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000108 VALUES(3,3,0,2,2,0,'F','3RD LEVEL - 2LEFT');
000109 INSERT INTO IBMUSER.TREE1
000110 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000120 VALUES(3,4,0,2,2,0,'G','3RD LEVEL - 2RIGHT');
用SELECT语句来检查插入后数据库表中的节点的情况:
000200 SELECT * FROM IBMUSER.TREE1;
查询处理的结果如下:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+-----+------+------+------+------+------+------+------+------+------
1 1 0 0 0 0 A ROOT
2 1 0 1 1 0 B 2ND LEVEL - LEFT
2 2 0 1 1 0 C 2ND LEVEL – RIGHT
3 1 0 2 1 0 D 3RD LEVEL - 1LEFT
3 2 0 2 1 0 E 3RD LEVEL - 1RIGHT
3 3 0 2 2 0 F 3RD LEVEL - 2LEFT
3 4 0 2 2 0 G 3RD LEVEL - 2RIGHT
对应的树如图5所示。再然后,在节点F和G之间插入节点H,由于节点H是中节点,我们需要为节点H生成一个随机数,假定为节点H生成的随机数为16384;这样,可以使用下面的SQL语句来完成节点H的生成:
000100 INSERT INTO IBMUSER.TREE1
000101 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000102 VALUES(3,3,16384,2,2,0,'H','3RD LEVEL - 2MIDD');
可以用SELECT语句来检查插入后数据库表中的节点的情况:
000200 SELECT * FROM IBMUSER.TREE1:
处理的结果如下:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+------+------+------+------+------+------+----+-----+-----+---------
1 1 0 0 0 0 A ROOT
2 1 0 1 1 0 B 2ND LEVEL - LEFT
2 2 0 1 1 0 C 2ND LEVEL – RIGHT
3 1 0 2 1 0 D 3RD LEVEL - 1LEFT
3 2 0 2 1 0 E 3RD LEVEL - 1RIGHT
3 3 0 2 2 0 F 3RD LEVEL - 2LEFT
3 4 0 2 2 0 G 3RD LEVEL - 2RIGHT
3 3 16384 2 2 0 H 3RD LEVEL - 2MIDD
从上面的查询结果我们可以看到,在节点F(3,3,0)和节点G(3,4,0)之间增加了节点H(3,3,16384)。对应的树如图6所示。
另外,在H下插入4个节点I、J、K和L,由于父节点H为中节点,因此,其所有子节点的溢出列都是非零的,我们必须为它们生成各自的非零随机数!假定为节点I、J、K和L生成的溢出列的随机数的值分别为16888、16288、168和88,这样,就可以知道节点I、J、K和L的坐标值分别是(4,5,16888)、(4,6,16288)、(4,5,168)和(4,5,88),可以使用下面的SQL INSERT语句来完成。
000100 INSERT INTO IBMUSER.TREE1
000101 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000102 VALUES(4,5,16888,3,3,16384,'I','4TH LEVEL - 4LEFT');
000103 INSERT INTO IBMUSER.TREE1
000104 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000105 VALUES(4,6,16288,3,3,16384,'J','4TH LEVEL - 4RIGT');
000106 INSERT INTO IBMUSER.TREE1
000107 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000108 VALUES(4,5,168,3,3,16384,’K','4TH LEVEL -1MID');
000109 INSERT INTO IBMUSER.TREE1
000110 (RW,CL,OVCL,FRW,FCL,FOVCL,NDNAME,NDDATA)
000111 VALUES(4,5,88,3,3,16384,'L','4TH LEVEL – 2MID');
用SELECT语句来检查插入后数据库表中的节点的情况:
000200 SELECT * FROM IBMUSER.TREE1:
查询处理的结果如下:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+------+------+------+------+------+------+-----+-----+------+-------
1 1 0 0 0 0 A ROOT
2 1 0 1 1 0 B 2ND LEVEL - LEFT
2 2 0 1 1 0 C 2ND LEVEL – RIGHT
3 1 0 2 1 0 D 3RD LEVEL - 1LEFT
3 2 0 2 1 0 E 3RD LEVEL - 1RIGHT
3 3 0 2 2 0 F 3RD LEVEL - 2LEFT
3 4 0 2 2 0 G 3RD LEVEL - 2RIGHT
3 3 16384 2 2 0 H 3RD LEVEL - 2MIDD
4 5 88 3 3 16384 L 4TH LEVEL – 2MID
4 5 168 3 3 16384 K 4TH LEVEL – 1MID
4 5 16888 3 3 16384 I 4TH LEVEL - 4LEFT
4 6 16288 3 3 16384 J 4TH LEVEL - 4RIGT
对应的树如图7所示。本实施例中,根节点的行、列和溢出列的取值总是1、1和0,其父节点的行、列和溢出列的取值总是0、0和0。子节点的行、列和溢出列的取值可以根据其父节点的行(X)、列(Y)和溢出列(Z)的值按照下面的规则产生:
a)左子节点的行数=X + 1,列数=Y*2 -1,如果Z=0,溢出列=0,否则,溢出列=介于1到最大溢出列随机数,比如32768,之间的随机数;
b)右子节点的行数=X + 1,列数=Y*2,如果Z=0,溢出列=0,否则,溢出列=介于1到最大溢出列随机数,比如32768之间的随机数;
c)其它中间节点的行数=X + 1,列数=Y*2-1,溢出列=介于1到最大溢出列随机数,比如32768,之间的随机数。
按照上面定义的通用规则,可以知道,如果需要在节点F下面插入子节点,那么,这些子节点的取值为:
1.左子节点,(4,5,0)
2.右子节点,(4,6,0)
3.中子节点,(4,5,X),X是介于1到最大随机数,比如32768,之间的一个正整数值。
这样,可以看到,节点F的中子节点的取值与节点H的子节点的取值范围是一样的,它们是重叠的,即共用介于1到最大随机数,比如32768,之间的一个正整数值。实际上,当节点C有多个中节点时,这些中节点的子节点与节点F的中节点都是共用介于1到最大随机数,比如32768,之间的正整数值的!这个结论对节点F和节点H的所有孙子辈都是适用的。
本实施例中的围棋树有基本操作:
1.确定树的高度:
由于最大的行数(RW)就是我们的树TREE1的高度,因此,可以使用下面的SQL语句来确定树TREE1的高度:
000200 SELECT MAX(RW) FROM IBMUSER.TREE1;
查询结果如下面显示的:
+---------+---------+---------
4
目前,树TREE1的高度为4。由于我们是直接使用数据库的索引得到的最大行(RW)数,因此,该操作需要的处理时间比起传统链表表示的树通过从上到下搜索整颗树才能确定树的高度要少得多。
确定树的节点数
树TREE1的节点数就是我们数据库表中的记录个数,因此,可以使用下面的SQL语句来获取答案:
000200 SELECT COUNT(*) FROM IBMUSER.TREE1;
命令简单明了,完全不需要像传统链表表示的树那样,遍历整颗树才能获得树的总节点数!查询结果正如下面SQL执行显示的,树TREE1一共有12个节点:
+---------+---
12
3.查找特定节点
比如,从树中找到节点D的内容:
000200 SELECT * FROM IBMUSER.TREE1
000300 WHERE NDNAME ='D';
下面的SQL语句执行结果给出了节点D的所有信息:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+------+------+------+------+------+------+------+-----+------+------
3 1 0 2 1 0 D 3RD LEVEL - 1LEFT
同样地,本实施例中由于是直接使用数据库的唯一索引得到节点D的信息,即使用直接存取的方法获得的,因此,该操作需要的处理时间比起传统链表表示的树通过从上到下遍历整颗树,即顺序存取,才能找到节点D,又会有大幅的降低!
4、确定节点之间的关系:
a) 查找节点H的父节点
要回答这个问题,首先要找到节点H,正如上面找节点D的方法一样,我们可以使用下面的SQL语句:
000200 SELECT * FROM IBMUSER.TREE1
000300 WHERE NDNAME ='H';
得到的查询结果如下:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+------+------+------+------+------+------+------+------+------+-----
3 3 16384 2 2 0 H 3RD LEVEL - 2MIDD
从上面的查询结果我们可以知道,节点H的父节点行RW的值为2,列CL的值为2,溢出列OVCL的值为0,这样,我们就可以提供下面的SQL语句来得到节点H的父节点的信息了:
000200 SELECT * FROM IBMUSER.TREE1
000300 WHERE RW = 2 AND
000400 CL= 2 AND
000500 OVCL = 0;
得到的查询结果如下:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+------+------+------+------+-------+------+------+-----+-----+------
2 2 0 1 1 0 C 2ND LEVEL - RIGHT
从上面的查询信息我们就知道,节点H的父节点为节点C。
上面的二条SQL语句都是通过主索引直接得到的节点H的父节点C的信息的,因此,这样的操作效率比起传统链表表示的树显然要高得多!
b)查找节点H的子节点
同样的先找到H:
000200 SELECT * FROM IBMUSER.TREE1
000201 WHERE NDNAME = 'H';
查询执行的结果如下:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+-----+------+------+------+-----+------+-----+-----+-----+----+-----
3 3 16384 2 2 0 H 3RD LEVEL - 2MIDD
然后,使用下面的SQL语句找到父节点为H,即FRW,FCL和FOVCL分别为3,3和16384的所有节点数:
000210 SELECT COUNT(*) FROM IBMUSER.TREE1
000300 WHERE FRW = 3 AND
000400 FCL = 3 AND
000500 FOVCL = 16384;
查询执行的结果如下所示:
+---------+
4
节点H一共有4个子节点。
最后,使用下面的SQL语句,找到节点H的子节点:
000600 SELECT * FROM IBMUSER.TREE1
000700 WHERE FRW = 3 AND
000800 FCL = 3 AND
000900 FOVCL = 16384;
查询出来的结果如下面显示的,分别是节点I、J、K和节点L。
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+------+------+------+------+------+------+----+-------+-----+-------
4 5 88 3 3 16384 L 4TH LEVEL – 2MID
4 5 168 3 3 16384 K 4TH LEVEL – 1MID
4 5 16888 3 3 16384 I 4TH LEVEL - 4LEFT
4 6 16288 3 3 16384 J 4TH LEVEL - 4RIGT
从上面检索可以看出:由于所有的查询,都是直接使用数据库的唯一索引直接得到的,因此,这些操作都是直接存取,所需的处理时间比起传统链表表示的树只能顺序存取,要少得多!
c)查找节点E和节点F的关系
为了确定节点E和F是不是兄弟,我们需要使用下面的SQL语句,将节点E和F的信息查询出来:
000200 SELECT * FROM IBMUSER.TREE1
000201 WHERE NDNAME = 'E' OR
000202 NDNAME = 'F';
查询出来以后,我们可以看到,节点E的父节点FRW,FCL和FOVCL的值分别是2、1和0,而节点F的父节点的FRW,FCL和FOVCL的值则为2、2和0,因此,它们不是处于同一个父节点的下面,
因此,节点E和节点F不是兄弟!
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
+-----+-----+-------+-------+------+------+-----+------+------+------
3 2 0 2 1 0 E 3RD LEVEL - 1RIGHT
3 3 0 2 2 0 F 3RD LEVEL - 2LEFT
通过上面的各种树的常用操作的演示,可以看出,本实施例的大部分的查询,都是直接使用数据库的唯一索引,通过直接(随机)存取得到的,因此,比起传统用链表或数组表示的树只能顺序存取,需要一步一趋地扫描树中的每个节点,这些操作效率高,这也就是将一颗树以围棋棋盘的格局来存放到关系数据库,而不是像传统数据结构算法中,将树使用链表或数组来存放的最主要原因。
另外,随着数据库技术的快速发展和SQL语句的越来越简便化,使用数据库的SQL来操作计算机最重要的一种数据结构,围棋树,比起原来那种按照链接,逐个节点浏览的操作方法,要简便和轻松。
、树的遍历
所谓树的遍历,就是要访问树中的每个节点一次而且只有一次,在传统的树结构下,要遍历树的算法是非常复杂的,而且还要有前序遍历、中序遍历、后序遍历和层次遍历的多种形式。在使用了本实施例的围棋树,结合数据库技术来存储围棋树结构以后,围棋树的遍历就会变得异常简单,只要使用下面的SQL语句,就能完成整个树的遍历:
000200 SELECT * FROM IBMUSER.TREE1;
SQL执行后的结果如下,可以看到,所有的树节点都列在了下面的清单中,每个节点出现一次而且只出现一次!
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
-+------+------+------+------+------+------+------+------+-----+-----
1 1 0 0 0 0 A ROOT
2 1 0 1 1 0 B 2ND LEVEL - LEFT
2 2 0 1 1 0 C 2ND LEVEL - RIGHT
3 1 0 2 1 0 D 3RD LEVEL - 1LEFT
3 2 0 2 1 0 E 3RD LEVEL - 1RIGHT
3 3 0 2 2 0 F 3RD LEVEL - 2LEFT
3 4 0 2 2 0 G 3RD LEVEL - 2RIGHT
3 3 16384 2 2 0 H 3RD LEVEL - 2MIDD
4 6 16288 3 3 16384 J 4TH LEVEL - 4RIGT
4 5 16888 3 3 16384 I 4TH LEVEL - 4LEFT
4 5 168 3 3 16384 K 4TH LEVEL – 1MID
4 5 88 3 3 16384 L 4TH LEVEL – 2MID
这种遍历出来的结果,是按照数据库默认的方式排列输出的。这与我们通常所需要的遍历输出方式并不一致。我们可以将上面的SQL语句稍微做一下修改,变成:
000300 SELECT * FROM IBMUSER.TREE1
000400 ORDER BY RW,CL,OVCL;
则输出结果如下:
RW CL OVCL FRW FCL FOVCL NDNAME NDDATA
-+------+-----+-----+------+------+-------+-----+------+------+------
1 1 0 0 0 0 A ROOT
2 1 0 1 1 0 B 2ND LEVEL - LEFT
2 2 0 1 1 0 C 2ND LEVEL - RIGHT
3 1 0 2 1 0 D 3RD LEVEL - 1LEFT
3 2 0 2 1 0 E 3RD LEVEL - 1RIGHT
3 3 0 2 2 0 F 3RD LEVEL - 2LEFT
3 3 16384 2 2 0 H 3RD LEVEL - 2MIDD
3 4 0 2 2 0 G 3RD LEVEL - 2RIGHT
4 5 88 3 3 16384 L 4TH LEVEL - 2MID
4 5 168 3 3 16384 K 4TH LEVEL -1MID
4 5 16888 3 3 16384 I 4TH LEVEL - 4LEFT
4 6 16288 3 3 16384 J 4TH LEVEL - 4RIGT
这就是我们常说的分层遍历的结果!对于整个表的分层遍历,可以使用SQL语句直接完成,但如果要对树中的某个子树做分层遍历,就要用程序来完成了。
、逆向生成树
一般来说,树的生成都是从上向下的,即先有根,然后是根的儿子、孙子等等,一代一代从上向下生成。这种生成方法,对于本实施例中的围棋树来说,是完全没有问题的,上面的例子已经有了很好的说明。
但是,在某些现实的情况下,树的生成可能是逆向的,即先有儿子节点再有父节点,即需要在原有树的基础上加一层,将原来的根节点变成子节点,其祖辈变成新的根节点。
这种情况在家(族)谱树的生成过程中会经常碰到,比如,对于一个家族来说,本来已经建立好了家族树,但后来又找到了更早的祖辈的信息,因此需要将他的信息增加到家族树中,这样,新出现的祖辈就变成新的树根节点,原来的根节点就要变成子节点了。
对于这种逆向生成的树,围棋树的操作非常简单,只需要做下面的二个简单动作:
i.将原来树中的每个节点的行号(RW)加1,列(CL)和溢出列(OVCL)保持不变;
ii. 将祖辈的信息作为根节点插入,其行号(RW)、列号(CL)和溢出列(OVCL)的值分别为1,1和0即可。
按照前面的节点坐标生成规则,子节点的列(CL)和溢出列(OVCL)的取值是由其父节点的列和溢出列的取值决定的,只要父节点的列和溢出列的取值不变,其子节点的列和溢出列的取值就可以保持不变。
原来的根节点的行、列和溢出列的取值分别为1,1和0,当新加一层后,新的根节点的取值依然是1,1和0,而原来的根节点变成现在的子节点后,由于它是新根节点的第一个儿子,按照围棋树的节点生成规则,它的行(RW)取值会变为2(1+1),列(CL)的取值为1(1*2- 1)而溢出列的取值为0。由于它的列和溢出列的取值没有发生变化,对应的,它的子节点的列和溢出列的取值也能保持不变,同理类推,它的所有子孙节点的列和溢出列的值都会保持不变,唯一变化的是每个节点的行号需要加1,因为,新的祖辈加入进来了,树的层数增加了,家族树的内容更充实、更丰富了。
、围棋树的二叉检索树
二叉树由节点组成,每个节点只能有一个父节点(只有一个例外,也就是根节点,它没有父节点),而且每个节点只能有二个子节点,即左子节点和右子节点。实际上,如果将每个子节点作为根,它的所有子孙同样也是一颗二叉树。
图8是一颗二叉树的例子。虚线三角形的区域是二颗分别以节点B和节点C作为根节点的子树。
一颗二叉检索树是一颗二叉树,其中每个节点都包含一个可以用来比较大小的键值,且每个节点的键值都大于其左子树中的任意节点的键值而小于右子树的任意节点的键值。二叉检索树通常用来高效地实现符号表,这也是计算机科学中最重要的算法之一。
如果将图8中的二叉树上节点的名字当着节点的键值,我们就可以看到,图8是不满足二叉检索树的要求的,因为对于根节点A来说,它的左子树的所有节点的值不是都比它小的,因此,图8的二叉树并不满足二叉检索树的要求。
如果要让图8的二叉树满足二叉检索树的要求,我们可以将它变成如图9所示,显然,图9的二叉树满足了二叉检索树的条件。
一颗二叉检索树代表了一组键(及其相应的值)的集合,而同一个集合可以用多颗不同的二叉检索树来表示。比如,图9和图10所示的二颗看起来完全不同的二叉检索树,代表的却是同一个集合。
对每一颗二分检索树,如果将一颗二分检索树的所有键投影到一条直线上,保证一个节点的左子树中的键出现在它的左边,右子树中的键出现在它的右边,那么我们肯定可以得到一条有序的键列。从图9和图10我们可以看到,投影下来得到的都是由小到大排列的字符集{A,B,C,D,E,F,G}。
二分检索树是一颗特殊类型的树,因此,前面介绍的使用坐标的方法来表示树的结构的做法依然是有效的。为了更好表达二分检索树,围棋树的结构进行形变。
000050 CREATE TABLE IBMUSER.BTREE
000060 ( RW INT NOT NULL, 【行号】
000070 CL INT NOT NULL, 【列号】
000080 OVCL INT NOT NULL, 【溢出列号】
000090 FRW INT NOT NULL, 【父节点的行号】
000100 FCL INT NOT NULL, 【父节点的列号】
000200 FOVCL INT NOT NULL, 【父节点的溢出列号】
000210 LRCHILD CHAR(01) NOT NULL, 【左或右子节点标识】
000300 NDNAME CHAR(60) NOT NULL, 【节点名字】
000310 NDDATA CHAR(30) NOT NULL, 【节点详细信息】
000400 PRIMARY KEY (RW,CL,OVCL)) 【主键】
000500 IN DATABASE DSNDB04;
000700 CREATE UNIQUE INDEX IBMUSER.XBTREE 【主键对应的主索引】
000800 ON IBMUSER.BTREE
000900 (RW,CL,OVCL)
000901 USING STOGROUP PUBSG001
000902 BUFFERPOOL BP1
000903 CLOSE YES;
000912 CREATE UNIQUE INDEX IBMUSER.XBTREE2 【节点名字作为独立的索引】
000913 ON IBMUSER.BTREE
000914 (NDNAME)
000915 USING STOGROUP PUBSG001
000916 BUFFERPOOL BP1
000920 CLOSE YES;
注意,这里BTREE的结构跟本实施例的TREE1结构基本一样,唯一不同的是增加了字段LRCHILD,用来标示当前节点的属性,取值为:
T –根节点
L –左子树
R –右子树
此外,将NDNAME的长度定义为60,表示我们的键值的最大长度为60,以便可以完整地保存后面的全球TOP 100所大学的英文全称,当然,如果在现实的符号表检索中需要更长的,可以增加NDNAME的长度,这个长度的大小对于我们后面的算法描述是没有任何影响的。
由于二叉检索树每个节点最多只有二个节点,因此,溢出列(OVCL和FOVCL)是可以不需要的,但考虑到树的表达的一致性,我们依然保留了这二个字段,只是它们的取值一直为零而已。
假定我们要将下面这些全球100家最优秀的大学放到我们的二叉检索树中,记录到树中的内容包括:大学的英文名字、所属的国家、所在国家的排名和总分,这个表可以从一些媒体上查到。生成的二叉检索树将用大学的英文名称作为关键字,按照二叉检索树的规则,每个节点的键值都会比其所有的左子树的大而又要比其所有的右子树的键值小。
为完成二叉检索树的插入工作,我们需要编写二叉检索树插入算法的程序;(程序略),然后运行程序即可生成世界上TOP 100大学组成的围棋树的二叉检索树。
先运行程序生成由3所世界上TOP 100大学组成的围棋树的二叉检索树数据库表IBMUSER.BTREE;
用SQL语句查询插入了三个记录的围棋树的二叉检索树:
SELECT* FROMIBMUSER.BTREE;
结果如下:
RW CL OVCL FRWFCLFOVCL LRCHILD NDNAME NDDATA
+----+----+----+----+-----+-----+-----+-----+-----+-----+-------+----
1 1 0 0 0 0 T Harvard University 美国 1 100
2 2 0 1 1 0 R Stanford University 美国 2 76.5
3 4 0 2 2 0 R University of Cambridge 英国 1 70.9
由这3个节点组成的树如图11所示,注意,为了与常见的树描述一致,没有严格按照每个节点的行和列的值来布局节点的位置,而是按照与大众审美观一致的要求来构造的。从图11可以看出,这个有3个节点的树,是完全满足二分检索树的条件的,即:所有的右子节点的值都大于其父节点,而且,全部只有右子节点没有左子节点。
为了更具代表性,再将十五大学所加到现有的树结构中后,查询的结果如下:
RW CL OVCL FRW FCLFOVCL LRCHILD NDNAME NDDATA
+----+----+----+----+----+----+---+----+----+----+----+---+----+-----
1 1 0 0 0 0 T Harvard University 美国 1 100
2 2 0 1 1 0 R Stanford University 美国 2 76.5
3 4 0 2 2 0 R University of Cambridge 英国 1 70.9
4 7 0 3 4 0 L University of California, Berkeley 美国 4 69.1
3 3 0 2 2 0 L Princeton University 美国 5 61.1
4 8 0 3 4 0 R University of Oxford 英国 2 60.1
2 1 0 1 1 0 L Columbia University 美国 6 58.8
3 1 0 2 1 0 L California Institute of Technology 美国7 57.3
5 15 0 4 8 0 L University of Chicago 美国 8 53.9
5 16 0 4 8 0 R Yale University 美国 9 52.8
5 14 0 4 7 0 R University of California, Los Angeles 美国10 52.5
6 31 0 5 16 0 LUniversity of Washington 美国 11 50.3
3 2 0 2 1 0 R Cornell University 美国 12 49.6
6 28 0 5 14 0 R University of California, San Diego 美国13 49.5
7 62 0 6 31 0 R University College London 英国 3 47.1
7 61 0 6 31 0 L University of Pennsylvania 美国 14 46
4 5 0 3 3 0 L Johns Hopkins University 美国 15 45.7
5 13 0 4 7 0 L Swiss Federal Instituteof Technology,Zurich 瑞士1 44.1
由这18个节点组成的树如图12所示。
注意,节点University College London 是节点University of Washington的右子树,因为在IBM主机的EBCDIC编码规则下,大写字符C(X’C3’)比小写的字符o(X’96’)要大!
使用同样的方法,我们可以将全球100所顶尖大学组成的树,存放到我们的数据库表中。限于篇幅,这里就不做说明了。
围棋树二叉检索树的查找
一般来说,在符号表中查找一个键可能得到二种结果。如果含有该键的节点存在于表中,我们的查找就命中了,然后返回相应的值。否则查找未命中。
在二叉检索树中查找一个键的递归算法通常是这样的:如果树是空的,则查找未命中;如果被查找的键和根节点的键相等,查找命中,否则就(递归地)在适当的子树中继续查找。
如果被查找的键较小就选择左子树,较大就选择右子树。继续查找直到节点找到或树为空,则未命中,查找过程结束。
比如,我们要在图12所示的树中查找【University of California, Berkeley】大学,递归算法的查找路径为:
1.先找到根节点【Harvard University】,它不是我们要找的大学,没有命中;
2.由于我们要找的大学【University of California, Berkeley】比根节点【Harvard University】大,因此,递归算法找到它的右子树;
3.右子树的根节点为【Stanford University】,它不是我们要查找的节点,而且我们要查找的节点比它大,因此,继续查找它的右子树;
4.右子树的根节点为【University of Cambridge】,它不是我们要查找的节点,而且我们要查找的节点比它小,因此,继续查找它的左子树;
5.左子树的根节点为【University of California, Berkeley】,它就是我们要查找的节点,因此查找完成,命中。
上面的步骤是传统的使用数组或链表表示的树的经典查找方法,必须按照树的路径一步一步查找,直到找到所需的节点或树为空为止。
显然,这种查找方法既费时又麻烦,我们必须找到更有效的办法才行!
实际上,按照我们现有的数据结构,我们只需要使用下面的SQL语句:
000001SELECT * FROM IBMUSER.BTREE
000002WHERE NDNAME = ‘University of California, Berkeley’;
查询出来的结果为:
RW CL OVCL FRW FCL FOVCL LRCHILD NDNAME NDDATA
+---+----+----+----+----+----+----+---+----+----+----+----+-----+----
470340L University of California, Berkeley 美国 4 69.1
9. 围棋树二叉检索树的范围查找
在传统的数据结构组织方法中,要能够返回给定范围内的键值,必须先有一个二叉检索树的中序遍历算法。要说明这个方法,我们先看看如何能够将二叉检索树中的所有键值按照顺序打印出来。要做到这一点,我们应该先打印出根节点的左子树的所有键(根据二叉检索树的定义,它们应该都小于根节点的键值),然后打印出根节点的键值,最后打印出根节点右子树中的所有键(根据二叉检索树的定义,它们应该都大于根节点的键)。
在遍历的过程中,我们将满足我们查找条件的节点的键值输出,得到的就是我们要求的结果。比如,我们需要在图12的18所全球TOP 100大学组成的树中找到以开头字母介于V和Z之间的所有大学的名字,树的遍历过程如图13所示,其中,黑底白字的节点是所有满足条件的节点,边框为虚线的节点则是虽然不满足条件但是遍历过程中仍然需要访问的节点。
传统二叉检索树的性能相当差,而且在某些特殊情况下,性能差得不得了!比如,从图13的范围查找轨迹来看,为了找到满足条件的一所大学,我们需要遍历近半颗树,即访问7个节点才能完成。
使用围棋树存放的二叉检索树来说,范围查找就非常简单了,因为,它只要执行下面的SQL语句即可查找到介于“V”和“Z”之间起始的学校名称。
SELECT * FROM IBMUSER.BTREE
WHERE NDNAME BETWEEN 'V' AND 'Z';
结果如下:
RW CL OVCL FRW FCL FOVCL LRCHILD NDNAME NDDATA
+-----+-----+------+------+------+-----+-----+-----+-------+---------
5160480R Yale University 美国 9 52.8
10.围棋树二叉检索树的节点删除
被删除的节点有3种可能的情况,对应的操作也各不相同。
(1)删除叶节点
处理的方法是直接释放要删除叶节点的空间,即在数据库表中直接删除掉该节点对应的记录即可。如果被删除的节点是根节点,被删除后,数据库的表中无记录,也表示树是空树。
(2)删除只有一颗子树的节点
被删除的节点只有一颗子树表示,该节点只有左子节点或右子节点。如果被删除的节点为根节点,即没有父节点,则该节点的唯一的子树就是我们需要的结果。如果被删除的节点有父节点,就将它唯一的子树作为其父节点的儿子,再将被删除的节点释放(即从数据库表中删除)即可。
在删除掉指定的节点后,我们需要继续保持围棋树的特性,即所有的节点依然使用围棋棋盘上的交叉点来表示,这样,当用相关的节点替换原来的节点后,无论是替换节点本身还是替换节点的子树中的所有节点的坐标都需要做相应的调整(通常需要往上提一层)。
(3)删除既有左子节点又有右子节点的节点
如果被删除的节点有2颗非空子树,我们需要先将该节点的元素替换为它的左子树的最大元素或右子树的最小元素,然后将要删除的元素删除。在删除掉指定的节点后,我们需要继续保持围棋树的特性,即所有的节点依然使用围棋棋盘上的交叉点来表示,这样,当用相关的节点替换原来的节点后,无论是替换节点本身还是替换节点的子树中的所有节点的坐标都需要做对应的调整(通常是要往上提一层)。

Claims (7)

1.一种借鉴围棋布局的数据结构树的存储方法,该方法利用计算机系统借鉴围棋布局的数据结构树存储家谱;其特征在于:该方法中,使用围棋的行、列坐标来表达树结构;包括:
S1、将围棋棋盘的规格从19*19扩展为m*n,其中,m和n都是正整数;
S2、将树节点标记为{RW,CL、OVCL、FRW、FCL、FOVCL、NDNAME,NDDATA},式中,RW为节点所在的行、CL节点所在的列、OVCL节点的溢出列,FRW为父节点的行,FCL父节点的列,FOVCL是父节点的溢出列,NDNAME是节点名,NDDATA节点数据;
S3、根节点设置在第一行第一列上,记为{1,1,0,0,0,0,NDNAME,NDDATA};NDNAME,NDDATA分别填写根节点名和根节点的数据;
S4、其它节点的行、列和溢出列的取值根据其父节点的行X、列Y和溢出列Z的值按照下面的规则产生:
左子节点的行数=X + 1,列数=Y*2 -1,如果Z=0,溢出列=0,否则,溢出列=介于1到最大溢出列的随机数;
右子节点的行数=X + 1,列数=Y*2,如果Z=0,溢出列=0,否则,溢出列=介于1到最大溢出列的随机数;
其它中间节点的行数=X + 1,列数=Y*2-1,溢出列=介于1到最大溢出列的随机数;
在同一父节点的子节点中,溢出列是唯一的。
2.根据权利要求1所述的借鉴围棋布局的数据结构树的存储方法,其特征在于:是用关系型数据库的表来表示树的结构。
3.根据权利要求2所述的借鉴围棋布局的数据结构树的存储方法,其特征在于:围棋树的最大的行数就是其高度。
4.根据权利要求2所述的借鉴围棋布局的数据结构树的存储方法,其特征在于:围棋树的节点数是记录个数。
5.根据权利要求2所述的借鉴围棋布局的数据结构树的存储方法,其特征在于:围棋树中,查找一个节点的父节点包括以下步骤:
首先、查找到节点本身,获得节点的FRW、FCL、FOVCL;
其次、该节点的FRW、FCL、FOVCL,就是其父节点的RW、CL、OVCL;
最后、利用父节点的RW、CL、OVCL,查找到父节点。
6.根据权利要求2所述的借鉴围棋布局的数据结构树的存储方法,其特征在于:围棋树中,查找某个节点H的子节点包括以下步骤:
S1、查找节点H本身,获得节点H的RW、CL、OVCL;
S2、查找节点的FRW、FCL、FOVCL的值分别为RW、CL、OVCL的所有节点。
7.根据权利要求2所述的借鉴围棋布局的数据结构树的存储方法,其特征在于:围棋树中,判断两个节点是不是兄弟,包括以下步骤:
A1、查找两个节点,获得该两个节点的FRW、FCL、FOVCL;
A2、判断该两个节点的FRW、FCL、FOVCL是否分别相等,若相等则该两个节点是兄弟,否则不是兄弟。
CN201910233077.6A 2019-03-26 2019-03-26 一种借鉴围棋布局的数据结构树的存储方法 Active CN109992584B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201910233077.6A CN109992584B (zh) 2019-03-26 2019-03-26 一种借鉴围棋布局的数据结构树的存储方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201910233077.6A CN109992584B (zh) 2019-03-26 2019-03-26 一种借鉴围棋布局的数据结构树的存储方法

Publications (2)

Publication Number Publication Date
CN109992584A CN109992584A (zh) 2019-07-09
CN109992584B true CN109992584B (zh) 2023-09-22

Family

ID=67131592

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201910233077.6A Active CN109992584B (zh) 2019-03-26 2019-03-26 一种借鉴围棋布局的数据结构树的存储方法

Country Status (1)

Country Link
CN (1) CN109992584B (zh)

Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5257365A (en) * 1990-03-16 1993-10-26 Powers Frederick A Database system with multi-dimensional summary search tree nodes for reducing the necessity to access records
CN101286160A (zh) * 2008-05-30 2008-10-15 同济大学 数据库索引的方法
JP2009265996A (ja) * 2008-04-25 2009-11-12 Toshiba Corp 検査装置、検証方法および検証プログラム
CN101923542A (zh) * 2009-06-12 2010-12-22 如临其境创意(上海)有限公司 一种用于网络多维空间数据表达的MDDRQ-Tree索引结构
WO2016040076A2 (en) * 2014-09-09 2016-03-17 Charles Simonyi Layout engine
CN107050839A (zh) * 2017-04-14 2017-08-18 安徽大学 基于uct算法的亚马逊棋机器博弈系统
CN206710818U (zh) * 2017-05-09 2017-12-05 青岛理工大学 一种基于ZigBee和云计算的智能家居控制系统

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US8930407B2 (en) * 2008-06-20 2015-01-06 Technion Research & Development Foundation Limited Incremental clustering of indexed XML data
US10430500B2 (en) * 2014-09-09 2019-10-01 Intentional Software Corporation Detecting and animating a change in position of a visual layout node of a visual layout tree

Patent Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5257365A (en) * 1990-03-16 1993-10-26 Powers Frederick A Database system with multi-dimensional summary search tree nodes for reducing the necessity to access records
JP2009265996A (ja) * 2008-04-25 2009-11-12 Toshiba Corp 検査装置、検証方法および検証プログラム
CN101286160A (zh) * 2008-05-30 2008-10-15 同济大学 数据库索引的方法
CN101923542A (zh) * 2009-06-12 2010-12-22 如临其境创意(上海)有限公司 一种用于网络多维空间数据表达的MDDRQ-Tree索引结构
WO2016040076A2 (en) * 2014-09-09 2016-03-17 Charles Simonyi Layout engine
CN107050839A (zh) * 2017-04-14 2017-08-18 安徽大学 基于uct算法的亚马逊棋机器博弈系统
CN206710818U (zh) * 2017-05-09 2017-12-05 青岛理工大学 一种基于ZigBee和云计算的智能家居控制系统

Also Published As

Publication number Publication date
CN109992584A (zh) 2019-07-09

Similar Documents

Publication Publication Date Title
Vuillemin A data structure for manipulating priority queues
US5799299A (en) Data processing system, data retrieval system, data processing method and data retrieval method
Sarnak et al. Planar point location using persistent search trees
US5852822A (en) Index-only tables with nested group keys
US6862599B2 (en) Software-based methodology for the storage and retrieval of diverse information
US5553218A (en) Graphical user interface for relating key index properties to database table columns
US6941314B2 (en) User selectable editing protocol for fast flexible search engine
Hansen et al. Hollow heaps
Chan et al. Towards an optimal method for dynamic planar point location
US5752016A (en) Method and apparatus for database interrogation using a user-defined table
JP2008269643A (ja) データベース・システムでデータを編成し、問合せを処理する方法、およびそのような方法を実施するためのデータベース・システムおよびソフトウェア製品
Icking et al. Priority search trees in secondary memory
US20160210354A1 (en) Methods for semantic text analysis
CN109992584B (zh) 一种借鉴围棋布局的数据结构树的存储方法
Kaplan et al. Purely functional, real-time deques with catenation
US7937411B2 (en) Finite-state machine augmented for multiple evaluations of text
Ghanem et al. Bulk operations for space-partitioning trees
JP2005135221A (ja) 表形式データの結合方法、結合装置およびプログラム
Arge External Memory Geometric Data Structures
JP2829259B2 (ja) データ処理装置、データ検索装置、データ処理方法及びデータ検索方法
JP4412291B2 (ja) 記憶装置
JPH10240741A (ja) 木構造型データの管理方法
US8849866B2 (en) Method and computer program product for creating ordered data structure
Karimov Data Structures and Algorithms in Swift
Aniche Red-Black Trees

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant