Binary Search Tree(二叉查找树)

Binary Search Tree

也被成为 ordered binary tree(有序二叉树)或 sorted binary tree(排序二叉树),有如下性质:

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;
  4. 没有键值相等的节点。

和数组,链表的比较

数据:查找快 O(1),插入慢O(N) 需要移动插入点之后的所有数据。
链表:查找慢 O(N) ,插入快 O(1) 每次查找都需要遍历一遍

于是作为平衡的Binary Search Tree出现了
查找 平均O(logN) 最差O(N)
插入 平均O(logN) 最差O(N)

JAVA实现

首先定义Node,最少包含3个属性,左节点,右节点和值。

public class Node {

    public Object data;

    public Node left;

    public Node right;

    public Node(Object o) {
        this.data = o;
    }
}

前序遍历

按照 root ー> left subtree ー> right subtree 的顺序访问节点。

递归实现
public void printPreOrder(Node n) {
        if (n == null) {
            return;
        }
        System.out.println(n.data);

        if (n.left != null) {
            printPreOrder(n.left);
        }
        if (n.right != null) {
            printPreOrder(n.right);
        }

    }
非递归实现
public void printPreOrderWithoutRecursion(Node n) {
        if (n == null) {
            return;
        }
        Stack<Node> s = new Stack<Node>();
        Node current = n;
        while (current != null || !s.isEmpty()) {

            while (current != null) {
                System.out.println(current.data);
                s.push(current);
                current = current.left;
            }

            if (!s.empty()) {
                current = s.pop();
                current = current.right;
            }

        }
    }

中序遍历

按照 left subtree ー> root ー> right subtree 的顺序访问节点。

递归实现
public void printMidOrder(Node n) {
        if (n == null) {
            return;
        }
        if (n.left != null) {
            printMidOrder(n.left);
        }
        System.out.println(n.data);

        if (n.right != null) {
            printMidOrder(n.right);
        }

    }
非递归实现
public void printMidOrderWithoutRecursion(Node n) {

        if (n == null) {
            return;
        }
        Stack<Node> s = new Stack<Node>();
        Node current = n;
        while (current != null || !s.isEmpty()) {

            while (current != null) {

                s.push(current);
                current = current.left;
            }

            if (!s.empty()) {
                current = s.pop();
                System.out.println(current.data);
                current = current.right;
            }

        }

    }

后序遍历

按照 left subtree ー> right subtree ー> root 的顺序访问节点。

递归实现
public void printAftOrder(Node n) {
        if (n == null) {
            return;
        }
        if (n.left != null) {
            printAftOrder(n.left);
        }

        if (n.right != null) {
            printAftOrder(n.right);
        }

        System.out.println(n.data);

    }
非递归实现

后序遍历的非递归实现方法有好几种,其中的一个思路是在node中增加一个标志位来记录是否是第一次访问,如果是第一次访问就再次入栈并查找right subtree,只有当right subtree也查找完成之后第二次入栈的时候再打印。

public class Node {
    public Object data;
    public Node left;
    public Node right;
    public boolean isFirst;

    public Node(Object o) {
        this.data = o;
    }
}
public void printAftOrderWithoutRecursion_1(Node n) {

        if (n == null) {
            return;
        }
        Stack<Node> s = new Stack<Node>();
        Node current = n;
        while (current != null || !s.isEmpty()) {

            while (current != null) {
                current.isFirst = true;
                s.push(current);
                current = current.left;
            }

            if (!s.empty()) {
                current = s.pop();

                if (current.isFirst) {
                    current.isFirst = false;
                    s.push(current);
                    current = current.right;
                } else {
                    System.out.println(current.data);
                    current = null;
                }
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_42498646/article/details/88419505