本帖说说“二叉查找树排序”的道理。
以下列乱序序列为例: i:1、2、3、4、5、6、7、8、9、10 brr(i):5、2、6、1、3、9、7、6、4、8 一、对于排序“不稳定”的二叉查找树 左孩子键值<=父节点键值 父节点键值<右孩子键值 按i的序号,依次可生成如下“二叉查找树”: 1.元素brr(i)的二叉查找树
2.相对应的元素序号i的二叉图
二、对于排序“稳定”的二叉查找树 左孩子键值<父节点键值 父节点键值<=右孩子键值 按i的序号,依次可生成如下“二叉查找树”: 1.元素brr(i)的二叉查找树
2.相对应的元素序号i的二叉图
三、VBA中如何用数组构建二叉查找树 以文首乱序序列为例,以构建对排序“稳定”的二叉查找树为例。 i:1、2、3、4、5、6、7、8、9、10 brr(i):5、2、6、1、3、9、7、6、4、8 1.记录左孩子序号 i:1、2、3、4、5、6、7、8、9、10 l(i):2、4、0、0、0、7、8、0、0、0 2.记录右孩子序号 i:1、2、3、4、5、6、7、8、9、10 r(i):3、5、6、0、9、0、10、0、0、0 3.记录父节点序号 i:1、2、3、4、5、6、7、8、9、10 f(i):0、1、1、2、2、3、6、7、5、7 4.记录各节点位于父节点的左枝或右枝 i:1、2、3、4、5、6、7、8、9、10 lr(i):False、False、True、False、True、True、False、False、True、True 其中:False表示左枝,True表示右枝。 5.标记各节点元素值(或键值)是否被“中序遍历”记录进有序区 i:1、2、3、4、5、6、7、8、9、10 jl(i):False、False、False、False、False、False、False、False、False、False 全部为True时意味着程序(或“中序遍历”)的结束。 6.动态记录当前节点及其父节点的序号 i1:当前节点的父节点序号 i2:当前节点的序号 其实,程序中的所谓“二叉查找树”主要由源数组brr(i)和上面1~4项中的数组:l(i)、r(i)、f(i)、lr(i)共同组成,是指它们的逻辑结构是“二叉查找树”,而非呈现形态。 四、二叉查找树的遍历取值 1.先序遍历:父节点→左孩子→右孩子; 2.中序遍历:左孩子→父节点→右孩子; 3.后序遍历:左孩子→右孩子→父节点。 可见,左孩子的访问始终在右孩子之前,以父节点的访问位置为划分依据,居左为“先序”,居中为“中序”,居右为“后序”。下面主要介绍“中序遍历”,因为该遍历方式下生成的是从小到大的已排序序列。 上例中,对于排序“稳定”的二叉查找树各节点的遍历次序如下图:
其实,程序中实际的遍历寻找路线是: 5→2→1→2→3→4→3→2→5→6→10→8→7→8→9→8→10 虽然说“只需遍历一次”就可提取出完整的已排序序列,但是明显可以看出,这“一次”中既有“寻找”,又有“回溯”,来回折腾不在话下,故而效率低了些,比不上快速排序,但是比起“堆”这种二叉树的维护来说,效率又是高的。
|