/**
* 后序遍历:非递归方法,左孩子、右孩子、根节点
* 第一次遇见才进栈,并标记遇见一次(false),一直向左找直到null,开始回溯向右找,取栈顶元素,
* 若只遇见一次(false),就标记遇见两次(true),访问栈顶元素右子树
* 若遇见了2次(true),就可以弹栈输出了,他就没用啦~
*
* @param root
*/publicvoidnoRecurPostorder(IntBSTNode root){Stack<IntBSTNode> stack =newStack<>();HashMap<IntBSTNode,Boolean> hashMap =newHashMap<>();IntBSTNode now = root;while(now !=null||!stack.empty()){while(now !=null&& hashMap.get(now)==null){//都是第一次,一直向左访问,进栈
stack.push(now);
hashMap.put(now,false);//null表示未访问过,false表示访问一次,true表示访问2次
now = now.left;}IntBSTNode top = stack.peek();if(!hashMap.get(top)){//若此节点访问过一次,说明左边访问完了还没看右边呢
now = top.right;
hashMap.put(top,true);}else{//若此节点访问2次,就可以输出了~,然后弹栈,没他的事情咯System.out.print(top.key +" ");
stack.pop();}}}
类
树节点
packagedataStructure.tree;/******************IntBSTNode.java****************
* binary search tree node of integers
*/publicclassIntBSTNode{publicint key;publicIntBSTNode left, right;publicIntBSTNode(){
left = right =null;}publicIntBSTNode(int el){this(el,null,null);}publicIntBSTNode(int el,IntBSTNode l,IntBSTNode r){
key = el;
left = l;
right = r;}}
树
/*****************IntBST.java****************
* binary search tree of integers 整数的二叉搜索树
*/publicclassIntBST{publicIntBSTNode root;publicIntBST(){
root =null;}publicIntBST(IntBSTNode r){
root = r;}/**
* 搜索二叉查找树:查找某个元素是否在树中,若是,返回节点,若不是,返回null
*
* @param el
* @return
*/publicIntBSTNodesearch(int el){returnsearch(root, el);}publicIntBSTNodesearch(IntBSTNode p,int el){while(p !=null){if(el == p.key)return p;elseif(el < p.key)//当前元素小于节点的值,进入左子树查找
p = p.left;elseif(el > p.key)
p = p.right;}returnnull;//没找到,返回null}publicvoidvisit(IntBSTNode p){System.out.print(p.key +" ");}/**
* 广度优先遍历:从根到叶、从左到右,根节点入队;
* 访问队首,将节点的孩子入队,循环;
*/publicvoidbreadFirst(){IntBSTNode p = root;Queue<IntBSTNode> queue =newLinkedList<>();if(p !=null){
queue.offer(p);while(!queue.isEmpty()){
p = queue.poll();// visit(p);System.out.print(p.key +" ");if(p.left !=null)
queue.offer(p.left);if(p.right !=null)
queue.offer(p.right);}}}/**
* 深度优先遍历包含:先序、中序、后序
*//**
* 先序遍历,递归方法
*/publicvoidpreorder(){preorder(root);}publicvoidpreorder(IntBSTNode p){if(p !=null){visit(p);preorder(p.left);preorder(p.right);}}/**
* 前序遍历非递归方法:根节点、左孩子、右孩子
* 遇见即进栈,并且输出,直到没有左孩子,回溯即弹栈,向栈顶元素的右孩子找
*
* @param root
*/publicvoidnoRecurPreorder(IntBSTNode root){IntBSTNode now = root;Stack<IntBSTNode> stack =newStack<>();while(now !=null||!stack.empty()){while(now !=null){
stack.push(now);System.out.print(now.key +" ");
now = now.left;}IntBSTNode top = stack.pop();
now = top.right;}}/**
* 中序遍历:递归式
*/publicvoidinorder(){inorder(root);}publicvoidinorder(IntBSTNode p){if(p !=null){inorder(p.left);visit(p);inorder(p.right);}}/**
* 中序遍历非递归方法:左孩子、根节点、右孩子,遇见即进栈,直到没有左孩子,才弹栈回溯(弹栈才输出),向栈顶元素的右孩子找
*
* @param root
*/publicvoidnoRecurInorder(IntBSTNode root){Stack<IntBSTNode> stack =newStack<>();IntBSTNode now = root;while(now !=null||!stack.empty()){while(now !=null){
stack.push(now);
now = now.left;}IntBSTNode top = stack.pop();System.out.print(top.key +" ");
now = top.right;}}/**
* 后序遍历:递归方法
*/publicvoidpostorder(){postorder(root);}publicvoidpostorder(IntBSTNode p){if(p !=null){postorder(p.left);postorder(p.right);visit(p);}}/**
* 后序遍历:非递归方法,左孩子、右孩子、根节点
* 第一次遇见才进栈,并标记遇见一次(false),一直向左找直到null,开始回溯向右找,取栈顶元素,
* 若只遇见一次(false),就标记遇见两次(true),访问栈顶元素右子树
* 若遇见了2次(true),就可以弹栈输出了,他就没用啦~
*
* @param root
*/publicvoidnoRecurPostorder(IntBSTNode root){Stack<IntBSTNode> stack =newStack<>();HashMap<IntBSTNode,Boolean> hashMap =newHashMap<>();IntBSTNode now = root;while(now !=null||!stack.empty()){while(now !=null&& hashMap.get(now)==null){//都是第一次,一直向左访问,进栈
stack.push(now);
hashMap.put(now,false);//null表示未访问过,false表示访问一次,true表示访问2次
now = now.left;}IntBSTNode top = stack.peek();if(!hashMap.get(top)){//若此节点访问过一次,说明左边访问完了还没看右边呢
now = top.right;
hashMap.put(top,true);}else{//若此节点访问2次,就可以输出了~,然后弹栈,没他的事情咯System.out.print(top.key +" ");
stack.pop();}}}}