数据结构---二叉树

数据结构---二叉树

1、二叉树结构

class Node{
     int value;
     Node left;
     Node right;
     Node(int data){
       this.value=data;
   }
}

2、二叉树遍历

前序遍历--递归方式
public void preOrderRecur(Node head){
		if(head==null) return;
		System.out.println(head.value+" ");
		preOrderRecur(head.left);
		preOrderRecur(head.right);
	} 

非递归方式:申请一个栈,先把头结点压入栈中,然后弹出,再把该节点的右子树压入栈中,再把左子树压入栈中,依次循环上述操作。
public static void preOrderRecur(Node head){
		Stack stack= new Stack();
		if(head==null) return;
		stack.push(head);
		Node node;
		while(!stack.isEmpty()){
			node=(Node) stack.pop();
			System.out.println(node.value);
			if(node.right != null) stack.push(node.right);
			if(node.left != null) stack.push(node.left);
		}
		
	}


中序遍历--递归方式

public void inOrderRecur(Node head){
<span style="white-space:pre">		</span>if(head==null) return;
<span style="white-space:pre">		</span>inOrderRecur1(head.left);
<span style="white-space:pre">		</span>System.out.println(head.value);
<span style="white-space:pre">		</span>inOrderRecur1(head.right);
<span style="white-space:pre">	</span>}
非递归方式:

1、申请一个栈,记为stack,申请一个变量为curr,初始时令cur等于头结点

2、先把cur压入栈中,对以cur节点为头结点的整棵子树来说,依次把整棵树的左边界压入栈中,即不断令cur=cur.left,然后重复步骤2

3、不断重复步骤2,直到发现cur为空,此时从stack中弹出一个节点,记为node,打印node的值,并让cur=node.right,将其压入栈中,继续重复步骤2

4、当stack为空并且cur为空时,整个过程结束。

public static void inOrderRecur(Node head){
		Stack<Node> stack =new Stack<Node>();
		if(head==null) return;
		Node curr = head;
		stack.push(curr);
		while (!stack.isEmpty()|| curr !=null) {
			while(curr.left!=null){
				stack.push(curr.left);
				curr=curr.left;	
			}
			if(!stack.isEmpty()){
				Node node=stack.pop();
				System.out.println(node.value);
				if(node.right !=null){
				curr = node.right;
				stack.push(curr);
				}
			}
		}
		
	}

后序遍历--递归方式

public void afterOrderRecur1(Node head){
		if(head==null) return;
		<span style="font-family: Arial, Helvetica, sans-serif;">afterOrderRecur1</span><span style="font-family: Arial, Helvetica, sans-serif;">(head.left);</span>
		<span style="font-family: Arial, Helvetica, sans-serif;">afterOrderRecur1</span><span style="font-family: Arial, Helvetica, sans-serif;">(head.right);</span>
		System.out.println(head.value+" ");
	}

非递归形式:

申请两个栈

1、申请一个栈记为S1,将数的头结点压入到S1中

2、从S1中弹出一个节点记为cur,然后将其右子节点压入到S1中,再将其左子树节点压入到S1中

3、在整个过程中,从S1中弹出的节点均放入到S2中

4、不断重复步骤2和步骤三

5、从S2中依次弹出并打印。


public static void afterOrderRecur(Node head){
		if(head==null) return;
		Stack<Node> s1= new Stack<Node>();
		Stack<Node> s2= new Stack<Node>();
		
		s1.push(head);
		while(!s1.isEmpty()){
			Node cur=s1.pop();
			s2.push(cur);
			if(cur.left!=null)s1.push(cur.left);
			if(cur.right!=null)s1.push(cur.right);		
		}
		while(!s2.isEmpty()){
			System.out.println(s2.pop().value);
		}
	}

不管是递归方式还是非递归方法,遍历整棵树的时间复杂度都是O(N),N为二叉树的节点树,额外空间复杂度为O(L),L为二叉树的层数


判断平衡二叉树:通过后序遍历来实现,首先判断左子树是不是平衡二叉树,再判断右子树是不是平衡二叉树

public static  boolean isBalance(Node head){
		boolean[] res = new boolean[1];
		res[0]=true;
		getHeight(head,1,res);
		return res[0];
	}



	private static int getHeight(Node head, int level,boolean[] res) {
		if(head==null){
			return level;
		}
		int lH = getHeight(head.left,level + 1,res);
		if(!res[0]){
			return level;
		}
		int rH=getHeight(head.right, level+1, res);
		if(!res[0]){
			return level;
		}
		if(Math.abs(lH-rH)>1){
			res[0]=false;
		}
		return Math.max(lH,rH);	
	}

搜索二叉树   :每棵树的头结点都比各自左子树上的所有节点值要大,也都比各自右子树上的所有节点值要小。按中序遍历得到的顺序是从小到大的。

判断是否是搜索二叉树:


满二叉树:除了最后一层的节点无任何子节点外,剩下每一层上的节点都有两个子节点。  满二叉树的层数为L,节点数为N,则N=2^L-1


完全二叉树:除最后一层外,其他每一层的节点数都是满的。最后一层如果不满,缺少的节点也全部的集中在右边,那也是一颗完全二叉树。

判断完全二叉树:

1、采用按层遍历二叉树的方式,从每层的左边向右边依次遍历所有的节点

2、如果当前节点有右孩子,但没有左孩子,直接返回false

3、如果当前节点并不是左右孩子全有,那之后的节点必须都为叶子节点,否则返回false

4、遍历过程中不反回false,遍历结束后返回true即可

后继节点:一个节点的后继节点,是指这个节点在中序遍历中的下一个节点

前驱节点:这个节点在中序遍历中的上一个节点。


 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值