《算法导论》笔记 第12章 12.1 二叉查找树
【总结】
终于刷到这里了。
二叉查找树性质:
设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)时间。