`
阅读更多
树:n个节点的有限集

在非空树中,有且仅有一个根节点(Root

N>1时,其余节点分为m个互不相交的有限集,T1T2… Tm.


节点的度:节点拥有的子树

叶子节点:度为0的节点(没有子节点)

分支节点:度不为0的节点(还有子节点)

树的度:树内各个节点的度的最大值(有的节点度为0,1,2,3

那么树的度应该为3

孩子:节点子树的根

兄弟:同一父亲的孩子

堂兄弟:双亲在同一层次的节点的那些节点,比如EF和和HIJ

祖先:从根到该节点所经分支的所有节点

子孙:以某节点为根的子树的任意一节点

深度:树中节点的最大层次即有几层

有序树:树的各个节点的各个子树都看成是有序的

 


二叉树:每一个节点最多有两个子树即度<=2,子树有左右之分

 

 

满二叉树和完全二叉树的区别:

满二叉树:深度为k且有2^k-1个节点的二叉树,也就是说二叉树要平衡,而且子节点都有左右节点(叶子节点除外)
 

完全二叉树:首先必须有叶子节点,叶子节点的顺序是从左往右的,可以没有右孩子,但是不能没有左孩子,否则就不是完全二叉树

如果前一个节点都不存在左右节点,而后边存在左节点或者有节点,或者某一个节点存在右节点,但是没有左节点都不是完全二叉树


性质:

  • 完全二叉树的节点数如果为n那么,深度是+1;
  • 对于每一个完全二叉树的节点x,如果x=1,就是根节点,否则这个节点父节点为x/2;
  • 如果节点x*2>节点个数(n),那么表示没有左孩子结点,比如7*2>12表示7这个节点没有左孩子
  • 如果x*2+1 > 表示没有右孩子节点6*2+1>12,表示没有右孩子节点

二叉树的存储结构:

顺序存储结构:

将完全二叉树上编号为I的节点元素存储在一维数组下标为(i-1)上。

即(2i)一定是左节点,2i+1一定是右节点

 

链式存储结构:

为了避免空间的浪费,可以采用链式存储结构,因为非完全二叉树很有可能有很多地方都没有子节点,如果空着的话,空间就浪费了

 


遍历二叉树和线索二叉树

先序遍历:

访问根节点,先序遍历左子树,先序遍历右子树

中序遍历:

中序遍历左子树,访问根节点,中序遍历右子树

后续遍历

后续遍历左子树,后续遍历右子树,访问根节点  

其实就是看访问跟节点的先后顺序。

 

package com.dataStructure.tree;

import java.util.Stack;

public class TreeBean {
	private String nodeName;
	private TreeBean leftChild;
	private TreeBean rightChild;
	
	public TreeBean() {

	}
	
	public TreeBean(String nodeName, TreeBean leftChild, TreeBean rightChild) {
		this.nodeName = nodeName;
		this.leftChild = leftChild;
		this.rightChild = rightChild;
	}
	
	protected TreeBean initTree(){
		TreeBean leafNode1 = new TreeBean();
		leafNode1.setNodeName("D");
		TreeBean leafNode2 = new TreeBean();
		leafNode2.setNodeName("E");
		TreeBean leafNode3 = new TreeBean();
		leafNode3.setNodeName("F");
		TreeBean leafNode4 = new TreeBean();
		leafNode4.setNodeName("G");
		TreeBean brachNode1 = new TreeBean();
		brachNode1.setNodeName("B");
		brachNode1.setLeftChild(leafNode1);
		brachNode1.setRightChild(leafNode2);
		TreeBean brachNode2 = new TreeBean();
		brachNode2.setNodeName("C");
		brachNode2.setLeftChild(leafNode3);
		brachNode2.setRightChild(leafNode4);
		TreeBean rootNode = new TreeBean();
		rootNode.setNodeName("A");
		rootNode.setLeftChild(brachNode1);
		rootNode.setRightChild(brachNode2);
		
		return rootNode;
	}
	
	protected void visit(TreeBean node){
		System.out.print(node.getNodeName());
	}
	/**
	 * 前序排列的算法
	 * @param node
	 */
	protected void preOrderTraversal(TreeBean node){
		if(node == null ){
			return;
		}
		visit(node);//遍历root

		preOrderTraversal(node.getLeftChild());//遍历左节点
		preOrderTraversal(node.getRightChild());//遍历右节点
	}

	/**
	 * 中序遍历的算法
	 * @param node
	 */
	protected void inOrderTraversal(TreeBean node){
		if(node == null ){
			return;
		}
		inOrderTraversal(node.getLeftChild());//遍历左节点
		visit(node);//遍历root
		inOrderTraversal(node.getRightChild());//遍历右节点
	}

	/**
	 * 后序遍历的算法
	 * @param node
	 */
	protected void postOrderTraversal(TreeBean node){
		if(node == null ){
			return;
		}
		postOrderTraversal(node.getLeftChild());//遍历左节点
		postOrderTraversal(node.getRightChild());//遍历右节点
		visit(node);//遍历root
	}

	/**
	 * 非递归实现先序遍历
	 * @param node
	 */
	protected void preOrderNonRecursive_1(TreeBean node){
		//create a stack
		Stack<TreeBean> stack = new Stack<TreeBean>();
		if(node == null){
			return;
		}
		//先把父节点入栈
		stack.push(node);
		while(!stack.isEmpty()){
			node = stack.pop();//及入及出
			visit(node);
			//先放置右节点,后入先出
			if(node.getRightChild() != null){
				stack.push(node.getRightChild());
			}
			if(node.getLeftChild() != null){
				stack.push(node.getLeftChild());
			}
		}
	}

	/**
	 * 非遞歸先序遍历
	 * @param node
	 */
	protected void preOrderNonRecursive_2(TreeBean node){
		//create a stack
		Stack<TreeBean> stack = new Stack<TreeBean>();
		if(node == null){
			return;
		}
		TreeBean bean = node;
		
		while(bean != null || stack.size() > 0){
			//所有左节点入栈
			while(bean != null ){
				visit(bean);
				stack.push(bean);
				bean = bean.getLeftChild();
			}
			//画图一目了然
			if(stack.size() > 0){
				bean = stack.pop();
				bean = bean.getRightChild();
			}
		}
	}

	/**
	 * 非递归后序遍历双栈法
	 * @param node
	 */
	protected void postOrderNonRecursive_doubleStack(TreeBean node){
		Stack<TreeBean> stack = new Stack<TreeBean>();
		Stack<TreeBean> tmpStack = new Stack<TreeBean>();
		TreeBean bean = node;
		
		while (bean != null || stack.size() > 0) {
			while (bean != null) {
				tmpStack.push(bean);
				stack.push(bean);
				bean = bean.getRightChild();
			}
			if (stack.size() > 0) {
				bean = stack.pop();
				bean = bean.getLeftChild();
			}
		}
		while (tmpStack.size() > 0) {
			bean = tmpStack.pop();
			visit(bean);
		}
	}

	/**
	 * 非递归后序遍历单栈法
	 * @param node
	 */
	protected void postOrderNonRecursive_singleStack(TreeBean node) {
		Stack<TreeBean> stack = new Stack<TreeBean>();
		TreeBean bean = node, prev = node;
		while (bean != null || stack.size() > 0) {
			while (bean != null) {
				stack.push(bean);
				bean = bean.getLeftChild();
			}
			if (stack.size() > 0) {
				TreeBean temp = stack.peek().getRightChild();
				if (temp == null || temp == prev) {
					bean = stack.pop();
					visit(bean);
					prev = bean;
					bean = null;
				} else {
					bean = temp;
				}
			}

		}
	}

	/**
	 * 非递归中序遍历
	 * @param node
	 */
	protected void iterativeInorder2(TreeBean bean) {
		Stack<TreeBean> stack = new Stack<TreeBean>();
		TreeBean node = bean;
		while (node != null || stack.size() > 0) {
			while (node != null) {
				stack.push(node);
				node = node.getLeftChild();
			}
			if (stack.size() > 0) {
				node = stack.pop();
				visit(node);
				node = node.getRightChild();
			}
		}
	}
	
	/**
	 * 层次遍历(广度优先遍历)
	 * @param root
	 */
	protected void levelOrder(TreeBean root){
		if(root == null){
			return;
		}
		System.out.println("Level:");
		Queue<TreeBean> queue = new LinkedList<TreeBean>();
		TreeBean currentNode = null;
		TreeBean leftChildNode = null;
		TreeBean rightChildNode = null;
		queue.add(root);
		while(!queue.isEmpty()){
			currentNode = queue.poll();//出队列
			
			visit(currentNode);
			leftChildNode = currentNode.getLeftChild();
			rightChildNode = currentNode.getRightChild();
			//左右节点入队列
			if(leftChildNode != null){
				queue.add(leftChildNode);
			}
			if(rightChildNode != null){
				queue.add(rightChildNode);
			}
		}
	}
	public String getNodeName() {
		return nodeName;
	}
	public void setNodeName(String nodeName) {
		this.nodeName = nodeName;
	}
	public TreeBean getLeftChild() {
		return leftChild;
	}
	public void setLeftChild(TreeBean leftChild) {
		this.leftChild = leftChild;
	}
	public TreeBean getRightChild() {
		return rightChild;
	}
	public void setRightChild(TreeBean rightChild) {
		this.rightChild = rightChild;
	}

}

 

 

 

 

  • 大小: 88 KB
分享到:
评论

相关推荐

    数据结构--二叉树--思维导图.pdf

    "数据结构--二叉树--思维导图" 二叉树是一种常见的数据结构,它是一种树形结构,每个节点最多有两个孩子节点,分别是左子树和右子树。二叉树可以用来存储大量数据,并且可以快速地查找、插入和删除数据。 二叉树的...

    数据结构-二叉树建立

    数据结构-二叉树的建立先序中序后序层次遍历

    数据结构-二叉树相关功能及算法

    二叉树是数据结构中的重要概念,它是一种特殊的树形数据结构,每个节点最多有两个子节点,通常称为左子节点和右子节点。在计算机科学中,二叉树的应用广泛,涉及搜索、排序、编译器设计等多个领域。本主题将深入探讨...

    数据结构-二叉树的建立及遍历操作

    数据结构-二叉树的建立及遍历操作

    数据结构-二叉树Java实现及其遍历算法

    数据结构-二叉树Java实现及其遍历算法,代码示例中实现了中序遍历,简单易学。

    数据结构-二叉树汇总

    二叉树是计算机科学中一种重要的数据结构,它在很多领域如计算机图形学、编译原理、数据库系统等都有广泛的应用。在这个“数据结构-二叉树汇总”中,我们将深入探讨二叉树的基本概念、类型、操作以及相关算法。 ...

    数据结构-二叉树算法拓展

    在IT领域,数据结构是计算机科学的基础,而二叉树作为一种重要的数据结构,广泛应用于搜索、排序、图形处理等场景。本主题将深入探讨二叉树的算法拓展,特别是关于交换左右子树、将二叉链表转换为完全二叉树以及寻找...

    数据结构-二叉树的建立与遍历 (2).pdf

    《数据结构-二叉树的建立与遍历》实验报告主要涵盖了如何使用链式存储结构构建二叉树以及非递归方式实现二叉树的先序遍历。实验旨在通过Visual C++6.0上机调试,提升对二叉树理论的理解及实际操作能力。 在实验需求...

    数据结构- 二叉树的定义及基本操作(代码+报告)

    ### 数据结构 - 二叉树的定义及基本操作 #### 实验目的与意义 本实验旨在帮助学生深入了解二叉树这一重要的数据结构,并通过实践掌握其基本操作。具体包括: 1. **熟悉二叉链表表示的二叉树结构及其递归遍历**:...

    Java基础复习笔记08数据结构-二叉树和二叉树的遍历

    ### Java基础复习笔记08数据结构-二叉树和二叉树的遍历 #### 一、二叉树概述 二叉树(Binary Tree)是一种重要的数据结构,在计算机科学中有广泛的应用。二叉树中的每个节点最多有两个子节点,分别称为左子节点和右...

    数据结构-二叉树-C++

    在IT领域,数据结构是计算机科学的基础,而二叉树作为一种重要的数据结构,广泛应用于算法设计、数据库系统、编译器等。本资料主要聚焦于使用C++语言实现二叉树的遍历方法,这对于理解和掌握C++编程以及数据结构至关...

    数据结构-二叉树的创建与遍历方法实现方式.docx

    相关链接 二叉树的基础知识点:数据结构-----树和二叉树的定义与性质_Gretel Tade的博客-CSDN博客堆的相关方法代码实现:数据结构-----堆(完全二叉树)_Gretel Tade的博客-CSDN博客二叉树的链式存储结构 #include...

    数据结构-二叉树 JAVA语言实现

    在IT领域,数据结构是计算机科学的基础,而二叉树作为一种重要的数据结构,被广泛应用于算法设计、数据库系统、编译器等领域。本教程将详细阐述如何使用JAVA语言实现二叉树的相关操作。 首先,我们要了解二叉树的...

    数据结构-二叉树遍历

    二叉树作为一种重要的数据结构,广泛应用于计算机科学的各个领域,如编译器设计、操作系统、数据库、图形学等。它的遍历是理解和操作二叉树的基础,这其中包括前序遍历、中序遍历、后序遍历以及层次遍历(也称为广度...

    数据结构-二叉树及存储结构

    ### 数据结构中的二叉树及存储结构 #### 一、二叉树的定义与形态 **二叉树**是一种常见的数据结构,它是由一个或多个节点组成的集合,这些节点之间存在一种特定的层次关系。根据定义,二叉树可以为空;如果不为空...

Global site tag (gtag.js) - Google Analytics