数据结构之二叉查找树的递归和非递归实现的一些方法

对于二叉树的学习可以很好的复习递归思想和非递归实现相同功能的方法:

1:二叉查找树:它的左子树中节点的值都小于该节点的值,而它的右子树的节点的值都大于该节点的值的树形结构

1:定义一个数接口

public interface Tree<E> extends Iterable<E>{
    public boolean search(E e);
    public boolean insert(E e);
    public boolean delete(E e);
    public void inorder();
    public void postorder();
    public void preorder();
    public int getSize();
    public boolean isEmpty();
}
3:定义一个抽象类实现树接口:

public abstract class AbstractTree<E> implements Tree<E>{
    public void inorder() {

    }

    public void postorder() {

    }

    public void preorder() {

    }

    public boolean isEmpty() {
        return getSize() == 0;
    }
}
4::定义一个二叉树类:

package com.li.tree;

import java.util.*;

public class BST<E extends Comparable<E>> extends AbstractTree<E>{
    protected TreeNode<E> root;
    protected int size = 0;
    public BST(){

    }
    public BST(E[] objects){
        for(int i = 0;i < objects.length;i++){
            insert(objects[i]);
        }
    }
    public boolean search(E e){
        TreeNode<E> current = root;
        while(current != null){
            if(e.compareTo(current.element) < 0){
                current = current.left;
            }else if(e.compareTo(current.element) > 0){
                current = current.right;
            }else{
                return true;
            }
        }
        return false;
    }
    //利用递归方法查询:search的重载方法
    public boolean search(E e,TreeNode<E> start){
         if(start == null){
             return false;
         }
         if(e.compareTo(start.element) > 0){
             return search(e,start.right);
         }else if(e.compareTo(start.element) < 0){
             return search(e,start.left);
         }else{
             return true;
         }




    }
    public boolean insert(E e){
        if(root == null){
            root = createNewNode(e);
        }else{
            TreeNode<E> parent = null;
            TreeNode<E> current = root;
            while(current != null){
                if(e.compareTo(current.element) < 0){
                    parent = current;
                    current = current.left;
                }else if(e.compareTo(current.element) > 0){
                    parent = current;
                    current = current.right;
                }else{
                    return false;
                }
            }
            //说明已经找到父节点了,当前current为空值,创建一个节点放置e的值
            if(e.compareTo(parent.element) < 0){
                parent.left = createNewNode(e);
            }else{
                parent.right = createNewNode(e);
            }

        }
        size++;
        return true;
    }
    protected TreeNode<E> createNewNode(E e){
        return new TreeNode<E>(e);
    }
    //中序遍历
    public void inorder(){
        inorder(root);
    }
    //中序遍历
    protected void inorder(TreeNode<E> root){
        if(root == null){
            return ;
        }
        inorder(root.left);
        System.out.println(root.element + " ");
        inorder(root.right);
    }
    //不使用递归实现中序遍历:使用栈代替递归
    private void inorder_1(){
        TreeNode<E> current = root;
        //创建一个栈
        Stack<TreeNode<E>> stack = new Stack<TreeNode<E>>();
        while(current != null || !stack.isEmpty()){
            //对根节点左子树进行压栈操作
            while(current != null){
                //将当前节点压入栈中
                stack.push(current);
                current = current.left;
            }
            //弹出最左边的节点
            current = stack.pop();
            //输出该节点后接着处理右子树
            System.out.print(current.element + " ");
            //处理右子节点
            current = current.right;
        }

    }
    public void postorder(){
        postorder(root);
    }
    //后序遍历
    protected void postorder(TreeNode<E> root){
        if(root == null) {
            return;
        }
        postorder(root.left);
        postorder(root.right);
        System.out.println(root.element + " ");

    }
    //非递归实现
    private void postorder_1(){
        TreeNode<E> current = root;
        if(current == null){
            return ;
        }
        Stack<TreeNode<E>> stack = new Stack<TreeNode<E>>();
        Map<TreeNode<E>,Boolean> map = new HashMap<TreeNode<E>,Boolean>();
        stack.push(current);
        while(!stack.isEmpty()){
            TreeNode<E> temp = stack.peek();
            if(temp.left != null && !map.containsKey(temp.left)){
                temp = temp.left;
                while(temp != null){
                    if(map.containsKey(temp))break;
                    else stack.push(temp);
                    temp = temp.left;
                }
                continue;
            }
            if(temp.right != null && !map.containsKey(temp.right)){
                stack.push(temp.right);
                continue;
            }
            TreeNode t = stack.pop();
            map.put(t,true);
            System.out.println(t.element);
        }


    }
    public void preorder(){
        preorder(root);
    }
    protected void preorder(TreeNode<E> root){
        if(root == null){
            return ;
        }
        System.out.print(root.element + " ");
        preorder(root.left);
        preorder(root.right);

    }
    //非递归方式实现前序遍历1
    private void preorder_1(){
        TreeNode<E> current = root;
        if(current == null){
            return ;
        }
        Stack<TreeNode<E>> stack = new Stack<TreeNode<E>>();
        stack.push(current);
        while(!stack.isEmpty()){
            TreeNode<E> temp = stack.pop();
            System.out.print(temp.element + " ");
            if(temp.right != null){
                stack.push(temp.right);
            }
            if(temp.left != null){
                stack.push(temp.left);
            }

        }

    }
    //非递归实现前序遍历2
    private void preorder_2(){
        TreeNode<E> current = root;
        Stack<TreeNode<E>> stack = new Stack<TreeNode<E>>();
        while(current != null || !stack.isEmpty()){
            while(current != null){
                System.out.print(current.element + " ");
                stack.push(current);
                current = current.left;
            }
            //先弹出之后再处理右节点
            current = stack.pop();
            current = current.right;

        }

    }
    //内部类
    public static class TreeNode<E extends Comparable<E>>{
        protected E element;
        protected TreeNode<E> left;
        protected TreeNode<E> right;
        public TreeNode(E e){
            element = e;
        }
    }
    public int getSize(){
        return size;
    }
    public TreeNode<E> getRoot(){
        return root;
    }
    //returns a path from the root leading to the specified element
    public ArrayList<TreeNode<E>> path(E e){
        ArrayList<TreeNode<E>> list = new ArrayList<TreeNode<E>>();
        TreeNode<E> current = root;  //从ROOT开始
        while(current != null){
            list.add(current);  //add the node to the root
            if(e.compareTo(current.element) < 0){
                current = current.left;
            }else if(e.compareTo(current.element) > 0){
                current = current.right;
            }else
                break;
        }
        return list;
    }
    /*分两种情况进行删除元素
    * 设查找的的节点为当前节点current,其父节点为parent,
    * 1:current没有左子树
    *   --有右子树
    *   --没有右子树
    * 2:current有左子树
    *    --有右子树
    *    --没有右子树
    * */
    public boolean delete(E e){
        TreeNode<E> parent = null;
        TreeNode<E> current = root;
        while(current != null){
            if(e.compareTo(current.element) < 0){
                parent = current;
                current = current.left;
            }else if(e.compareTo(current.element) > 0){
                parent = current;
                current = current.right;
            }else{
                break;
            }
        }
        if(current == null){
            //没有找到该元素
            return false;
        }
        //current没有左子树,current是含有删除元素的节点,正是我们要找的节点
        if(current.left == null){
            //如果父节点为空的话:说明当前节点是根节点
            if(parent == null){

                root = current.right;
            }else{
                //如果他的父节点不为空的话说明不是根节点
                if(e.compareTo(parent.element) < 0){
                    parent.left = current.right;
                }else
                    parent.right = current.right;
            }
        }else{
            //current有左子树
            TreeNode<E> parentOfRightMost = current;
            //当前节点的左子树
            TreeNode<E> rightMost = current.left;
            //对当前节点的左子树的右子树不为空的时候进行遍历
            while(rightMost.right != null){
                //将当前节点转向其左子树
                parentOfRightMost = rightMost;
                rightMost = rightMost.right;
            }
            current.element = rightMost.element;
            if(parentOfRightMost.right == rightMost){
                parentOfRightMost.right = rightMost.left;
            }else{
                parentOfRightMost.left = rightMost.left;
            }

        }
        size --;
        return true;
    }
    public Iterator<E> iterator(){
        return new InorderIterator();
    }
    //内部类
    private class InorderIterator implements Iterator<E> {
        private ArrayList<E> list = new ArrayList<E>();
        private int current = 0;
        public InorderIterator(){
            inorder();
        }
        private void inorder(){
            inorder(root);
        }
        private void inorder(TreeNode<E> root){
            if(root == null){
                return ;
            }
            inorder(root.left);
            list.add(root.element);
            inorder(root.right);
        }
        public boolean hasNext(){
            if(current < list.size()){
                return true;
            }
            return false;
        }
        public E next(){
            return list.get(current++);
        }
        public void remove(){
            delete(list.get(current));
            list.clear();
            inorder();
        }
        public void clear(){
            root = null;
            size = 0;
        }
    }


}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值