`
阅读更多
树: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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics