`

java二叉树算法(转)

阅读更多

原文地址:http://wenku.baidu.com/view/bee988fe910ef12d2af9e769.html

 

一、创建二叉树

 

package tree.bintree;

/**
 * 创建非完全二叉树、完全二叉树、满二叉树 由于二叉树的节点增加没有什么规则,
 * 所以这里只是简单的使用了递次性把整棵树创建出来,而没有设计出一个一个添加节点的方法与删除
 */
public class BinTree {
	protected Entry root;	//根
	private int size;		//树的节点数

	/**
	 * 树的节点结构
	 * @author jzj
	 * @date 2009-12-23
	*/
	protected static class Entry {
	    int elem;  		//数据域,这里我们作为编号
		Entry left;		//左子树
		Entry right;	//右子树
	    public Entry(int elem) {
	        this.elem = elem;
	    }
	    public String toString() {
	        return " number=" + elem;
	    }
	}

	/**
	 * 根据给定的节点数创建一个完全二叉树或是满二叉树
	 * @param nodeCount 要创建节点总数
	 */
	public void createFullBiTree(int nodeCount) {
		root = recurCreateFullBiTree(1,nodeCount);
	}

	/**
	 * 递归创建完全二叉树
	 * @param num 节点编号
	 * @param nodeCount 节点总数
	 * @return TreeNode 返回创建的节点
	 */

	private Entry recurCreateFullBiTree(int num, int nodeCount) {
		size++;
		Entry rootNode = new Entry(num);//根节点
		//如果有左子树则创建左子树
		if (num * 2 <= nodeCount) {
			rootNode.left = recurCreateFullBiTree(num * 2, nodeCount);
			//如果还可以创建右子树,则创建
			if (num * 2 + 1 <= nodeCount) {
				rootNode.right = recurCreateFullBiTree(num * 2 + 1,nodeCount);
			}
		}
		return (Entry) rootNode;
	}


	/**
	 * 根据给定的数组创建一棵树,这个棵树可以是完全二叉树也可是普通二叉树
	 * 数组中为0的表示不创建该位置上的节点
	 * @param nums 数组中指定了要创建的节点的编号,如果为0,表示不创建
	*/
	public void createBinTree(int[] nums) {
		root = recurCreateBinTree(nums, 0);
	}

	/**
	 * 递归创建二叉树
	 * @param nums 数组中指定了要创建的节点的编号,如果为0,表示不创建
	 * @param index 需要使用数组中的哪个元素创建节点,如果为元素为0,则不创建
	 * @return TreeNode 返回创建的节点,最终会返回树的根节点
    */
	private Entry recurCreateBinTree(int[] nums, int index) {
		//指定索引上的编号不为零上才需创建节点
		if (nums[index] !=0) {
			size++;
			Entry rootNode = new Entry(nums[index]);//根节点
			//如果有左子树则创建左子树
			if ((index + 1) * 2 <= nums.length) {
				rootNode.left = (Entry) recurCreateBinTree(nums, (index +1) * 2 - 1);
				//如果还可以创建右子树,则创建
				if ((index + 1) * 2 + 1 <= nums.length) {
					rootNode.right = (Entry) recurCreateBinTree (nums, (index + 1) * 2);
				}
			}
			return (Entry) rootNode;
		}
		return null;
	}


	public int size() {
		return size;
	}


	//取树的最右边的节点
	public int getLast() {
		Entry e = root;
		while (e.right != null) {
			e = e.right;
		}
		return e.elem;
	}

	//测试
	public static void main(String[] args) {
		//创建一个满二叉树
		BinTree binTree = new BinTree();
		binTree.createFullBiTree(15);
		System.out.println(binTree.size());//15
		System.out.println(binTree.getLast());//15

		//创建一个完全二叉树
		binTree = new BinTree();
		binTree.createFullBiTree(14);
		System.out.println(binTree.size());//14
		System.out.println(binTree.getLast());//7

		//创建一棵非完全二叉树
		binTree = new BinTree();
		int[] nums = new int[] {1,2,3,4,0,0,5,0,6,0,0,0,0,7,8};
	    binTree.createBinTree(nums);
	    System.out.println(binTree.size());//8
	    System.out.println(binTree.getLast());//8
	}
}

 

 

二、二叉树的递归遍历

package tree.bintree;

/*
 * 由于二叉树所具有的递归性质,一棵非空的二叉树可以看作是由根节点、左子树和右子树3部分构成,
 * 因为若能依次遍历这3部分的信息,也就遍历了整个二叉树。按照左子树的遍历在右子树的遍历之前进行的约定,
 * 根据访问根节点位置的不同,可以得到二叉的前序、中序、后序3种遍历方法。
 */

/**
 * 二叉树的三种 内部 遍历:前序、中序、后序
 * 但不管是哪种方式,左子树的遍历在右子树的遍历之前遍历是这有三种遍历方式都
 * 必须遵循的约定
 */
public class BinTreeInOrder extends BinTree {
	/**
      * 节点访问者,可根据需要重写visit方法
     */
    static abstract class Visitor {
        void visit(int ele) {
            System.out.print(ele + " ");
        }
    }


    public void preOrder(Visitor v) {
        preOrder(v, root);
    }

    /**
     * 树的前序递归遍历 pre=prefix(前缀)
     * @param node 要遍历的节点
     */
    private void preOrder(Visitor v, Entry node) {
        //如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null
        if (node != null) {
            v.visit(node.elem);		//先遍历父节点
            preOrder(v, node.left);	//再遍历左节点
            preOrder(v, node.right);//最后遍历右节点
        }
    }


    public void inOrder(Visitor v) {
        inOrder(v, root);
    }

    /**
     * 树的中序递归遍历 in=infix(中缀)
     * @param node 要遍历的节点
     */
    private void inOrder(Visitor v, Entry node) {
        //如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null
        if (node != null) {
            inOrder(v, node.left);	//先遍历左节点
            v.visit(node.elem);		//再遍历父节点
            inOrder(v, node.right);	//最后遍历右节点
        }
    }

    public void postOrder(Visitor v) {
        postOrder(v, root);
    }

    /**
     * 树的后序递归遍历 post=postfix(后缀)
     * @param node 要遍历的节点
     */
    private void postOrder(Visitor v, Entry node) {
        //如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null
        if (node != null) {
            postOrder(v, node.left);//先遍历左节点
            postOrder(v, node.right);//再遍历右节点
            v.visit(node.elem);//最后遍历父节点
        }
    }

    //测试
    public static void main(String[] args) {

        //创建二叉树
        int[] nums = new int[] { 1, 2, 3, 4, 0, 0, 5, 0, 6, 0, 0, 0, 0, 7, 8 };
        BinTreeInOrder treeOrder = new BinTreeInOrder();
        treeOrder.createBinTree(nums);
        System.out.print("前序遍历 - ");
        treeOrder.preOrder(new Visitor() {});
        System.out.println();

        System.out.print("中序遍历 - ");
        treeOrder.inOrder(new Visitor() {});
        System.out.println();
        System.out.print("后序遍历 - ");
        treeOrder.postOrder(new Visitor() {});

        /*
         * output:
         * 前序遍历 - 1 2 4 6 3 5 7 8
         * 中序遍历 - 4 6 2 1 3 7 5 8
         * 后序遍历 - 6 4 2 7 8 5 3 1
         */
    }
}

 

三、二叉树的外部遍历

package tree.bintree;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Stack;

/**
 * 二叉树的外部遍历:深度优先(先根)、广度(层次)优先遍历
 *
 * @author jzj
 * @date 2009-12-23
 */
public class BinTreeOutOrder extends BinTree {

    /**
     * 二叉树深序优先遍历(即二叉树的先根遍历)迭代器,外部可以使用该迭代器
     * 进行非递归的遍历,这是一种在二叉树结构外部的一种遍历算法,它没有使用
     * 二叉树本身的结构特点(左右子树递归)进行递归遍历
     * @author jzj
     */
    private class DepthOrderIterator implements Iterator {
        //栈里存放的是每个节点
        private Stack stack = new Stack();

        public DepthOrderIterator(Entry node) {
            //根入栈,但在放入左右子节点前会马上出栈,即根先优于左右子节点访问
            stack.push(node);
        }

        //是否还有下一个元素
        public boolean hasNext() {
            if (stack.isEmpty()) {
                return false;
            }
            return true;
        }

        //取下一个元素
        public Object next() {
            if (hasNext()) {
                //取栈顶元素
                Entry treeNode = (Entry) stack.pop();//先访问根

                if (treeNode.right != null) {
                    stack.push(treeNode.right);//再放入右子节点
                }

                if (treeNode.left != null) {
                    stack.push(treeNode.left);//最后放入左子节点,但访问先于右节点
                }

                // 返回遍历得到的节点
                return treeNode;

            } else {
                // 如果栈为空
                return null;
            }
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }

    }

    /**
     * 向外界提供先根遍历迭代器
     * @return Iterator 返回先根遍历迭代器
     */
    public Iterator createPreOrderItr() {
        return new DepthOrderIterator(root);
    }

    /**
     * 二叉树广度优先遍历迭代器,外部可以使用该迭代器
     * 进行非递归的遍历,这是一种在二叉树结构外部的一种遍历算法,它没有使用
     * 二叉树本身的结构特点(左右子树递归)进行递归遍历
     * @author jzj
     */
    private class LevelOrderIterator implements Iterator {
        //使用队列结构实现层次遍历,队列里存储的为节点
        private LinkedList queue = new LinkedList();
        public LevelOrderIterator(Entry node) {
            if (node != null) {
                //将根入队
                queue.addLast(node);
            }
        }

        //是否还有下一个元素
        public boolean hasNext() {
            if (queue.isEmpty()) {
                return false;
            }
            return true;
        }

        //取下一个元素
        public Object next() {
            if (hasNext()) {
                //取栈顶迭元素
                Entry treeNode = (Entry) queue.removeFirst();

                if (treeNode.left != null) {//如果有左子树,加入有序列表中
                    queue.addLast(treeNode.left);
                }
                if (treeNode.right != null) {//如果有右子树,加入有序列表中
                    queue.addLast(treeNode.right);
                }

                // 返回遍历得到的节点
                return treeNode;

            } else {
                // 如果队列为空
                return null;
            }
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }

    }

    /**
     * 向外界提供广度优先迭代器
     * @return Iterator 返回遍历迭代器
     */
    public Iterator createLayerOrderItr() {
        return new LevelOrderIterator(root);
    }

    public static void main(String[] args) {
        //创建一棵满二叉树
        BinTreeOutOrder treeOrder = new BinTreeOutOrder();
        treeOrder.createFullBiTree(15);
        Iterator preOrderItr = treeOrder.createPreOrderItr();
        System.out.print("深度优先(先根)遍历 - ");
        while (preOrderItr.hasNext()) {
            System.out.print(((Entry) preOrderItr.next()).elem + " ");
        }

        System.out.println();
        System.out.print("广度优先(层次)遍历 - ");
        Iterator layerOrderItr = treeOrder.createLayerOrderItr();
        while (layerOrderItr.hasNext()) {
            System.out.print(((Entry) layerOrderItr.next()).elem + " ");
        }
        /*
         * output:
         * 深度优先(先根)遍历 - 1 2 4 8 9 5 10 11 3 6 12 13 7 14 15
         * 广度优先(层次)遍历 - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
         */
    }
}

 

四、可逆二叉树

package tree.bintree;

/**
 * 可回溯的二叉树
 * 二叉树的非递归遍历
 */
public class BackBinTree {
	// Bin=Binary(二进位的, 二元的)
    protected Entry root;	//根
    private int size;		//树的节点数

    /**
     * 树的节点结构
     * @author jzj
     * @date 2009-12-23
     */
    private static class Entry {
        int elem;		//数据域,这里为了测试,就作为节点编号吧
        Entry paraent;	//父节点
        Entry left;		//左节点
        Entry right;	//右节点

        //构造函数只有两个参数,左右节点是调用add方法时设置
        public Entry(int elem, Entry parent) {
            this.elem = elem;
            this.paraent = parent;
        }
    }

    /**
     * 查找前序遍历(根左右)直接后继节点
     *
     * 以非递归 根左右 的方式遍历树
     *
     * @param e 需要查找哪个节点的直接后继节点
     * @return Entry 前序遍历直接后继节点
     */
    public Entry preOrderSuccessor(Entry e) {
        if (e == null) {
            return null;
        }else if (e.left != null) {
        	//如果左子树不为空,则直接后继为左子节点
        	//先看左子节点是否为空
        	//如果不为空,则直接后继为左子节点
            return e.left;
        }else if (e.right != null) {
        	//否则如果右子树不为空,则直接后继为右子节点
        	//如果左子节点为空,则看右子节点是否为空
        	//如果右子节点不为空,则返回
            return e.right;
        }else {
        	//左右子节点都为空的情况下
            Entry s = e.paraent;
            Entry c = e;

            /*
            * 一直向上,直到c是s的左子树,且s的右子树不为空。请试着找一下36与68节点的
            * 直接后继节点,36的应该是75,而68则没有后继节点了
            *
            *                            50
            *                            /\
            *                          37  75
            *                         /    /
            *                       25    61
            *                      /\     /\
            *                    15 30   55 68
            *                       /\    \
            *                     28 32   59
            *                         \
            *                         36
            */
            while (s != null && (c == s.right || s.right == null)) {
                c = s;
                s = s.paraent;
            }
            //退出循环时 s 可以为null,比如查找 68 节点的直接后继时退出循环时s=null
            if (s == null) {
                return null;
            } else {
                return s.right;
            }
        }
    }

    /**
     * 查找前序遍历(根左右)直接前驱节点
     *
     * 以非递归 右左根 的方式遍历树
     *
     * @param e 需要查找哪个节点的直接前驱节点
     * @return Entry 前序遍历直接前驱节点
     */
    public Entry preOrderAncestor(Entry e) {
        if (e == null) {
            return null;
        }//如果节点为父节点的左节点,则父节点就是直接前驱节点
        else if (e.paraent != null && e == e.paraent.left) {
            return e.paraent;
        }//如果节点为父节点的右节点
        else if (e.paraent != null && e == e.paraent.right) {

            Entry s = e.paraent;//前驱节点默认为父节点
            if (s.left != null) {//如果父节点没有左子,前驱节点就为父节点
                s = s.left;//如果父节点的左子节点不空,则初始为父节点左子节点

                /*
                * 只要父节点左子节点还有子节点,则前驱节点要从其子树中找。请试着找
                * 一下75直接前驱节点,应该是36
                *
                *                            50
                *                            /\
                *                          37  75
                *                         /    /
                *                       25    61
                *                      /\     /\
                *                    15 30   55 68
                *                       /\    \
                *                     28 32   59
                *                         \
                *                         36
                */
                while (s.left != null || s.right != null) {
                    //在父节点的左子节点的子树中查找时,一定要先向右边拐
                    if (s.right != null) {
                        s = s.right;
                    } else {//如果右边没有,然后才能向左边拐
                        s = s.left;
                    }
                }
            }
            return s;
        } else {//如果是根节点,则没有直接前驱节点了
            return null;
        }
    }

    /**
     * 查找后序遍历(左右根)直接后继节点
     *
     * 以非递归 左右根 的方式遍历树
     *
     * @param e 需要查找哪个节点的直接后继节点
     * @return Entry 后序遍历直接后继节点
     */
    public Entry postOrderSuccessor(Entry e) {
        if (e == null) {
            return null;
        }else if (e.paraent != null && e == e.paraent.right) {
        	//如果节点为父节点的右子节点,则父节点就是直接后继节点
            return e.paraent;
        }//如果节点为父节点的左子节点
        else if (e.paraent != null && e == e.paraent.left) {
            Entry s = e.paraent;//后继节点默认为父节点
            if (s.right != null) {
            	//如果父节点没有右子,后继节点就为父节点
            	//如果父节点的右子节点不空,则初始为父节点右子节点
                s = s.right;
                /*
                 * 只要父节点右子节点还有子节点,则后断节点要从其子树中找,
                 * 如15的后继节点为28
                 *                            50
                 *                            /\
                 *                          37  75
                 *                         /    /
                 *                       25    61
                 *                      /\     /\
                 *                    15 30   55 68
                 *                       /\    \
                 *                     28 32   59
                 *                         \
                 *                         36
                */
                while (s.left != null || s.right != null) {
                    //在父节点的右子节点的子树中查找时,一定要先向左边拐
                    if (s.left != null) {
                        s = s.left;
                    } else {//如果左边没有,然后才能向右边拐
                        s = s.right;
                    }
                }
            }
            return s;
        } else {
            //如果是根节点,则没有后继节点了
            return null;
        }
    }

    /**
     * 查找后序遍历(左右根)直接前驱节点
     *
     * 以非递归 根右左 的方式遍历树
     *
     * @param e 需要查找哪个节点的直接前驱节点
     * @return Entry 后序遍历直接前驱节点
     */
    public Entry postOrderAncestor(Entry e) {

        if (e == null) {
            return null;
        }else if (e.right != null) {
        	//如果右子树不为空,则直接前驱为右子节点
        	//先看右子节点是否为空
        	//如果不为空,则直接后继为右子节点
            return e.right;
        } else if (e.left != null) {
        	//否则如果左子树不为空,则直接前驱为左子节点
            return e.left;
        } else {
        	//左右子节点都为空的情况下
            Entry s = e.paraent;
            Entry c = e;

            /*
            * 一直向上,直到c是s的右子树,且s的左子树不为空。请试着找一下59与15节点的
            * 直接后继节点,59的应该是37,而15则没有后继节点了
            *
            *                            50
            *                            /\
            *                          37  75
            *                         /    /
            *                       25    61
            *                      /\     /\
            *                    15 30   55 68
            *                       /\    \
            *                     28 32   59
            *                         \
            *                         36
            */
            while (s != null && (c == s.left || s.left == null)) {
                c = s;
                s = s.paraent;
            }
            if (s == null) {
                return null;
            } else {
                return s.left;
            }
        }
    }

    /**
     * 查找中序遍历(左根右)直接后继节点
     *
     * 以非递归 左根右 的方式遍历树
     *
     * @param e 需要查找哪个节点的直接后继节点
     * @return Entry 中序遍历直接后继节点
     */
    public Entry inOrderSuccessor(Entry e) {
        if (e == null) {
            return null;
        }else if (e.right != null) {
        	//如果待找的节点有右子树,则在右子树上查找
            //默认后继节点为右子节点(如果右子节点没有左子树时即为该节点)
            Entry p = e.right;
            while (p.left != null) {
                //注,如果右子节点的左子树不为空,则在左子树中查找,且后面找时要一直向左拐
                p = p.left;
            }
            return p;
        }else {
        	//如果待查节点没有右子树,则要在祖宗节点中查找后继节点
            //默认后继节点为父节点(如果待查节点为父节点的左子树,则后继为父节点)
            Entry p = e.paraent;
            //当前节点,如果其父不为后继,则下次指向父节点
            Entry current = e;
            //如果待查节点为父节点的右节点时,继续向上找,一直要找到current为左子节点,则s才是后继
            while (p != null && current == p.right) {
                current = p;
                p = p.paraent;
            }
            return p;
        }
    }

    /**
     * 查找中序遍历(左根右)直接前驱节点
     *
     * 以非递归 右根左 的方式遍历树
     *
     * @param e 需要查找哪个节点的直接前驱节点
     * @return Entry 中序遍历直接前驱节点
     */
    public Entry inOrderAncestor(Entry e) {
        if (e == null) {
            return null;
        } else if (e.left != null) {
        	//如果待找的节点有左子树,则在在子树上查找
            //默认直接前驱节点为左子节点(如果左子节点没有右子树时即为该节点)
            Entry p = e.left;
            while (p.right != null) {
                //注,如果左子节点的右子树不为空,则在右子树中查找,且后面找时要一直向右拐
                p = p.right;
            }
            return p;
        } else {
        	//如果待查节点没有左子树,则要在祖宗节点中查找前驱节点
            //默认前驱节点为父节点(如果待查节点为父节点的右子树,则前驱为父节点)
            Entry p = e.paraent;
            Entry current = e;//当前节点,如果其父不为前驱,则下次指向父节点
            //如果待查节点为父节点的左节点时,继续向上找,一直要找到current为p的右子节点,则s才是前驱
            while (p != null && current == p.left) {
                current = p;
                p = p.paraent;
            }
            return p;
        }
    }

    /**
     * 查找指定的节点
     * @param num
     * @return Entry
     */
    public Entry getEntry(int num) {
        return getEntry(root, num);
    }

    /**
     * 使用树的先序遍历递归方式查找指定的节点
     *
     * @param entry
     * @param num
     * @return
     */
    private Entry getEntry(Entry entry, int num) {

        //如果找到,则停止后续搜索,并把查找到的节点返回给上层调用者
        if (entry.elem == num) {//1、先与父节点比对
            return entry;
        }

        Entry tmp = null;

        if (entry.left != null) {//2、再在左子树上找
            tmp = getEntry(entry.left, num);
            //如果左子树上找到,返回并停止查找,否则继续在后续节点中找
            if (tmp != null) {
                //节点在左子树中找到,返回给上层调用者
                return tmp;
            }
        }

        if (entry.right != null) {//3、否则在右子树上找
            tmp = getEntry(entry.right, num);
            //如果右子树上找到,返回并停止查找,否则继续在后续节点中找
            if (tmp != null) {
                //节点在右子树中找到,返回给上层调用者
                return tmp;
            }
        }

        //当前比较节点 entry 子树为空或不为空时没有找到,直接返回给上层调用者null
        return null;
    }

    /**
     * 根据给定的数组创建一棵树,这个棵树可以是完全二叉树也可是普通二叉树
     * 数组中为0的表示不创建该位置上的节点
     * @param nums 数组中指定了要创建的节点的编号,如果为0,表示不创建
     */
    public void createBinTree(int[] nums) {
        root = recurCreateBinTree(nums, null, 0);
    }

    /**
     * 递归创建二叉树
     * @param nums 数组中指定了要创建的节点的编号,如果为0,表示不创建
     * @param paraent 父节点
     * @param index 需要使用数组中的哪个元素创建节点,如果为元素为0,则不创建
     * @return Entry 返回创建的节点,最终会返回树的根节点
     */
    private Entry recurCreateBinTree(int[] nums, Entry pararent, int index) {
        //指定索引上的编号不为零上才需创建节点
        if (nums[index] != 0) {
            size++;
            Entry root = new Entry(nums[index], pararent);//根节点
            //如果有左子树则创建左子树
            if ((index + 1) * 2 <= nums.length) {
                root.left = (Entry) recurCreateBinTree(nums, root, (index + 1) * 2 - 1);
                //如果还可以创建右子树,则创建
                if ((index + 1) * 2 + 1 <= nums.length) {
                    root.right = (Entry) recurCreateBinTree(nums, root, (index + 1) * 2);
                }
            }
            return (Entry) root;
        }
        return null;

    }

    public int size() {
        return size;
    }

    //测试
    public static void main(String[] args) {
        //创建一棵非完全二叉树
        BackBinTree binTree = new BackBinTree();
        /*
        *                            50
        *                            /\
        *                          37  75
        *                         /    /
        *                       25    61
        *                      /\     /\
        *                    15 30   55 68
        *                       /\    \
        *                     28 32   59
        *                         \
        *                         36
        */
        int[] nums = new int[] { 50, 37, 75, 25, 0, 61, 0, 15, 30, 0, 0, 55, 68, 0, 0, 0,
                0, 28, 32, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36 };
        binTree.createBinTree(nums);

        Entry entry = binTree.getEntry(50);
        System.out.print("根左右(先序遍历)- ");
        while (entry != null) {
            System.out.print(entry.elem + " ");
            entry = binTree.preOrderSuccessor(entry);
        }
        System.out.println();
        entry = binTree.getEntry(68);
        System.out.print("右左根(先序的逆)- ");
        while (entry != null) {
            System.out.print(entry.elem + " ");
            entry = binTree.preOrderAncestor(entry);
        }
        System.out.println();
        entry = binTree.getEntry(15);
        System.out.print("左右根(后序遍历)- ");
        while (entry != null) {
            System.out.print(entry.elem + " ");
            entry = binTree.postOrderSuccessor(entry);
        }
        System.out.println();

        entry = binTree.getEntry(50);
        System.out.print("根右左(后序的逆)- ");
        while (entry != null) {
            System.out.print(entry.elem + " ");
            entry = binTree.postOrderAncestor(entry);
        }
        System.out.println();

        entry = binTree.getEntry(15);
        System.out.print("左根右(中序遍历)- ");
        while (entry != null) {
            System.out.print(entry.elem + " ");
            entry = binTree.inOrderSuccessor(entry);
        }
        System.out.println();

        entry = binTree.getEntry(75);
        System.out.print("右根左(中序的逆)- ");
        while (entry != null) {
            System.out.print(entry.elem + " ");
            entry = binTree.inOrderAncestor(entry);
        }
        System.out.println();
        /*
         * output:
         * 根左右(先序遍历)- 50 37 25 15 30 28 32 36 75 61 55 59 68
         * 右左根(先序的逆)- 68 59 55 61 75 36 32 28 30 15 25 37 50
         * 左右根(后序遍历)- 15 28 36 32 30 25 37 59 55 68 61 75 50
         * 根右左(后序的逆)- 50 75 61 68 55 59 37 25 30 32 36 28 15
         * 左根右(中序遍历)- 15 25 28 30 32 36 37 50 55 59 61 68 75
         * 右根左(中序的逆)- 75 68 61 59 55 50 37 36 32 30 28 25 15
         */
    }
}

 

 

分享到:
评论

相关推荐

    Java二叉树算法实例.zip_java 二叉树_二叉树

    这个名为"Java二叉树算法实例.zip"的压缩包显然是一个针对初学者的教程,旨在帮助他们理解并掌握二叉树的基本概念和常见算法。 首先,二叉树是由节点构成的数据结构,每个节点包含两个子节点,分别称为左子节点和右...

    java 二叉树 算法

    java 二叉树 算法。。。。。。。。。。。。。。。

    java算法二叉树

    以下是一些关于Java中二叉树算法的知识点: 1. **递归实现**: - 在给定的代码中,我们可以看到斐波那契数列(Fibonacci sequence)的递归实现。递归是一种强大的编程技术,尤其适用于处理树状结构。在这个例子中...

    二叉树的java算法

    在Java中实现二叉树算法,我们通常会用到面向对象编程的思想,通过定义一个类来表示树节点,并包含相关的操作方法。在这个主题中,我们将深入探讨二叉树的遍历算法,包括前序遍历、中序遍历和后序遍历。 首先,我们...

    Java二叉树算法实现:节点插入与遍历示例代码

    ### Java二叉树算法实现:节点插入与遍历示例代码 #### 一、核心概念与定义 在深入了解本文档中的代码之前,我们先来回顾一下二叉树的基本概念: - **二叉树**是一种非线性的数据结构,每个节点最多有两个子节点...

    java 二叉树新增删除

    总的来说,理解和掌握二叉树的插入、删除及遍历是Java数据结构和算法学习中的重要部分。它们不仅有助于解决实际问题,而且对于提高编程能力,特别是处理复杂数据结构时,都有着不可忽视的价值。在实践中,二叉树的...

    java二叉树

    以下是对"java二叉树"这个主题的详细解析。 首先,我们要理解二叉树的基本操作: 1. 插入节点:在二叉树中插入新节点时,需要遵循二叉树的规则,即新节点只能作为现有节点的左孩子或右孩子。插入操作取决于比较新...

    用Java实现的二叉树算法.doc

    用Java实现的二叉树算法.doc

    java二叉树的前序+中序+后序遍历

    java实现 二叉树的遍历 前序遍历用到递归, 中序和后序遍历用到栈, 其实还是有一定难度的

    Java二叉树中序遍历

    二叉树被广泛应用于数据存储、搜索算法、编译器设计等多种场景。中序遍历是二叉树遍历的一种方法,它按照“左-根-右”的顺序访问树中的所有节点,对于理解树的性质和执行某些操作非常有用。本课程设计将详细介绍如何...

    java二叉树算法

    二叉树算法,主要是实现二叉树的子树的添加,删除,修改等

    Java 二叉树(生成与遍历)

    总的来说,Java中的二叉树是数据结构与算法学习的重要部分,掌握其生成与遍历对于提升编程能力非常有益。通过练习和实践,你可以更好地理解和运用二叉树在各种场景下的优势。在提供的`BinaryTree`项目中,你将找到更...

    java 常见排序算法的实现 包括二叉树

    本文将详细介绍几种常见的排序算法及其Java实现,同时也会涉及二叉树的基本概念和实现。 首先,让我们从最简单的排序算法开始。冒泡排序是一种基础的交换排序方法,它通过重复遍历待排序的数组,依次比较相邻元素并...

    Java常用算法手册(jb51.net)_Java常用算法手册_

    《Java常用算法手册》是一本面向Java初学者的算法指南,旨在通过深入浅出的方式,帮助读者理解并掌握各种常见的编程算法,从而提高他们的编程能力和解决问题的效率。这本书的覆盖范围广泛,涉及到算法基础、数据结构...

    二叉树算法

    掌握二叉树算法对于学习面向对象编程、迭代、排序和搜索算法(如冒泡排序、选择排序、快速排序等)至关重要,同时也对理解C++、Java等编程语言、数据库操作、底层知识、网络编程、多线程和多进程等高级主题有深远...

    用Java编写的二叉树代码

    在计算机科学领域,二叉树是一...通过分析和实践这些Java二叉树代码,你可以深入理解二叉树的基本原理和操作,提高你的编程技能和解决问题的能力。同时,这对于准备面试或参加编程竞赛的开发者来说也是必不可少的练习。

    二维矩形装箱算法--二叉树--java实现

    在Java实现中,`BaseBoxChoose.java`可能包含了装箱算法的基本策略或基类,定义了装箱选择的接口和通用方法。`Slaves.java`可能是处理并行计算的部分,利用多线程并行处理多个箱子的装车问题,提高算法执行效率。`...

    java实现的二叉树源码

    在Java编程语言中,二叉树是一种非常基础且重要的数据结构。它由一系列节点组成,每个节点最多有两个子节点,通常分为左子节点和右子节点。二叉树的应用广泛,比如在搜索、排序、文件系统等场景。下面我们将详细讨论...

Global site tag (gtag.js) - Google Analytics