java树状结构之二叉树

参考:http://blog.youkuaiyun.com/zhangerqing/article/details/8822476

前面已经提到过树和二叉树的相关概念内容,下面主要来介绍下关于二叉树的创建,遍历,查找等相关内容。在此之间先说一个概念,广义表

一、广义表

广义表是一种非线性的数据结构,广义表是n个数据元素d1,d2,d3,…,dn的有限序列,但线性表不同的是,广义表中的di 则既可以是单个元素,还可以是一个广义表,通

常记作:GL=(d1,d2,d3,…,dn)。GL是广义表的名字,通常广义表的名字用大写字母表示。n是广义表的长度。若其中di是一个广义表,则称di是广义表GL的子表。在

广义表GL中,d1是广义表GL的表头,而广义表GL其余部分组成的表(d2,d3,…,dn)称为广义表的表尾。由此可见广义表的定义是递归定义的。

二、创建二叉树

采用广义表的方式创建二叉树。创建的二叉树结构如下:

1 定义Node节点

public class Node {

	private char data;
	private Node lchild;
	private Node rchild;

	public Node(){
		
	}
	public char getData() {
		return data;
	}

	public void setData(char data) {
		this.data = data;
	}

	public Node getRchild() {
		return rchild;
	}

	public void setRchild(Node rchild) {
		this.rchild = rchild;
	}

	public Node getLchild() {
		return lchild;
	}

	public void setLchild(Node lchild) {
		this.lchild = lchild;
	}

	public Node(char ch, Node rchild, Node lchild) {
		this.data = ch;
		this.rchild = rchild;
		this.lchild = lchild;
	}

	public String toString() {
		return "" + getData();
	}
}
2. 二叉树创建类

Node createTree(String express, char split){
		String[] array = StringUtils.split(express, split);
		int length = array.length-1;
		int capicity = (1<<(length-1))-1;
		Node[] nodes = new Node[capicity];
		Node head =null;
		Node p = null;
		int level = -1;
		int childType = 0;
		int index =0;
		char data;
		char[] charArray = express.toCharArray();
		while(index < charArray.length-1){
			data = charArray[index];
			switch(data){
				case '(': 
					level++;
					childType = 1;
					nodes[level]=p;
					break;
				case ',':
					childType = 2;
					break;
				case ')':
					level--;
					break;
				default:
					p = new Node(data, null, null);
					if(head == null){
						head = p;
						break;
					}else{
						switch(childType){
							case 1: nodes[level].setLchild(p);break;
							case 2: nodes[level].setRchild(p);break;
						}
					}
			}
			data = charArray[++index];
		}
		return head;
	}

三、二叉树的遍历

1. 先序遍历

此种遍历模式是先读取父节点,然后再读取左右节点。

1.1 递归先序遍历

        /**
	 * 递归先序遍历
	 * @param node
	 */
	public void preTraversal(Node node){
		if(null == node){
			return;
		}else{
			System.out.print(node.getData()+" ");
			preTraversal(node.getLchild());
			preTraversal(node.getRchild());
		}
	}

1.2 非递归先序遍历

        /**
	 * 非递归先序遍历
	 * @param node
	 */
	public void preTraversalNoRecursive(Node node){
		if(null == node){
			return;
		}
		Node p = null;
		int level=0;
		Node[] stack = new Node[1024];
		stack[0] = node;//先将树根节点压入栈中
		while(level > -1){
			p = stack[level];
			level--;//移除栈的顶层节点
			System.out.print(p.getData()+" ");
			if(null != p.getRchild()){//如果树右子节点不为null,则压入栈中
				stack[++level] = p.getRchild();
			}
			if(null != p.getLchild()){//如果树左子节点不为Null,则压入栈中
				stack[++level] = p.getLchild();
			}
		}
	}

2. 中序遍历

此种遍历模式是先读取左子节点,然后读取节点,最后读取右节点

        2.1  递归中序遍历

<span style="white-space:pre">	</span>/**
	 * 递归中序遍历 
	 * @param node
	 */
	public void midTraversal(Node node){
		if(null == node){
			return;
		}else{
			midTraversal(node.getLchild());
			System.out.print(node.getData()+" ");
			midTraversal(node.getRchild());
		}
	}

2.2 非递归中序遍历

/**
	 * 非递归中序遍历
	 * @param node
	 */
	public void midTraversalNoRecursive(Node node){
		if(null == node){
			return;
		}
		int level = -1;
		Node[] stack = new Node[1024];
		Node p = node;
		while(p != null || level > -1){//节点不为null或则当前层数不为-1
			while(p != null){
				stack[++level] = p;//将p压入栈
				p = p.getLchild();//获取p的左子结点
			}
			if(level > -1){
				p = stack[level];//获取栈顶层节点
				level--;
				System.out.print(p.getData()+" ");
				p = p.getRchild();//读取为最下方的左子节点,接着访问该节点的右子节点
			}
		}
	}

3. 后序遍历

此种遍历模式是先读取左右节点,然后再读取父节点

3.1 递归后序遍历

<span style="white-space:pre">	</span>/**
	 * 递归后序遍历 
	 * @param node
	 */
	public void lastTraversal(Node node){
		if(null == node){
			return;
		}else{
			lastTraversal(node.getLchild());
			lastTraversal(node.getRchild());
			System.out.print(node.getData()+" ");
		}
	}
4. 二叉树的深度遍历

待补充

5. 二叉树的广度遍历

待补充

$(function(){ $.fn.extend({ SimpleTree:function(options){ //初始化参数 var option = $.extend({ click:function(a){ } },options); option.tree=this; /* 在参数对象中添加对当前菜单树的引用,以便在对象中使用该菜单树 */ option._init=function(){ /* * 初始化菜单展开状态,以及分叉节点的样式 */ this.tree.find("ul ul").hide(); /* 隐藏所有子级菜单 */ this.tree.find("ul ul").prev("li").removeClass("open"); /* 移除所有子级菜单父节点的 open 样式 */ this.tree.find("ul ul[show='true']").show(); /* 显示 show 属性为 true 的子级菜单 */ this.tree.find("ul ul[show='true']").prev("li").addClass("open"); /* 添加 show 属性为 true 的子级菜单父节点的 open 样式 */ }/* option._init() End */ /* 设置所有超链接不响应单击事件 */ this.find("a").click(function(){ $(this).parent("li").click(); return false; }); /* 菜单项 接受单击 */ this.find("li").click(function(){ /* * 当单击菜单项 * 1.触发用户自定义的单击事件,将该 标签中的第一个超链接做为参数传递过去 * 2.修改当前菜单项所属的子菜单的显示状态(如果等于 true 将其设置为 false,否则将其设置为 true) * 3.重新初始化菜单 */ option.click($(this).find("a")[0]); /* 触发单击 */ /* * 如果当前节点下面包含子菜单,并且其 show 属性的值为 true,则修改其 show 属性为 false * 否则修改其 show 属性为 true */ /* if($(this).next("ul").attr("show")=="true"){ $(this).next("ul").attr("show","false"); }else{ $(this).next("ul").attr("show","true"); }*/ /* 初始化菜单 */ option._init(); }); /* 设置所有父节点样式 */ this.find("ul").prev("li").addClass("folder"); /* 设置节点“是否包含子节点”属性 */ this.find("li").find("a").attr("hasChild",false); this.find("ul").prev("li").find("a").attr("hasChild",true); /* 初始化菜单 */ option._init(); }/* SimpleTree Function End */ }); });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值