二叉树(java)

一。用JAVA写二叉树

public class BinaryTree {
	
	Node root;
	
	//得到树的深度
	public Integer getHeight(){
		return getHeight(root);
	}

	private Integer getHeight(Node node){
		if(node==null)
			return 0;
		else{
			int left=getHeight(node.getLeftChildTree());
			int right=getHeight(node.getRightChildTree());
			return left>right?left+1:right+1;//左子树 右子树最深的,再加上父节点本身深度1
		}
	} 
	
	//得到节点数量
	public Integer getSize(){
		return getSize(root);
	};
	
	private Integer getSize(Node node){
		if(node==null)
			return 0;
		else{
			int leftSize=getSize(node.getLeftChildTree());
			int rightSize=getSize(node.getRightChildTree());
			return leftSize+rightSize+1;
		}
	}
	
	//前序遍历,迭代
	public void preOrder(Node node){
		if(node==null)
			return;
		else{
			System.out.println("preOrder"+node.getData());
			preOrder(node.getLeftChildTree());
			preOrder(node.getRightChildTree());
		}
	}	
	
	//中序遍历,迭代
	public void midOrder(Node node){
		if(node==null)
			return;
		else{
			midOrder(node.getLeftChildTree());
			System.out.println("midOrder"+node.getData());
			midOrder(node.getRightChildTree());
		}
	}
	
	//后序遍历,迭代
	public void proOrder(Node node){
		if(node==null)
			return;
		else{
			proOrder(node.getLeftChildTree());
			proOrder(node.getRightChildTree());
			System.out.println("proOrder"+node.getData());
		}
	}
	
	//前序遍历,非迭代,利用栈,要遍历一个节点,就先把它压入,再弹出,输出数据,把此节点的右节点压入,再把左节点压入
	public void nonRecOrder(Node node){
		if(node==null)
			return;
		Stack<Node>stack=new Stack<>();
		stack.push(root);
		while(!stack.isEmpty()){
			Node pop = stack.pop();
			System.out.println("nonRecOrder:"+pop.getData());
			if(pop.getRightChildTree()!=null)//不要把空节点push栈
				stack.push(pop.getRightChildTree());
			if(pop.getLeftChildTree()!=null)
				stack.push(pop.getLeftChildTree());
		}
	}
	
	/**
	 * 			A
	 * 		B		C
	 *     D		E		F
	 */
	public BinaryTree(){
		root=new Node("A");
		Node nodeB=new Node("B");
		Node nodeC=new Node("C");
		Node nodeD=new Node("D");
		Node nodeE=new Node("E");
		Node nodeF=new Node("F");
		nodeB.setLeftChildTree(nodeD);
		nodeB.setRightChildTree(nodeE);
		nodeC.setRightChildTree(nodeF);
		root.setLeftChildTree(nodeB);
		root.setRightChildTree(nodeC);
	}
	
	public class Node<T>{
		private Integer index;
		private Node leftChildTree;
		private Node rightChildTree;
		private T data;
		
		public Integer getIndex() {
			return index;
		}

		public void setIndex(Integer index) {
			this.index = index;
		}

		public Node getLeftChildTree() {
			return leftChildTree;
		}

		public void setLeftChildTree(Node leftChildTree) {
			this.leftChildTree = leftChildTree;
		}

		public Node getRightChildTree() {
			return rightChildTree;
		}

		public void setRightChildTree(Node rightChildTree) {
			this.rightChildTree = rightChildTree;
		}

		public T getData() {
			return data;
		}

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

		public Node(T data){
			this.data=data;
			leftChildTree=null;
			rightChildTree=null;
		}
	}
	
	public static void main(String[] args) {
		BinaryTree tree=new BinaryTree();
		System.out.println("treeHeight"+tree.getHeight());
		System.out.println("treeSize"+tree.getSize());
		tree.preOrder(tree.root);
		tree.midOrder(tree.root);
		tree.proOrder(tree.root);
		tree.nonRecOrder(tree.root);
	}
}

二。建立二叉树

用前序遍历反向生成二叉树

/**
	 *				A
	 *			B		C
	 *		D		#        E
	 * 	#      #        #       F
	 * 
	 * ABD###CE#F  用队列
	 */
	public void creatBinaryTree(LinkedList<String> data){
		creatBinaryTree(0,data);
	}
	
	private Node creatBinaryTree(int index,LinkedList<String> data){
		if(data.isEmpty()){return null;}
		String d = data.pop();
		Node node=new Node<String>(d);
		if(d==null){
			return null;
		}
		if(index==0){
			root=node;
		}
		if(d.equals("#")){
			return null;
		}
		node.leftChildTree=creatBinaryTree(++index,data);
		node.rightChildTree=creatBinaryTree(++index,data);
		return node;
	}

public static void main(String[] args) {
		BinaryTree tree=new BinaryTree();
		LinkedList l=new LinkedList();
		String []data=new String[]{"A","B","D","#","#","#","C","E","#","F"};
		for(String d:data){
			l.offer(d);
		}
		tree.creatBinaryTree(l);
		tree.preOrder(tree.root);
	}

三。树、森林、二叉树的转换

1树转换为二叉树


2森林转化为二叉树


3二叉树转换为树



4二叉树转换为森林



四。赫夫曼树用于数据压缩


1赫夫曼树





带权的节点:比例40的是70-90分的人,判断1个人的分数要走一遍路径,判断40个人路径长就得乘40

2赫夫曼树的构造



3赫夫曼编码

五。遍历树中元素,put新元素

之前数据是泛型,现在用Integer,方便对比。

数据比父节点数据小的放在左子树,数据比父节点数据大的放右子树,树中的数据按此排序的,则查询节省效率,类似二分法

/**
	 * 					30
	 * 			20				40
	 * 		10		25		35		50
	 * @param data
	 * @return
	 */

	public class Node<T>{
		private Integer index;
		private Node<T> leftChildTree;
		private Node<T> rightChildTree;
		private Node<T> parent;  //父节点
		private T data;
		}
	private Node<Integer>put(Integer data){
		if (data==null)
			return null;
		Node<Integer> node=new Node<Integer>(data);
		if(root==null){
			root=node;
			return node;
		}
		node = root;
		Node <Integer> parent=null;
		while(node!=null){
			parent=node;
			if(node.data>data){
				node=node.leftChildTree;
			}
			else if(node.data<data){
				node=node.rightChildTree;
			}else{
				return node;
			}
		}
		node=new Node<Integer>(data);
		node.parent=parent;
		if(parent.data>data){
			parent.leftChildTree=node;
		}else{
			parent.rightChildTree=node;
		}
		return node;
	}

六。遍历通过数据找到节点、删除节点

	public Node getNodeByData(Integer data){
		if(data==null||root==null)
			return null;
		Node <Integer>node=root;
		while (node!=null){
			//System.out.println(node.data);
			if(node.getData().equals(data)){
				return node;
			}else if(node.data>data){
				node=node.leftChildTree;
			}else{
				node=node.rightChildTree;
			}
		}
		return null;
	}

得到某个数据节点下的树

	public void anyPreOrder(Integer data){
		Node nodeByData = getNodeByData(data);
		preOrder(nodeByData);
	}

删除某节点

	public Integer delete(Integer data){
		Node node = getNodeByData(data);
		if(node==null){
			return null;
		}
		List<Integer>list=new ArrayList<>();
		Node parent=node.parent;
		if(parent.leftChildTree==node){//要删除节点的父节点 关系中断
			parent.leftChildTree=null;
		}else{
			parent.rightChildTree=null;
		}
		getDataPreOrder(list, node);
		list.remove(data);
		for(Integer i:list){    //把数据重新放一次
			put(i);
		}
		return data;
	}
	
	//找到某节点下的所有数据放在list,旧节点属性置空
	private void getDataPreOrder(List list,Node node){
		if (node==null)
			return;
		node.parent=null;
		list.add(node.getData());
		getDataPreOrder(list, node.leftChildTree);
		node.leftChildTree=null;
		getDataPreOrder(list, node.rightChildTree);
		node.rightChildTree=null;
		node.data=null;
	}


猜你喜欢

转载自blog.csdn.net/u014203449/article/details/80297137