【总结】
终于刷到这里了。
二叉查找树性质:
设x为二叉查找树中的一个节点。
如果y是x的左子树中的一个结点,则key[x]<=key[y]。
如果y是x的右子树中的一个结点,则key[x]>=key[y]。
如果x是一棵包含n个结点的子树的根,则调用INORDER-TREE-WALK(x)过程的时间为Θ(n)。
void inoderTreeWalk(NODE *rt) {
if (rt->l) inoderTreeWalk(rt->l);
cout<<rt->key<<endl;
if (rt->r) inoderTreeWalk(rt->r);
}
【练习】
12.1-1 基于关键字集合{1,4,5,10,16,17,21},画出高度为2、3、4、5、6的二叉查找树。
12.1-2 二叉查找树性质与最小堆性质之间有什么区别?能否利用最小堆性质在O(n)时间内,按序输出含有n个结点的树中的所有关键字?行的话,解释该怎么做;不行的话,说明原因。
二叉查找树的中序遍历时有序的,最小值在最左叶子结点上。最小堆的遍历是无序的,最小值在根节点。
12.1-3 给出一个非递归的中序树遍历算法。(两种,用栈,或假设可测试两个指针是否相等)
用栈:
void output(NODE *rt) {
stack<NODE*>sp;
stack<bool>sf;
sp.push(rt);
sf.push(false);
while (!sp.empty()) {
NODE *tp = sp.top();
bool tf = sf.top();
sp.pop();
sf.pop();
if (!tf) {
sp.push(tp);
sf.push(true);
if (tp->l) {
sp.push(tp->l);
sf.push(false);
}
}
else {
cout<<tp->key<<endl;
if (tp->r) {
sp.push(tp->r);
sf.push(false);
}
}
}
}
12.1-4 对一棵含有n个结点的树,给出能在Θ(n)时间内,完成前序遍历和后序遍历的递归算法。
void preOrder(NODE *rt) {
cout<<rt->key<<endl;
if (rt->l) preOrder(rt->l);
if (rt->r) preOrder(rt->r);
}
void postOrder() {
if (rt->l) postOrder(rt->l);
if (rt->r) postOrder(rt->r);
cout<<rt->key<<endl;
}
12.1-5 论证:在比较模型中,最坏情况下排序n个元素的时间为Ω(nlgn),则为从任意的n个元素中构造出一棵二叉查找树,任何一个基于比较的算法在最坏情况下,都要花Ω(nlgn)时间。