zoukankan      html  css  js  c++  java
  • DSA——二叉树笔记

    几个总忘的点儿:

    结点的深度:一个结点向上移动到其父节点——是一步,再移动到父结点的父结点——是两步,移动到了根结点——结点的深度

    树的深度:所有叶子结点的最大深度

    数组存储完全二叉树:某个Node在数组中的位置为[i],其父结点则是在[(i-1)/2],其两个孩子则是[2i+1],[2i+2]

    树的遍历:前中后广

    前序遍历-递归【根左右】

    protected void preOder(BinTreeNode root)
    {
    		if(root!=null)
    			visit();//①
    	preOrder(root.left);    //②
            preOrder(root.right);   //③
    }
    

      

    中序遍历-递归【左根右】②①③

    后序遍历-递归【左右根】②③① 

    //很显然,重头戏是 非递归------使用栈帮忙【使得效率并没有改进多少,在使用栈的过程中每次while都需要push,pop分别两次】

    前序遍历-非递归_1

    【visit()必须在pop()后,pop()必须在两次push()前面,显然,visit()和两次push()的先后关系没什么必要】

    【记得,访问必须在子女压栈之前】

    1. 维护一个栈,将根节点入栈,然后只要栈不为空,出栈并访问,接着依次将访问节点的右节点、左节点入栈。 
    2.  这种方式应该是对先序遍历的一种特殊实现(看上去简单明了),但是不具备很好的扩展性,在中序和后序方式中不适用 
    public void iterativePreOrder_1(BinTreeNode root)
    	{
    		BinTreeNode p=root;
    		Stack<BinTreeNode> stack=new Stack<BinTreeNode>();
    		if(p!=null)
    		{
    			stack.push(p);
    			while(!stack.isEmpty())
    			{
    				p=stack.pop();
    				visitNode(p);
    				if(p.right!=null)
    					stack.push(p.right);
    				if(p.left!=null)
    					stack.push(p.left);//left后于right入栈,为了保持在栈顶先访问
    			}
    		}
    

     前序遍历-非递归_2

    1.  利用栈模拟递归过程实现循环先序遍历二叉树 
    2.      * 这种方式具备扩展性,它模拟递归的过程,将左子树点不断的先访问再压入栈,直到null,然后处理栈顶节点的右子树 
     public void iterativePreOrder_2(BinTreeNode root){  
    	        if(root==null)return;  
    	        Stack<BinTreeNode> s=new Stack<BinTreeNode>();  
    	        while(root!=null||!s.isEmpty()){  
    	            while(root!=null){  
    	                visitNode(p);
    	                s.push(root);//先访问再入栈  
    	                root=root.left;  
    	            }  
    	            root=s.pop();  
    	            root=root.right;//如果是null,出栈并处理右子树  
    	        }  
    	    }  
    

    中序遍历---非递归【思想同前序2】

    	public void iterativeInOrder(BinTreeNode root)
    	{
    		if(root==null)return;
    		BinTreeNode p=root;
    		Stack<BinTreeNode> stack=new Stack<BinTreeNode>();
    		while(!stack.isEmpty()||p!=null)
    		{
    			while(p!=null)
    			{
    	            stack.push(p);
    	            root=root.left;  
    			}
    			p=stack.pop();
    			visitNode(p);
    			p=p.right;
    		}
    	}
    

    后序---非递归【又不一样了,参考数据结构C++】

    建立两个类似指针的 p【p和之前用法一样,都表示当前要访问的结点】和pre 【表示刚刚访问过的结点-用于判断如果当前结点不是刚刚访问过的】

    和之前一样都是不断向左搜索,不断压栈--这点和前序和中序一样。

    找到最左面一个结点以后,先判断当前结点没有右孩子或者右孩子刚刚被访问过

    如果满足条件:就访问自己,访问完要记得设置自己为刚刚访问的,如果栈不为空就把

    否则就先把自己压栈,然后找自己的右子树即可,继续循环

      
    	public void iterativePostOrder(BinTreeNode root)
    	{
    		if(root==null)return;
    		BinTreeNode p=root;
    		BinTreeNode prev=root;//保存上一个刚被访问的结点
    		Stack<BinTreeNode> stack=new Stack<BinTreeNode>();
    		while(p!=null)
    		{
    			for(;p.left!=null;p=p.left)//不断向左搜索,压栈
    				stack.push(p);
    			
    		    while(p!=null&&(p.right==null||p.right==prev))//当前结点没有右孩子或者右孩子刚刚被访问过
        {   
                     visitNode(p);//就访问这个结点
        prev=p;//访问后别忘了置为上一个被访问的结点     if(stack.isEmpty())      return;     p=stack.pop();      }     stack.push(p);//有右孩子的时候,先把自己压栈     p=p.right;//再找自己的右子树 }}

     最后一个--广度优先遍历

    1. /** 
    2.      *  
    3.      * @param root 树根节点 
    4.      * 层序遍历二叉树,用队列实现,先将根节点入队列,只要队列不为空,然后出队列,并访问,接着讲访问节点的左右子树依次入队列 
    5.      */ 
     public static void levelTravel(BinTreeNode root){  
        	 if(root==null)return;  
        	BinTreeNode p=root;
        	Queue<BinTreeNode> queue=new LinkedList<BinTreeNode>(); 
        	queue.add(p);
        	while(!queue.isEmpty())
        	{
        		p=queue.poll();
        		visitNode(p);
        		if(p.left!=null) queue.add(p.left);
        		if(p.right!=null) queue.add(p.right);
        	}	
    }
    

      

        参考博客:http://blog.csdn.net/kerryfish/article/details/24309617

  • 相关阅读:
    Ural 1099 Work Scheduling (一般图的最大匹配:带花树算法)
    HDU 4687 Boke and Tsukkomi (2013.8.20 多校9 1002)(暴力+带花树算法)
    2013 Multi-University Training Contest 9 小结(2013.8.20)
    TeX代码模板(持续更新中)
    POJ 3177 Redundant Paths
    POJ 1904 King's Quest
    hdu 4685 Prince and Princess (2013.8.15 多校8---1010)
    2-SAT模板(修改自LRJ的模板)
    HDU 3622 Bomb Game
    Ubuntu 压缩命令
  • 原文地址:https://www.cnblogs.com/Cherrylalala/p/6536146.html
Copyright © 2011-2022 走看看