昨天做了个二叉树的笔试题 大概十几分钟就做完了 但是有些疑惑 想到了一个新题 不知道有没有人能解

2015-06-15 22:13:39 +08:00
 woai110120130
下面是笔试题目: 根据用户的输入的字母, 构建一个满二叉树, 然后打印出它的所有从根到叶子的路径. (假设用户的输入字母的个数恰好满足构建一个满二叉树)
例如: 输入 a b c d e f g后构建成下面的树
a
b c
c d e f 就是这样的一个满二叉树

然后输出 abc,abd,ace,acf
要求: 使用任意一种你熟悉的语言即可。
然后菜鸟我是这样做的

/**
* Created by tangtang on 15/6/15.
*/
public class Tree {


public static void main(String[] args)
{
byte[] byteArray={'D','B','A','C','F','E','G'};

Node root=new Node();




for (byte b: byteArray)
{
root.insert(b);

}

root.traverseBiTree("");
}


static class Node{

private byte value=-1;

private Node leftChild;
private Node rightChild;

public Node getLeftChild()
{
return leftChild;
}

public Node getRightChild()
{
return rightChild;
}


public byte getValue()
{
return value;
}

public void setLeftChild(Node leftChild)
{
this.leftChild=leftChild;
}

public void setRightChild(Node rightChild)
{
this.rightChild=rightChild;
}

public void setValue(byte value)
{
this.value=value;
}


/**
* 遍历加打印 遍历路径
* 思路 让上一层都产生一个string
* @return
*/
public void traverseBiTree(String str)
{
str+=(char)value;
if (leftChild==null&&rightChild==null) {
System.out.println(str);
return;
}

if (leftChild!=null)
{
leftChild.traverseBiTree(str);
}

if (rightChild!=null)
{
rightChild.traverseBiTree(str);
}
}




public void insert(byte c)
{
if (value==-1) {
value = c;
return;
}

if (c>value)
{
if (rightChild==null)
rightChild=new Node();
rightChild.insert(c);
}else {
if (leftChild==null)
leftChild=new Node();
leftChild.insert(c);
}

}

}
}

用java写的 有点长 不过去掉set get方法也非常简洁了


在做的过程产生了这样一个问题
如果 试题问的 就是输入a b c d e f g 生成上边的那个满二叉树 要求下一层的孩子都大于上一层的孩子 并且 右孩子都大于左孩子 如何生成该 上面的那个满二叉树? 好好想想 这个问题还是很困难的
要求只能一个一个的插入 不可以先排序再生成二叉树
6250 次点击
所在节点    程序员
56 条回复
Heartwork
2015-06-16 09:14:03 +08:00
@binux 恩,不错,是这样
binux
2015-06-16 09:17:43 +08:00
@Heartwork 所以只要层间排序,不需要层内排序。
如果一次解决就是做一半快速划分,如果插入就是层内做大根堆。
都是 O(n) 的
Heartwork
2015-06-16 09:38:18 +08:00
@binux 堆的那个恐怕不行吧。怎么处理插入一个比该层元素都小的值?
binux
2015-06-16 10:07:12 +08:00
@Heartwork 大根堆顶往下推,不然为什么是大根堆呢
zwzmzd
2015-06-16 10:17:43 +08:00
这个题目根据描述很可能有歧义,我觉得楼主你在叫人写代码之前应该给出几个测试用例,这样别人才好着手去写
woai110120130
2015-06-16 12:03:59 +08:00
@zwzmzd 哈哈 没有其他的意思 就是讨论学习 我并没有测试用例 确实有人理解的不太正确 嗯等晚上下班在写吧
woai110120130
2015-06-16 12:05:12 +08:00
@binux 不是我 我出题的意思是
隐藏 感谢回复者 Reply 40
binux 3 小时 0 分钟前
@woai110120130 事实?你自己问题都说不清楚,让人家找事实?你写得出测试用例吗?

@Heartwork 不是的
a
b c
d e f g
成立

a
b c
e g d f 这个不成立 右边的都要大于左边的 可能是我描述的不清楚 实在不好意思哈
binux
2015-06-16 12:33:48 +08:00
@woai110120130 如果右边的都要大于左边,这棵树可以被证明是完全排序的,这个题目就更没意义了。
billwsy
2015-06-16 14:43:42 +08:00
你要求的所谓树用数组来表示那就是有序数组嘛,要求可以快速随机访问插入那就是块状链表了,效率是sqrt(n)
woai110120130
2015-06-16 14:46:57 +08:00
@billwsy 其实更像是杨辉三角 但是要求动态插入 而不是排好序再排列
billwsy
2015-06-16 14:52:26 +08:00
Oops, 似乎弄错了,我把条件加强了。。
billwsy
2015-06-16 15:02:59 +08:00
这样做如何:每一层对应一个大根堆,插入时二分查找到需要插入的层,O(lg lg n),将其根剔除并插入元素,将其根插入下一层,每次执行O(lg n),最多执行lg n次,效率O(lg^2 n);总效率O(lg lg n + lg n * lg n) = O(lg^2 n)。如果用数组来存储堆,并且将所有数组头尾相接起来,可以以大数组来解释二叉树。
这样的话,总效率O(n lg^2 n),缺点是插入时会破坏所有原有的父子关系。
billwsy
2015-06-16 15:05:52 +08:00
Oops,又漏了。用大数组来解释时,会出现左儿子大于右儿子的情况,访问时交换它们修正就可以了
billwsy
2015-06-16 15:07:48 +08:00
发现@binux 已经给出正解了…默默匿了…
billwsy
2015-06-16 15:10:45 +08:00
好吧,按@woai110120130 47楼的解释,那我的解答就是49楼提到的块状链表了……
洗洗睡了……
woai110120130
2015-06-16 22:16:33 +08:00
@billwsy 好的吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/198803

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX