您的位置:首页 > 其它

二叉树题目

2013-10-17 19:51 302 查看
1. 二叉树的三种遍历方式

先序遍历:节点 -> left子节点(包括其子树)-> right子节点(包括其子树);
后序遍历:left子节点(包括其子树)-> right子节点(包括其子树)-> 节点;
中序遍历:left子节点(包括其子树)-> 节点 -> right子节点。
2. 怎样从根开始逐层打印二叉树结点数据

其实就是广度优先遍历(BFS)的思想。

使用一个队列queue,将root入队;
若queue不为空,出队一个节点,并将此节点两个儿子按从左到右顺序入栈
则出队顺序即为逐层遍历顺序。
3. 如何判断一颗二叉树是否平衡二叉树?

平衡二叉树定义:任意节点的左右子树深度相差不超过1。

只要当前节点root的left和right深度差不超过1,就递归判断left和right是否也符合条件,直到left或right为null,这意味着他们的深度为0,能走到这一步,前面必然都符合条件,所以整个二叉树都符合条件。

//先编写一个递归计算二叉树深度的函数getDepth,利用递归实现
public static int getDepth(Node root){

if(root == null)
return 0;
int leftDepth = getDepth(root.left);
int rightDepth = getDepth(root.right);
return (leftDepth > rightDepth? leftDepth : rightDepth) + 1;
}

public static boolean isBalance(Node root){
if(root == null)
return true;

int leftDepth = getDepth(root.left);
int rightDepth = getDepth(root.right);
int distance = leftDepth > rightDepth ? leftDepth-rightDepth : rightDepth - leftDepth;

if(distance > 1)
return false;
else
return isBalance(root.left) && isBalance(root.right);
}
4. 设计一个算法,找出二叉树上任意两个节点的最近共同父节点,复杂度如果是O(N^2)则不得分。

需要两个栈,在递归遍历寻找两个节点的同时,将从根到两个节点的路径分别压栈(由于是递归,两节点父节点最先入栈,根最后入栈);
同时pop两个元素,如果相等,则继续pop,直到不等,则之前相等的元素节点就是最近共同父节点。

此解法需要两个辅助栈。

注意这里是二叉树而不是二叉查找树,如果是二叉查找树,则不需要递归查找,直接往下遍历,直到分叉位置,就是最近共同父节点。

//递归寻找节点,并将路径存入stack中
pubilc static boolean getPositionByNode(Node root, Node node, Stack<E> stack){

if(root == null)
return false;
//递归的基准情况
if(root == node){
stack.push(root);
return true;
}
//递归调用
if(getPositionByNode(root.left, node, stack) || getPositionByNode(root.right, node, stack)){
stack.push(root);
return true;
}
return false;
}

public static Node findParentNode(Node root, Node node1, Node node2){

Stack stack1 = new Stack();
getPositionByNode(node1, stack1);
Stack stack2 = new Stack();
getPositionByNode(node2, stack2);

Node temp = null;
//两者不相等,则同时弹栈,但是要记录弹栈元素
while(stack1.peek() != stack2.peek()){
temp = stack1.pop();
stack2.pop();
}
return temp;
}


5. 如何不用递归实现二叉树的三种遍历。

先序遍历
//先序遍历
public static void preOrder(Node root){

Stack stack = new Stack();
Node node = root;

while(node != null || stack.size() > 0){
//压入所有左节点,压入前打印
while(node != null){
System.out.println(node.data);
stack.push(node);
node = node.left;
}

if(stack.size() > 0){
node = stack.pop();
node = node.right;
}
}
}

后序遍历
//后序遍历
public static void postOrder(Node root){

Stack stack = new Stack();

Node node = root;
Node prev = node;

while(node != null || stack.size() > 0){
//压入所有左节点
while(node != null){
stack.push(node);
node = node.left;
}

if(stack.size() > 0){

Node temp = stack.peek().right;
//如果右节点是null或者刚访问过
if(temp == null || temp == prev){
node = stack.pop();
System.out.println(node.data);
prev = node;
node = null;
}else{
node = temp;
}
}
}
}

中序遍历
//中序遍历
public static void inOrder(Node root){

Stack stack = new Stack();

Node node = root;

while(node != null || stack.size() > 0){
//压入所有左节点
while(node != null){
stack.push(node);
node = node.left;
}

if(stack.size() > 0){
node = stack.pop();
System.out.println(node.data);
node = node.right();
}
}
}

6. 在二叉树中找出和为某一值的所有路径

当访问某一个节点时,把该节点添加到路径上,并累加当前节点的值。如果当前节点为叶节点并且当前路径的和刚好等于输入的整数,则当前的路径符合要求,把它打印出来。如果当前节点不是叶节点,则继续访问它的子节点。当前节点访问结束后,递归函数自动回到父节点。因此,函数退出之前要在路径上删除当前节点并减去当前节点的值,以确保返回父节点时路径刚好是根节点后父节点的路径。不难看出保存路径的数据结构实际上是一个栈结构。

7. 编写一个程序,把一个有序整数数组放到二叉树中

构造一个完全二叉树,让数组第一个元素小标为1,则有左儿子是2i, 右儿子是 2i+1,这样是平衡的。

8. 判断整数序列是不是二叉查找树的后序遍历结果

在后序遍历的序列中,最后一个元素为树的根节点。从头开始扫描这个序列,比根节点小的元素都应该位于序列的左半部分,从第一个大于根节点开始到根节点前面一个元素为止,所有元素都大于根节点,因为这部分元素对应的是树的右子树。根据这样划分,把序列分为左右两部分,递归的确认序列的左右两部分是不是都是二叉查找树。

9. 求二叉树的镜像

利用遍历二叉树的方法,把访问操作修改为交换左右节点的逻辑即可。

10. 一棵二叉查找树,令 f = (最大值 + 最小值)/2,设计一个算法,找出距离 f 值最近,大于 f 值的节点。复杂度如果是O(n^2)则不得分。

//最小最大节点分别在最左下与最右下节点
public static Node find(Node root){
Node min = findMinNode(root);
Node max = findMaxNode(root);

double find = (double)(min.data + max.data)/2.0;

return findNode(root, find);
}

//最小节点
public static Node findMinNode(Node root){
Node min = root;
]
while(min.left != null)
min = min.left;

return min;
}

//最大节点
public static Node finMaxNode(Node root){
Node max = root;

while(max.right != null)
max = max.right;

return max;
}

//寻找节点,O(logN)
public static findNode(Node root, double mid){
//如果小于等于,则从右边找一个最小值
if(root.data <= mid){
if(root.right == null)
return root;
Node find = findNode(root.right, mid);
//不一定找得到
return find.data < mid ? root : find;
}
//如果大于,则找到left
else{//root.data > find
if(root.left == null)
return root;
Node find = findNode(root.left, mid);
//不一定找到
return find.data < mid ? root:find;
}
}


11. 把二叉查找树转变成排序的双向链表。

就是树的中序遍历。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息