|
锁定老贴子 主题:艾格瑞哲姆攻击第二波,有兴趣的人便来战吧!
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2005-08-31
嗯嗯,我想大家都知道二叉排序树是怎么回事吧?而且大家也都知道二叉树的前序、中序、后序遍历是怎么一回事吧?不知道的人自己回去翻书。OK,那么现在题目是这样的:
引用 已知有一棵二叉排序树,其中保存了 n 个互不相同的元素,且左子树中的元素小于根小于右子树中的元素。现在给你这棵二叉排序树的前序遍历序列,请你给出一个算法能够把这棵二叉排序树重新构造起来。具体实现不拘,用伪码说明也可以,但是要求:
1、说明你的算法的正确性。 2、分析你的算法的时间复杂度。 嗯嗯,和上次一样,这题给出一个解是相当容易的,不过说明正确性和分析复杂度可能需要费点口舌,另外就是能不能把时间复杂度压下来。有兴趣的人便来试试吧。 最后 BS 一下看不懂我标题的家伙,:D:D 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
啊啊,几乎要被鄙视到,幸亏及时想起……
|
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
gigix 写道 啊啊,几乎要被鄙视到,幸亏及时想起……
咔咔,居然被你逃过一劫么? :D |
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
重新构造的二叉排序树,唯一吗?
|
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
buaawhl 写道 重新构造的二叉排序树,唯一吗?
唯一。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
1 2 3 4 5 6 7 8 9
case A: ------------------- 4 ------------------/---\ -----------------2-----8 ---------------/--\----/--\ -------------1----3--6---9 ---------------------/--\ --------------------5---7 case B: -------------------- 9 --------------------/ ------------------ 8 ------------------/ -----------------7 -----------------/ ----------------6 ----------------/ ---------------5 ---------------/ --------------4 --------------/ -------------3 -------------/ ------------2 -----------/ ----------1 ================== Sorry. 忘了什么是 前序了。给出的是中序。 http://student.zjzk.cn/course_ware/data_structure/web/shu/shu6.3.1.htm 引用 遍历概念 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。 遍历方案 1.遍历方案 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作: (1)访问结点本身(N), (2)遍历该结点的左子树(L), (3)遍历该结点的右子树(R)。 以上三种操作有六种执行次序: NLR、LNR、LRN、NRL、RNL、RLN。 注意: 前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。 2.三种遍历的命名 根据访问结点操作发生位置命名: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderTraversal) ——访问结点的操作发生在遍历其左右子树之后。 注意: 由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtlee)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。 遍历算法 1.中序遍历的递归算法定义: 若二叉树非空,则依次执行如下操作: (1)遍历左子树; (2)访问根结点; (3)遍历右子树。 2.先序遍历的递归算法定义: 若二叉树非空,则依次执行如下操作: (1) 访问根结点; (2) 遍历左子树; (3) 遍历右子树。 3.后序遍历得递归算法定义: 若二叉树非空,则依次执行如下操作: (1)遍历左子树; (2)遍历右子树; (3)访问根结点。 4.中序遍历的算法实现 用二叉链表做为存储结构,中序遍历算法可描述为: void InOrder(BinTree T) { //算法里①~⑥是为了说明执行过程加入的标号 ① if(T) { // 如果二叉树非空 ② InOrder(T->lchild); ③ printf("%c",T->data); // 访问结点 ④ InOrder(T->rchild); ⑤ } ⑥ } // InOrder 记得《数据结构》书里面讲了这个反构造的算法。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
给定的是前序序列![color=red][/color]
|
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
buaawhl 写道 记得《数据结构》书里面讲了这个反构造的算法。 一般数据结构书里讲的算法,是给你前序序列(或是后序序列)和中序序列,然后重新构造二叉树,而且是任意的二叉树。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
我说,这题没有这么难吧?还是大家都不好意思给 navie 的算法憋着劲要出最优解法?
|
|
| 返回顶楼 | |
|
最后更新时间:2005-08-31
没看太多,第一反映就是递归来做,实在对不起啊,习惯了用递归:
取中间计算元素 左链给递归(1,n/2-1)函数 右链给递归(n/2+1, n)函数 返回中间元素指针 --------------------------------------------------- 小声问一句,前序排序二插数的输出,是不是一个由小到大的有序输出啊?上面写的是按照如果输入是由小到大的有序输入设计的。 |
|
| 返回顶楼 | |











