• 树、多路树、二叉树


    结合了有序数组和链表的优点。在树中查询和在有序数组中一样快;插入和删除和链表一样快。

    遍历相对比较慢一点。

    从根到其它任何一个节点有且只有一条路径,比如下面的图示不是树:

    多路树

    每个节点的子节点可以多于两个

    二叉树

    每个节点的子节点最多有两个

    二叉搜索树

    一个节点的左子节点的数小于该节点,右子节点的数大于或等于该父节点

    其它二叉树

    二叉树并不全是搜索树。二叉树可以用于表示代数表达式,还可以用于哈夫曼编码以令人惊讶的方式压缩数据。

    二叉搜索树的代码

    class Node {
        public int iData;
        public double dData;
        public Node leftChild;
        public Node rightChild;
    
        public void displayNode() {
            System.out.print('{');
            System.out.print(iData);
            System.out.print(", ");
            System.out.print(dData);
            System.out.print("} ");
        }
    }
    
    class Tree {
        private Node root;
        public Tree() {
            root = null;
        }
        /* 前序遍历
         * 二叉树(不是二叉搜索树)可以表示包括二元操作符的算术表达式。
         *             *
         *          a     +
         *              b   c 
         * 中序遍历会得到中序表达式,不过要自己加括号
         * 前序遍历会得到前序表达式
         * 后序遍历会得到后序表达式
         */
        private void preOrder(Node localRoot) {
            if (localRoot != null) {
                System.out.print(localRoot.iData + " ");
                preOrder(localRoot.leftChild);
                preOrder(localRoot.rightChild);
            }
        }
        // 中序遍历,最常用,如果是二叉搜索树结果升序。
        private void inOrder(Node localRoot) {
            if (localRoot != null) {
                inOrder(localRoot.leftChild);
                System.out.print(localRoot.iData + " ");
                inOrder(localRoot.rightChild);
            }
        }
        // 后序遍历
        private void postOrder(Node localRoot) {
            if (localRoot != null) {
                postOrder(localRoot.leftChild);
                postOrder(localRoot.rightChild);
                System.out.print(localRoot.iData + " ");
            }
        }
        // 插入
        public void insert(int id, double dd) {
            Node newNode = new Node();
            newNode.iData = id;
            newNode.dData = dd;
            if (root == null)
                root = newNode;
            else {
                Node current = root;
                Node parent;
                while (true) {
                    parent = current;
                    if (id < current.iData) {
                        current = current.leftChild;
                        if (current == null) {
                            parent.leftChild = newNode;
                            return;
                        }
                    }  
                    else {
                        current = current.rightChild;
                        if (current == null) {
                            parent.rightChild = newNode;
                            return;
                        }
                    }  
                }
            }
        }
        // 查找
        public Node find(int key) {
            Node current = root;
            while (current.iData != key) {
                if (key < current.iData)
                    current = current.leftChild;
                else
                    current = current.rightChild;
                if (current == null)
                    return null;
            }
            return current;
        }
        // 删除
        public boolean delete(int key) {
            Node current = root;
            Node parent = root;
            boolean isLeftChild = true;
    
            while (current.iData != key) {
                parent = current;
                if (key < current.iData) {
                    isLeftChild = true;
                    current = current.leftChild;
                } else {
                    isLeftChild = false;
                    current = current.rightChild;
                }
                if (current == null)
                    return false;
            }
            if (current.leftChild == null &&
                    current.rightChild == null) {
                if (current == root)
                    root = null;
                else if (isLeftChild)
                    parent.leftChild = null;
                else
                    parent.rightChild = null;
            } else if (current.rightChild == null)
                if (current == root)
                    root = current.leftChild;
                else if (isLeftChild)
                    parent.leftChild = current.leftChild;
                else
                    parent.rightChild = current.leftChild;
    
    
            else if (current.leftChild == null)
                if (current == root)
                    root = current.rightChild;
                else if (isLeftChild)
                    parent.leftChild = current.rightChild;
                else
                    parent.rightChild = current.rightChild;
    
            else {
                Node successor = getSuccessor(current);
                if (current == root)
                    root = successor;
                else if (isLeftChild)
                    parent.leftChild = successor;
                else
                    parent.rightChild = successor;
                successor.leftChild = current.leftChild;
            }
            return true;
        }
        private Node getSuccessor(Node delNode) {
            Node successorParent = delNode;
            Node successor = delNode;
            Node current = delNode.rightChild;
            while (current != null) {
                successorParent = successor;
                successor = current;
                current = current.leftChild;
            }
    
            if (successor != delNode.rightChild) {
                successorParent.leftChild = successor.rightChild;
                successor.rightChild = delNode.rightChild;
            }
            return successor;
        }
        public void traverse(int traverseType) {
            switch (traverseType) {
                case 1:
                    System.out.print("
    Preorder traversal: ");
                    preOrder(root);
                    break;
                case 2:
                    System.out.print("
    Inorder traversal:  ");
                    inOrder(root);
                    break;
                case 3:
                    System.out.print("
    Postorder traversal: ");
                    postOrder(root);
                    break;
            }
            System.out.println();
        }
        public void displayTree() {
            Stack globalStack = new Stack();
            globalStack.push(root);
            int nBlanks = 32;
            boolean isRowEmpty = false;
            System.out.println(
                    "......................................................");
            while (isRowEmpty == false) {
                Stack localStack = new Stack();
                isRowEmpty = true;
    
                for (int j = 0; j < nBlanks; j++)
                    System.out.print(' ');
    
                while (globalStack.isEmpty() == false) {
                    Node temp = (Node) globalStack.pop();
                    if (temp != null) {
                        System.out.print(temp.iData);
                        localStack.push(temp.leftChild);
                        localStack.push(temp.rightChild);
    
                        if (temp.leftChild != null ||
                                temp.rightChild != null)
                            isRowEmpty = false;
                    } else {
                        System.out.print("--");
                        localStack.push(null);
                        localStack.push(null);
                    }
                    for (int j = 0; j < nBlanks * 2 - 2; j++)
                        System.out.print(' ');
                }  // end while globalStack not empty
                System.out.println();
                nBlanks /= 2;
                while (localStack.isEmpty() == false)
                    globalStack.push(localStack.pop());
            }  // end while isRowEmpty is false
            System.out.println(
                    "......................................................");
        }
    }
    View Code

    树的效率

    节点数 层数  
    1 1
    3 2
    7 3
    15 4
    31 5
    ... ...
    1023 10
    ... ...
    32767 15
    ... ...
    1048575 20
    ... ...
    33554432 25
    ... ...
    1073741824 30              

      


    如果一颗树是绝对平衡的满树,该树有L层,那么最差的查询效率是L次。
    设表中节点数是N,层数是L,则N = 2L - 1;L = log2(N+1),大致为L=Log2N 。因此,常见的树的操作时间复杂度大致是O(LogN)。
    如果树不满,分析起来比较困难。不过,在这种情况下,在较低层查找的次数要少。

  • 相关阅读:
    HTML文本格式化与HTML 超链接
    html知识杂记
    常用的默认函数
    js条件语句初步练习
    DevOps之docker自动化部署web应用
    DevOps之docker自动化部署java应用
    hive应用基础知识备忘
    hive应用-离线数据仓库分层模型
    hive基础-数据模型
    hive基础-组件介绍
  • 原文地址:https://www.cnblogs.com/Mike_Chang/p/10417482.html
Copyright © 2020-2023  润新知