Java实现数据结构——二叉查找树

二叉查找树

二叉树是层次结构,要么是空集,要么是一个根(root)的元素和两颗不同的二叉树组成。空树的高度为0,非空树的高度是从根结点到它最远叶子结点的路劲长度+1。

树的遍历

访问树中每个结点一次且只有一次的过程
Tree-example:
《Java实现数据结构——二叉查找树》

前序遍历

  1. 访问当前结点
  2. 访问该结点的左子树
  3. 访问该结点的右子树
    《Java实现数据结构——二叉查找树》
    遍历结果:5 3 2 4 7 6 8
    用途:打印结构性文档,书、章、节

中序遍历

  1. 访问该结点的左子树
  2. 访问当前结点
  3. 访问该结点的右子树
    《Java实现数据结构——二叉查找树》
    遍历结果:2 3 4 5 6 7 8
    用途:以递增的顺序显示二叉树的所有节点

后序遍历

  1. 访问该结点的左子树
  2. 访问该结点的右子树
  3. 访问当前结点
    《Java实现数据结构——二叉查找树》
    遍历结果:2 4 3 6 8 7 5
    用途:文件系统中,在找出根目录之前,得到每个文件和子目录。

广度优先遍历

逐层访问树中的结点
1. 访问根结点
2. 从左往右,访问根结点的所有孩子
3. 从左往右,访问根结点的所有孙子结点
遍历结果:5 3 7 2 4 6 8

详细实现

设计结构图:
《Java实现数据结构——二叉查找树》

接口定义

package com.edu.chapter.twenty_six.day0416;

import java.util.Iterator;

/** * @author xukai * @date 2017年4月16日 下午6:17:40 * */
public interface Tree<E extends Comparable<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();

    public Iterator<E> iterator();

}

抽象类定义

package com.edu.chapter.twenty_six.day0416;

import java.util.Iterator;

/** * @author xukai * @param <E> * @date 2017年4月16日 下午6:24:12 * */
public abstract class AbstractTree<E extends Comparable<E>> implements Tree<E> {

    @Override
    public void inorder() {
        // TODO Auto-generated method stub
    }

    @Override
    public void postorder() {
        // TODO Auto-generated method stub
    }

    @Override
    public void preorder() {
        // TODO Auto-generated method stub
    }

    @Override
    public boolean isEmpty() {
        // TODO Auto-generated method stub
        return getSize() == 0;
    }

    @Override
    public Iterator<E> iterator() {
        // TODO Auto-generated method stub
        return null;
    }

}

具体实现

结点静态内部类

    /** * 结点类 * @author xukai * @date 2017年4月18日 上午10:52:46 * @param <E> * */
    public static class TreeNode<E extends Comparable<E>>{
        E element;
        TreeNode<E> left;
        TreeNode<E> right;

        public TreeNode(E e) {
            element = e;
        }


        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result =
                prime * result + ((element == null) ? 0 : element.hashCode());
            result = prime * result + ((left == null) ? 0 : left.hashCode());
            result = prime * result + ((right == null) ? 0 : right.hashCode());
            return result;
        }


        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            TreeNode<?> other = (TreeNode<?>) obj;
            if (element == null) {
                if (other.element != null)
                    return false;
            } else if (!element.equals(other.element))
                return false;
            if (left == null) {
                if (other.left != null)
                    return false;
            } else if (!left.equals(other.left))
                return false;
            if (right == null) {
                if (other.right != null)
                    return false;
            } else if (!right.equals(other.right))
                return false;
            return true;
        }


        @Override
        public String toString() {
            return "TreeNode [element=" + element + ", left=" + left
                + ", right=" + right + "]";
        }

    }

添加元素

  1. 判断是否为空树
  2. 找出当前插入结点的父结点
  3. 插入节点,size++
    @Override
    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;
                }
            }

            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);
    }

查找元素

    @Override
    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;
    }

删除元素

  1. 查找到要删除的元素
  2. 假如当前结点没有左孩子,将该结点的父结点和当前结点的右孩子相连。
  3. 假如当前结点有一个左孩子,找出当前结点current的左子树中最大元素结点rightMax,
    将rightMax的父结点和rightMax的左孩子相连,删除rightMax,size–。
    @Override
    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;
        }

        if (current.left == null) {
            // current-node not exist left-node
            if (parent == null) {
                root = current.right;
            } else {
                // connect to current.right and parent
                if (e.compareTo(parent.element) < 0) {
                    parent.left = current.right;
                } else {
                    parent.right = current.right;
                }
            }
        } else {
            // current-node exist left-node
            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 == current is true; 
                parentOfRightMost.left = rightMost.left;
            }
        }

        size --;
        return true;
    }

前序遍历

    @Override
    public void inorder() {
        inorder(root);
    }

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

广度优先遍历

    /** * 广度优先遍历 */
    public void breadthFirstTraversal() {
        LinkedList<BinaryTree.TreeNode<E>> queue = new LinkedList<>();

        if (this.root == null) {
            return;
        }
        queue.add(this.root);

        while (!queue.isEmpty()) {
            TreeNode<E> node = queue.removeFirst();
            System.out.println(node.element + " ");
            if (node.left != null) {
                queue.add(node.left);
            }
            if (node.right != null) {
                queue.add(node.right);
            }
        }
    }

二叉排序树是一种分层的数据结构。
查看源码(附带Applet可视化界面,乱码是因为项目是utf-8,需要改成gbk)
《Java实现数据结构——二叉查找树》

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/u011499992/article/details/70674087
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞