`
gengu
  • 浏览: 86748 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

树的相关操作

阅读更多

最近很多大公司的笔试题都考到了树这个数据结构

 

淘宝武汉地区的笔试题倒数第二题是关于树中两个节点找父节点的

 

搜狗昨天又考到了,是找树中两个距离最远节点的题。

 

所以树被考到的概率很高啊,今天又java把树的基本操作都写了一遍,需要的童鞋果断分享吧

package com.gengu.树;

import java.util.Queue;
import java.util.Stack;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.junit.Test;

/**
 * 这里测试树的相关算法
 * 1:构造一个树
 * 2:先序遍历
 * 3:中序遍历
 * 4:后序遍历
 * 5:层次遍历
 * 6:打印某一层二叉树的所有节点
 * 7:求高度
 * 8:求最远的节点
 * 9:判断一个树是不是平衡二叉树
 * */
class Node{
	public int value;
	public Node left;
	public Node right;
	public Node(int value){
		this.value = value;
	}
}

public class TestTree {

	public static Node root = new Node(9);
	public static Node value1 ;
	public static Node value2 ;
	/**
	 * 创建一颗二叉树
	 * */
	public static void createTree(){
		Node node1 = new Node(8);
		Node node2 = new Node(7);
		Node node3 = new Node(6);
		Node node4 = new Node(5);
		Node node5 = new Node(4);
		Node node6 = new Node(3);
		Node node7 = new Node(2);
		Node node8 = new Node(1);
		Node node9 = new Node(0);
		Node node10 = new Node(11);
		Node node11 = new Node(12);
		value1 = node3;
		value2 = node9;
		
		root.left = node1;
		root.right = node2;
		
		node1.left = node3;
		node1.right = node4;
		
		node2.left = node5;
		node2.right = node6;
		
		node3.left = node7;
		node3.right = node8;
		node6.left = node10;
		node10.right = node11;
		node8.right = node9;
	}
	
	
	/**
	 * 先序遍历
	 * */
	public static void rootFirst(Node node){
		System.out.println(node.value);
		if(node.left != null){
			rootFirst(node.left);
		}
		if(node.right != null){
			rootFirst(node.right);
		}
	}
	
	/**
	 * 后序遍历
	 * */
	public static void rootLast(Node node){
		if(node.left != null){
			rootLast(node.left);
		}
		if(node.right != null){
			rootLast(node.right);
		}
		System.out.println(node.value);
		
	}
	
	/**
	 * 中序
	 */
	public static void rootMid(Node node){
		if(node.left != null){
			rootMid(node.left);
		}
		System.out.println(node.value);
		if(node.right != null){
			rootMid(node.right);
		}
	}

	/**
	 * 层次第n层的节点
	 * */
	public static void layer(Node node,int n){
		if(node == null){
			return ;
		}
		if(1 == n){
			System.out.println(node.value);
		}
		else {
			layer(node.left,n-1);
			layer(node.right, n-1);
		}
	}
	
	/**
	 * 求出树的高度
	 * */
	public static int getHeight(Node root){
		if(null == root){
			return 0;
		}else{
			int lh = getHeight(root.left);
			int rh = getHeight(root.right);
			return lh>rh?lh+1:rh+1;
		}
	}
	
	/**
	 * 层次序遍历
	 * */
	public static void layer1(Node root){
		Queue<Node> nodes = new ConcurrentLinkedQueue<Node>();
		//加入第一个节点
		nodes.add(root);
		
		while(true){
			if(nodes.isEmpty()){
				break;
			}
			Node node2 = nodes.poll();
			if(node2.left!=null){
				nodes.add(node2.left);
			}
			if(node2.right!=null){
				nodes.add(node2.right);
			}
			System.out.println(node2.value);
		}
	}
	
	/**
	 * 判断一颗树是不是平衡二叉树
	 * */
	public static boolean isAVL(Node root){
		if(root==null){
			return true;
		}else {
			//求左树的高度
			int left_depth = getHeight(root.left);
			//右子树的高度
			int right_depth = getHeight(root.right);
			System.out.println(left_depth);
			System.out.println(right_depth);
			//如果从这个点可以看出它不平衡那么就返回false
			if(left_depth-right_depth>1||right_depth-left_depth>1){
				return false;
			}
			//如果从这个节点往下看是平衡的不能就说它是平衡
			//还要看它的左右子树
			else {
				return isAVL(root.right)&&isAVL(root.right);
			}
		}
	}
	
	/**
	 * 中序遍历的非递归算法
	 * 要注意的是所有节点都要入栈
	 * */
	public static void inorder(Node root){
		Stack<Node> stack1 = new Stack<Node>();
		Node node = root;
		//stack1.push(root);
		//第一个节点的路径
		while(node!=null||!stack1.isEmpty()){
			if(node!=null){
				stack1.push(node);
				node = node.left;
			}else {
				node = stack1.pop();
				System.out.print(node.value);
				node = node.right;
			}
		}
		System.out.println();
	}
	
	/**
	 * 先序遍历
	 * 非递归算法
	 * */
	public static void preorder(Node root){
		Stack<Node> stack = new Stack<Node>();
		Node node = root;
		stack.push(root);
		while(!stack.isEmpty()){
			node = stack.pop();
			System.out.print(node.value);
			if(node.right!=null){
				stack.push(node.right);
			}
			if(node.left!=null){
				stack.push(node.left);
			}
		}
		System.out.println();
	}
	
	/**
	 * 寻找最近公共父节点
	 * */
	public static Node commanNode(Node root,Node value1,Node value2){
		if(root == null){
			return null;
		}
		else if(root==value1){
			//这里表示的是如果在其它地方没有找到value2
			//而找到了value1 那么表示value2在value1下面
			//所以返回value1
			return value1;
		}
		//同上
		else if(root==value2){
			return value2;
		}
		/**
		 * 这里是一个分治的思想
		 * 从它的左右子树分别去找两个节点
		 * 如果找到那么当前节点就是最近父节点
		 * 想不通的可以画图
		 */
		Node leftNode = commanNode(root.left, value1, value2);
		Node rightNode = commanNode(root.right, value1, value2);
		
		//如果在左右子树种分别找到就返回当前节点
		if(leftNode!=null&&rightNode!=null){
			return root;
		}
		/**
		 * 如果只有在左边找到这个节点 那么返回
		 * 因为在右边没找到所以另外那个顶点一定是这个节点的子节点
		 * 画个图就能看懂
		 */
		
		else if(leftNode!=null){
			return leftNode;
		}
		/**
		 * 如果只有在右边找到这个节点 那么返回
		 * 因为在左边没找到所以另外那个顶点一定是这个节点的子节点
		 * 画个图就能看懂
		 */
		else if(rightNode!=null){
			return rightNode;
		}
		else return null;
	}
	
	@Test
	public void test(){
		createTree();
		System.out.println(commanNode(root, value1, value2).value);
	}
	
}

 

还有几种情况我会再写了传上来

2
0
分享到:
评论
2 楼 gengu 2011-11-08  
秦时明月黑 写道
淘宝笔试就吃树的亏


搜狗笔试遇到了树,我没搞出来,然后回来把大部分可能考到的关于树的都弄了一遍
亡羊补牢,为时未晚,后面的笔试帮了大忙
1 楼 秦时明月黑 2011-11-08  
淘宝笔试就吃树的亏

相关推荐

    二叉排序树相关操作

    这种特性使得在二叉排序树中进行查找、插入和删除操作的时间复杂度可以达到最优的O(logn),在最坏情况下可能退化为链表,此时时间复杂度为O(n)。 1. **插入操作**:`InsertBST` 函数实现了在二叉排序树中插入一个新...

    数据结构有关树的操作

    本章主要探讨了树和二叉树的基本概念、操作、性质、存储结构以及它们之间的转换。 首先,树是一种具有层次关系的有限集合,由一个称为根节点的节点开始,其下可以有零个或多个子树。当集合为空时,我们称之为空树,...

    树操作基于c语言

    本项目聚焦于使用C语言实现树的操作,这将帮助我们深入理解C语言的底层机制以及树数据结构的原理。 首先,让我们了解一下树的基本概念。树是由节点(或称为顶点)和边构成的图形数据结构,每个节点可以有零个或多...

    《数据结构》树的相关操作

    基于C语言的树的相关操作:新建、插入、删除、函数递归及非递归的遍历、层遍历

    数据结构课程设计-二叉排序树操作演示系统-C代码&说明文档

    "二叉排序树相关操作演示程序"则是实际的C语言代码实现,通过编译运行这个程序,可以直观地体验二叉排序树的各种操作。 总的来说,这个项目为学习和理解二叉排序树提供了实践平台,有助于深入掌握数据结构的核心...

    《数据结构课程设计》二叉排序树基本操作实验程序

    在实现这些操作时,`file1.cpp`和`file2.cpp`可能分别包含了不同的算法实现或测试用例,而`head.h`可能包含了相关的函数声明和数据结构定义。通过阅读和理解这些代码,你可以深入理解二叉排序树的操作,并提升你的...

    ext2.0 树的增删改操作

    以上就是关于"ext2.0 树的增删改操作"及其相关知识的详细说明。掌握这些内容,将有助于你在构建Web应用时更熟练地使用树形控件,并且能够根据需求进行定制化开发。同时,了解下拉树的实现,可以使你的界面更加友好,...

    倾情奉献:二叉排序树相关操作(绝对无错)

    RT,二叉排序树的建立 && 二叉排序树的遍历 && 求树深 绝对受用

    树形控件操作

    本篇将深入探讨“树形控件操作”,特别是如何实现拖放(Drag and Drop)功能。 树形控件的操作主要包括以下几个方面: 1. **创建与初始化**:首先,我们需要在程序中创建一个树形控件。这可以通过编程语言中的特定...

    二叉排序树基本操作

    二叉排序树的基本操作,创建、插入数据、删除数据、中序遍历、销毁

    B树的基本操作

    B树的实现与基本操作,包括添加和删除有关节点等

    树的操作相关代码

    树的操作相关代码

    从设备树构建kernel驱动platform_device的流程.pdf

    最后,本文档提供了在U-Boot和Linux内核环境中设备树相关操作的详细说明,这包括如何在内核启动时传递dtb地址、如何编写和编译设备树源文件以及如何将设备树与内核镜像合为一体。理解这些知识点对于在Linux驱动开发...

    树形控件操作 地方 地方

    在本篇中,我们将深入探讨树形控件的操作和应用。 首先,理解树形控件的基本概念至关重要。它由节点(TreeNode)组成,每个节点可以有零个或多个子节点,形成一棵多级的“树”。根节点位于顶部,没有父节点,而叶子...

    Huffman树编码解码

    【描述】中提到的队列和栈的存储结构,其实是实现霍夫曼树相关操作的数据结构。队列用于管理待处理的节点,因为队列先进先出(FIFO)的特性适合于管理按权值排序的节点。栈的链式存储结构则可能用于处理递归调用或...

    Tree_数据结构二叉树和树的相关操作_

    在本主题中,我们将深入探讨“树_数据结构二叉树和树的相关操作_”所涵盖的知识点。 首先,我们要了解什么是树。树是一种非线性的数据结构,它由一组节点(或称为顶点)和连接这些节点的边组成。每个节点可以有零个...

    赫夫曼树文件操作

    下面将详细介绍赫夫曼树及其相关的文件操作。 **赫夫曼树基础** 赫夫曼树,又称最优二叉树或最小带权路径长度树,是一种带权路径长度最短的二叉树。它的构造过程基于贪心策略,通过不断合并权重最小的两个节点来...

    树的基本操作,哈夫曼树,哈弗曼码

    本程序是有关树的基本操作如:遍历,求叶子节点,深度等等,这是作为初学者我自己调试的C++代码,里面有注释,简单易懂,希望对你们有帮助!

    数据结构中树和图的操作实验报告

    总之,这个实验报告深入探讨了数据结构中树和图的基本概念、操作和应用,包括二叉树的遍历策略和图的存储结构,以及图的m着色问题,这些都是理解和解决复杂算法问题的基础。通过实验,学生能够更好地掌握这些概念,...

Global site tag (gtag.js) - Google Analytics