Traversal is largely unchanged from BSTs. However, we can be confident that the tree won't easily exceed the maximum stack height, because of the AVL balance condition, so we can omit checking for stack overflow.
5.6 遍历
178. <AVL traversal functions 178> = <BST traverser refresher; bst => avl 62> <BST traverser null initializer; bst => avl 64> <AVL traverser least-item initializer 180> <AVL traverser greatest-item initializer 181> <AVL traverser search initializer 182> <AVL traverser insertion initializer 179> <BST traverser copy initializer; bst => avl 69> <AVL traverser advance function 183> <AVL traverser back up function 184> <BST traverser current item function; bst => avl 74> <BST traverser replacement function; bst => avl 75>
This code is included in 145 and 196.
We do need to make a new implementation of the insertion traverser initializer. Because insertion into an AVL tree is so complicated, we just write this as a wrapper to avl_probe(). There probably wouldn't be much of a speed improvement by inlining the code anyhow:
179. <AVL traverser insertion initializer 179> =
下面我们会实现其它余下的所有的函数,它们只是有很小部分的修改,所以就不在添加注释了
180. <AVL traverser least-item initializer 180> =
181. <AVL traverser greatest-item initializer 181> =
182. <AVL traverser search initializer 182> =
183. <AVL traverser advance function 183> =
184. <AVL traverser back up function 184> =
Exercises:
1. Explain the meaning of this ugly expression, used in avl_t_insert():
(struct avl_node *) ((char *) p - offsetof (struct avl_node, avl_data))
A: At this point in the code, p points to the avl_data member of an struct avl_node. We want a pointer to the struct avl_node itself. To do this, we just subtract the offset of the avl_data member within the structure. A cast to char* is necessary before the subtraction, because offsetof returns a count of bytes, and a cast to struct avl_node * afterward, to make the result the right type.