创造练习——自适应树(Self-Adjusting Tree)
这个树的定义的确很有问题。其实AVLTree和SplayTree以及RedBlackTree都是self-adjusting Tree
因为如果是树做索引那么大部分的时间将用来查找。这个树在查找上可以将查找的节点提升到树根,插入时也是一样。这样提高了查找的效率。并且操作系统有一种说法是近来用
到的,将来用到的几率也会很大(LRU原理)。删除,既然删除对于此树来说再也没有什么,那就直接删除算了。
根据这几点想法。自己做一个self-adjusting Tree。但是还没有验证是否能达到实际水平的O(nlogn)。虽然理论上这个树并不能达到这样一个时间
复杂度。但是对于实际数据来说,还是有可能达到的。不知道有没有这么lucky。
因为对于这个树来说插入和查找操作其实差不多。
所以下面只介绍插入操作。找到要插入的地方,反遍历单旋转(这里和SplayTree不同一点是只使用单旋转)
TreeNode
返回值为当前子树根节点
1.subroot是否为空,创建新的节点,并返回subroot
2.如果不为空
A.subroot中的值 < data中的值,对subroot右子树调用insertNode(),subroot
与当前右子树根节点采用旋转操作。将两个节点位置对换。
B.subroot中的值 > data中的值,对subroot左子树调用insertNode(),subroot
与当前左子树根节点采用旋转操作。将两个节点位置对换。
C.subroot中的值 == data中的值,do nothing
3.查看该节点是否已成为根节点。如果是的话,调整根节点的值。
下面给出代码。
- template < class T>
- class SelfTree: public BinaryTree
- {
- private :
- // return the sub tree root
- // a b
- // / -> /
- // b a
- TreeNode
* sLeftRotate(TreeNode * a,TreeNode * b) - {
- a->setLeft(b->getRight());
- b->setRight(a);
- return b;
- }
-
-
- // return the sub tree root
-
- // a b
- // / -> /
- // b a
- TreeNode
* sRightRotate(TreeNode * a, TreeNode * b) - {
- a->setRight(b->getLeft());
- b->setLeft(a);
- return b;
- }
-
-
-
- TreeNode
* insertNode(TreeNode * subroot,TreeNode * prev,T& data)
- TreeNode
-
-
- {
- if (subroot == NULL)
- {
- subroot = new TreeNode
(data); - return subroot;
- }
- else
- {
- TreeNode
* tempNode = NULL; - TreeNode
* tempRoot = NULL; - if (subroot->getData() > data)
- {
-
- tempNode = insertNode(subroot->getLeft(),subroot,data);
- tempRoot = sLeftRotate(subroot,tempNode);
-
- }
- else if (subroot->getData() < data)
- {
- tempNode = insertNode(subroot->getRight(),subroot,data);
- tempRoot = sRightRotate(subroot,tempNode);
- }
- else
- {
- throw “the same key” ;
- }
-
- if (prev == NULL)
- {
- this ->head = tempRoot;
- }
- else
- {
- if (prev->getData() > tempRoot->getData())
- {
- prev->setLeft(tempRoot);
- }
- else
- {
- prev->setRight(tempRoot);
- }
- }
- return tempRoot;
- }
- }
- public :
- SelfTree(T& data):BinaryTree(data)
- {
-
- }
-
- ~SelfTree()
- {
-
- }
-
- void insertNode(T& data)
- {
- insertNode( this ->head,NULL,data);
- }
-
- };