找个实习不容易,今天去面试,面试官先问了我JVM的很底层东西,因为看过深入了解JVM这本书答得很顺,结果面试官来劲了,先说 你给我写一个 平衡二叉查找树删除节点的代码,我故意念到 “平衡二叉查找树”,面试官见我认怂说那你写二叉查找吧,我只知道删除节点有三种情况,分为删除节点是否是叶子节点,有一个子节点,有两个子节点,但是当场手写代码还是没有写出来。回来在参考书的帮助下手写了一遍。哎,基础不行。
package graphic;
public class BinarySearchTree {
private TreeNode root = null;
/**
* 中序遍历
* @param root
*/
public void inOrder_tree_walk(){
inOrder(root);
}
private void inOrder(TreeNode root){
if(root==null){return;}
inOrder(root.left);
System.out.print(root+" ");
inOrder(root.right);
}
/**
* 返回指向key的节点指针
* @param root
* @param key
* @return
*/
public TreeNode treeSearch(int key){
if(root==null)return null;
TreeNode cur = root;
while(cur!=null && cur.value!=key){
if(cur.value >key){
cur = cur.left;
}else{
cur = cur.right;
}
}
return cur;
}
/**
* 返回包含最小key的节点指针
*/
public TreeNode treeMinimum(TreeNode root){
if(root==null)return null;
TreeNode cur = root;
while(cur.left!=null){
cur = cur.left;
}
return cur;
}
/**
* 返回包含最大key的节点指针
* @param root
* @return
*/
public TreeNode treeMaximum(TreeNode root){
if(root==null)return null;
TreeNode cur = root;
while(cur.right!=null){
cur = cur.right;
}
return cur;
}
/**
* 返回node 节点的后继节点
* @param root
* @param node
* @return
*/
public TreeNode treeSuccessor(TreeNode node){
//rigth branch is not null
if(node.right!=null)return treeMinimum(node.right);
//if the right branch is null
TreeNode cur = node.parent;
while(cur!=null && node == cur.right){
node = cur;
cur = cur.parent;
}
return cur;
}
/**
* 返回node 节点的前继节点
* @param root
* @param node
* @return
*/
public TreeNode treePredecessor(TreeNode node){
if(root.left!=null) return treeMaximum(root.left);
//the left branch is null
TreeNode cur = node.parent;
while(cur!=null && node==cur.left){
node = cur;
cur = cur.parent;
}
return cur;
}
/**
* 插入新节点
* @param root
* @param insert
*/
public void treeInsert(TreeNode insert){
if(root==null){
root = insert;
return ;
}
TreeNode cur = root;
TreeNode parent =null;
while(cur!=null){
parent = cur;
if(insert.value >=cur.value){cur = cur.right;}
else{cur = cur.left;}
}
if(insert.value >=parent.value){
parent.right = insert;
insert.parent = parent;
}else{parent.left = insert;insert.parent = parent;}
}
/**
* 删除目标节点
* @param root
* @param target
*/
public void delete(TreeNode target){
//find the node need to be deleted
TreeNode delNode;
//只有一个孩子或者是叶子节点
if(target.left==null || target.right==null){
delNode = target;
}else{
//如果有两个孩子就找到后继节点作为删除的节点
delNode = treeSuccessor(target);
}
//对于所有情况,要删除的节点最多只有一个孩子
//这个时候需要找到删除节点的孩子节点和父亲节点,并把父亲节点指向孩子节点,
//孩子节点的指针也指回新的父亲节点
TreeNode child;
if(delNode.left ==null){
child = delNode.right;
}else{child = delNode.left;}
TreeNode parent = delNode.parent;
if(parent.left == delNode){
parent.left = child;
}else{
parent.right = child;
}
if(child!=null){
child.parent = parent;
}
//delete the successor
if(delNode!=target){
target.value = delNode.value;
}
freeNode(delNode);
}
/**
* 删除包含key的第一个节点
* @param root
* @param key
*/
public void treeDelete(int key){
TreeNode searched = treeSearch(key);
delete(searched);
}
private void freeNode(TreeNode node){
node.parent =null;
node.left = null;
node.right = null;
}
private void addNode(TreeNode node){
treeInsert(node);
}
private class TreeNode{
TreeNode parent = null;
TreeNode left = null;
TreeNode right = null;
int value = 0;
@Override
public String toString() {
return value+"";
}
public TreeNode(int value) {
this.value = value;
}
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
TreeNode node = tree.new TreeNode(15);
tree.addNode(node);
node = tree.new TreeNode(6);
tree.addNode(node);
node = tree.new TreeNode(18);
tree.addNode(node);
node = tree.new TreeNode(3);
tree.addNode(node);
node = tree.new TreeNode(7);
tree.addNode(node);
node = tree.new TreeNode(17);
tree.addNode(node);
node = tree.new TreeNode(20);
tree.addNode(node);
node = tree.new TreeNode(2);
tree.addNode(node);
node = tree.new TreeNode(4);
tree.addNode(node);
node = tree.new TreeNode(13);
TreeNode node13= node;
tree.addNode(node);
node = tree.new TreeNode(9);
tree.addNode(node);
tree.inOrder_tree_walk();
System.out.println();
System.out.println(tree.treeSearch(15).parent);
System.out.println(tree.treeSuccessor(node13));
tree.treeDelete(6);
tree.inOrder_tree_walk();
}
}
相关推荐
- 二叉查找树(BST):了解其特性,如左子树值小于根,右子树值大于根,以及如何实现和遍历二叉查找树。 以上是Java面试中常见的问题,涵盖链表、数组、字符串、排序算法、数据结构和算法等多个方面,对这些知识点...
4. **树**:树是分层的数据结构,包括二叉树、二叉搜索树、平衡树(如AVL树、红黑树)等。二叉树常用于查找、排序等,Python中可以通过类来实现。 5. **堆**:堆是一种特殊的树形数据结构,满足堆性质(最大堆或...
红黑树是一种自平衡二叉查找树,其特点包括:每个节点是红色或黑色,根节点是黑色,所有叶子节点是黑色,每个红色节点的两个子节点都是黑色(或者为空),从任一节点到其每个叶子的所有简单路径都包含相同数量的...
7. **树**:如二叉搜索树、平衡树(AVL树、红黑树),用于高效查找、排序等操作。 8. **图**:用于表示对象之间的关系,如邻接矩阵和邻接表。 二、算法 算法是解决问题或执行任务的明确步骤,是编程的灵魂。常见的...
6. 树结构:二叉树、二叉搜索树、平衡树(AVL、红黑树)等,Java中的TreeMap和TreeSet使用了红黑树。 7. 图:图用于表示对象之间的关系,Java中可以使用邻接矩阵或邻接表来表示。 二、算法篇 1. 排序算法:冒泡...