`
sunlujing
  • 浏览: 180079 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

面试时让我手写二叉查找树删除节点函数

阅读更多

找个实习不容易,今天去面试,面试官先问了我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();
		

	}


}

 

 

1
0
分享到:
评论
7 楼 kjmmlzq19851226 2013-06-17  
sunlujing 写道
kjmmlzq19851226 写道
面试嘛就说哈思路就行了,真要写的话10个有9.5个写不出来的

当时我就想对面试官说 你20分钟要是写出平衡二叉树删除节点的代码,我永世不入你们公司。

6 楼 sunlujing 2013-06-14  
kjmmlzq19851226 写道
面试嘛就说哈思路就行了,真要写的话10个有9.5个写不出来的

当时我就想对面试官说 你20分钟要是写出平衡二叉树删除节点的代码,我永世不入你们公司。
5 楼 kjmmlzq19851226 2013-06-14  
面试嘛就说哈思路就行了,真要写的话10个有9.5个写不出来的
4 楼 sunlujing 2013-06-11  
hamber 写道
目测楼主应该很牛逼的样子。

我要是很牛逼就不至于找个实习都老费劲了。哎
3 楼 hamber 2013-06-11  
目测楼主应该很牛逼的样子。
2 楼 sunlujing 2013-06-11  
lvwenwen 写道
深入了解JVM?是哪一本啊

深入理解java虚拟机--周志明,觉得不错。
1 楼 lvwenwen 2013-06-11  
深入了解JVM?是哪一本啊

相关推荐

    数据结构与算法面试题(2020最新版)-重点.pdf

    1. AVL树:AVL树是最早被发明的自平衡二叉查找树,特点是任何节点的两个子树高度差不超过1,因此被称为高度平衡树。AVL树的主要操作包括查找、插入和删除,它们在平均和最坏情况下的时间复杂度都是O(log n)。在插入...

    二叉树源代码,纯手写好理解

    为了实现一个纯手写的二叉树源代码,我们需要定义一个二叉树节点结构,通常包括节点值、左子节点和右子节点的引用。以下是一个简单的C++实现: ```cpp struct TreeNode { int val; TreeNode* left; TreeNode* ...

    面试题手写代码(很实用)

    面试中可能会要求你手写DOM解析器,理解和操作DOM树,例如查找特定元素、修改节点属性或者遍历整个文档结构。熟悉JavaScript的DOM API是必要的,同时了解SAX和DOM解析的区别也是加分项。 再来看“通迅”这个标签,...

    前端面试题-手写代码实现

    2. **函数实现.js**:此文件可能包含一系列要求面试者手写的函数题目,包括但不限于常见的高阶函数(如map、reduce、filter)、闭包、递归、函数柯里化等。此外,函数式编程的概念和实践也是前端面试中常见的考察点...

    「2021」高频前端面试题汇总之手写代码篇.pdf

    "前端面试题汇总之手写代码篇" 本资源主要对前端面试题的常见问题进行了总结和分类,涵盖了 JavaScript 基础知识、手写代码等方面的知识点。下面是对本资源中提到的知识点的详细解释: 1. 手写 Object.create 方法...

    支持异步加载的纯手写的js树

    本人手写的一款js树形控件,附带图片,代码简洁,注释齐全,可读性高,易于维护,方便移植,结构清晰,思路明了,界面美观,同时支持异步加载,对浏览器的兼容行强,你还可以根据自己的需要扩展功能,可大量应用于...

    纯JS+JQ手写web树

    3. **递归渲染**:为了将数据结构转换为可视化的树,可以使用递归函数遍历树节点,为每个节点创建DOM元素并将其插入到页面适当的位置。 4. **事件处理**:通过`addEventListener`或jQuery的`.on()`方法,可以为树...

    算法面试通关手写代码40讲 .txt

    57.理论讲解:布隆过滤器.mp4 56.面试题:设计和实现一个LRU Cache缓存机制.mp4 55.理论讲解: LRU Cache.mp4 54.面试题:岛屿的个数&朋友圈(下).mp4 53....面试题:二叉树&二叉搜索树的最近公共祖先.mp4

    原生js手写tree树形分类选择插件

    5. **API设计**:为了让插件更易用,可以设计一套API,如`init(treeData)`初始化树,`expand(node)`展开节点,`collapse(node)`折叠节点,`select(node)`选择节点,`getSelectedNodes()`获取已选择的节点等。...

    手写卷积函数.zip

    本项目名为“手写卷积函数.zip”,其核心内容是作者手写代码实现了卷积操作,旨在帮助理解卷积的工作原理,并演示不同卷积核对图像处理的影响。 卷积操作通常由以下几个步骤组成: 1. **定义卷积核**:卷积核是一...

    MNIST手写字识别+ReLU激活函数+规则化

    MNIST手写字识别是机器学习领域的一个经典任务,主要用于测试和开发手写数字识别的算法。这个任务的数据集包含了60,000个训练样本和10,000个测试样本,每个样本都是28x28像素的灰度图像,代表了一个0到9的手写数字。...

    java程序员最可能被考到的面试题.pdf,这是一份不错的文件

    - 二叉查找树(BST):了解其特性,如左子树值小于根,右子树值大于根,以及如何实现和遍历二叉查找树。 以上是Java面试中常见的问题,涵盖链表、数组、字符串、排序算法、数据结构和算法等多个方面,对这些知识点...

    面试常写的c语言函数

    面试嵌入式工程师常见的手写C语言函数,全部摘录与Rtthread内核源码进行少量修改

    pytorch学习(九)——交叉熵代价函数原理及其在MNIST手写数字识别中的应用

    上传时间:2020/11/09 ...内容:pytorch框架:交叉熵代价函数原理及其在MNIST手写数字识别中的应用(神经网络) 其他:pytorch学习练习代码 相关介绍:https://blog.csdn.net/jerry_liufeng/article/details/109573157

    面试必备JS函数工具库手写.docx

    在JavaScript中,`call()`, `apply()`, 和 `bind()` 都是用来改变函数执行时的上下文(即`this`的指向)。这三个方法对于理解JavaScript的运行机制至关重要,尤其在面试中经常被考察。 首先,我们来看`call()`方法...

    手写代码必备手册—面试必须

    在准备技术面试,尤其是外企面试时,手写代码是考察应聘者编程能力和思维能力的重要环节。手写代码不仅仅是简单地写出正确的代码,更是要在限定时间内理解题目要求、设计算法、调试代码,并以清晰的逻辑表达出来。在...

    09-手写函数bind.md

    在前端领域,掌握如何手写核心函数是面试中常见的考点,其中函数的bind、call和apply方法是面试必考内容。这些方法涉及到函数上下文、参数传递等重要概念,是编写高质量JavaScript代码不可或缺的技能。下面详细介绍...

    场论与复变函数_67_西电(梁昌洪)-手写课件

    3. **黎曼面**:在处理复杂系统的动态行为时,黎曼面可以用来表示多值函数,比如在混沌理论和动力系统的研究中。 4. **复数极坐标**:在优化问题中,使用极坐标表示复数可以简化计算,特别是在矩阵运算和特征值问题...

    天天造轮子,手写面试常见源码.zip

    3. **查找算法**:线性查找、二分查找、哈希查找、二叉搜索树查找等。理解其查找效率和适用情况。 4. **递归与回溯**:用于解决组合优化问题、路径搜索等问题,如八皇后问题、迷宫问题、图的深度优先搜索等。 5. *...

    前端面试常见手写题整理.zip

    4. **DOM操作**:理解DOM树结构,能熟练使用`getElementById`、`querySelector`、`querySelectorAll`等方法,以及添加、删除和修改元素属性。 5. **AJAX与Fetch API**:理解异步请求的原理,掌握XMLHttpRequest或新...

Global site tag (gtag.js) - Google Analytics