data structure —— tree data structure

Trees

What is a tree data structure?

Definition: is a non-linear hierarchical structure that is used to represent and organize data in a way that is easy to navigate and search. It is a collection of nodes that are connected by edges and has a hierarchical relationship between the nodes. The topmost node of the tree is called the root, and the nodes below it are called the child nodes, and these child nodes can also have their own child nodes, forming a recursive structure.

Basic Operation of tree

Create-create a tree in data structure.

Insert- inserts data in a tree.

Search-

Preorder Traversal-per form Traveling a tree in a pre-order manner in data structure.

In order traversal – perform traveling a tree in an in-order manner.

Post order traversal- perform Traveling a tree in a post-order manner.

Types of tree data structures.

  1. General tree
public class BinaryTree {
    Node root;

    public class Node {

        public int data;

        public Node leftNode;

        public Node rightNode;

        public Node(int key) {
            data = key;
        }

        Node findNode(int key) {
            Node currentNode = root;
            if (currentNode == null) {
                return null;
            }
//            //暴力查找
//            if (currentNode.data == key) {
//                return currentNode;
//            }
//
//            //查找左节点
//            while (currentNode.leftNode != null) {
//                if (currentNode.leftNode.data == key) {
//                    return currentNode.leftNode;
//                }
//                currentNode = currentNode.leftNode;
//            }
//            //查找右节点
//            while (currentNode.rightNode != null) {
//                if (currentNode.rightNode.data == key) {
//                    return currentNode.rightNode;
//                }
//                currentNode = currentNode.rightNode;
//            }

            //二分法查找
            while (currentNode != null) {
                if (currentNode.data > key) {
                    //当前值比查找值大 则继续遍历左子树
                    currentNode = currentNode.leftNode;
                } else if (currentNode.data < key) {
                    //当前值小于查找值 则继续遍历右子树
                    currentNode = currentNode.rightNode;
                } else {
                    //查找到 返回
                    return currentNode;
                }
            }
            return null;
        }
    }

    void insert(int value, BinaryTree binaryTree) {
        if (binaryTree == null || binaryTree.root == null) {
            binaryTree = new BinaryTree();
            binaryTree.root = new Node(value);
            return;
        }
        //compare the key value
        Node currentNode = binaryTree.root;
        while (currentNode != null) {
            if (currentNode.data > value) {
                currentNode = currentNode.leftNode;
                if (currentNode == null) {
                    currentNode.leftNode = new Node(value);
                }
            } else {
                currentNode = currentNode.rightNode;
                if (currentNode == null) {
                    currentNode.rightNode = currentNode;
                }
            }
        }
    }

    boolean deleteNode(int value) {
        Node current = root;
        Node parent = root;
        boolean isLeft = false;
        //Check the node exists
        while (current != null) {
            if (root == null) {
                return false;
            } else {
                if (root.data < value) {
                    isLeft = true;
                    current = current.rightNode;
                    parent = current;
                } else if (root.data > value) {
                    parent = current;
                    current = current.leftNode;
                }
            }
        }
        //case 1: the node is a left
        if (current.leftNode == null && current.rightNode == null) {
            if (isLeft) {
                parent.leftNode = null;
            } else {
                parent.rightNode = null;
            }
        }
        //case 2: the node has a child
        else if (current.leftNode != null || current.rightNode != null) {
            Node childNode = current.leftNode != null ? current.leftNode : current.rightNode;
            if (isLeft) {
                parent.leftNode = childNode;
            } else {
                parent.rightNode = childNode;
            }
        }
        //case 3: the node has two children.
        else {

        }
        return true;
    }
     
}
  1. Binary tree
  2. Balanced tree
  3. Binary search tree
  4. AVL tree
    1. It likes a binary search tree. But the root of this tree changes when a new item is added.
    2. It speeds up searching with insertion and deletion(That means dynamic searching).
    3. If this tree is null, the height will be -1. An empty binary tree is height balanced. If T is a nonempty binary tree with TL and TR as its left and right subtrees, then T is height balanced if and only if.
    4. The balance factor BF(node) = hL- hR. In an AVL tree , BF(node) =-1, 0 ,or1. If it’s over 1, we call this node troublemaker.
    5. Therefor, if a tree has troublemaker, we can have single rotation,  RR/LL rotation, or RL/LR rotation. And several bf’s might be changed even if we don’t need to reconstruct the tree.
    6. The minimum number of nodes nh can be calculated as nh=Fh+2 -1 ,for h>=0. Or nh = n(h-1)+n(h-2)+1
    7. Some example
      1.       First step is an R rotation ,followed by an L rotation. The third step is another R rotation and finally an L rotation. 
      2.  

F(1) = 1

F(2)=F(1)+1

F(3)=F(1)+F(2)+1

```

F(7)=F(6)+F(5)+1

We already know height = depth + 1 and n(h) = n(h-1)+n(h-2)+1

package tree;

/**
 * @ClassName AVLTree
 * @Description AVLTree
 * @Author  
 * @Date 4/4/2023 9:55 AM
 * @Version 1.0
 */
public class AVLTree {

    class Node {
        int key;
        int height;
        Node left;
        Node right;

        Node() {
        }

        Node(int d) {
            key = d;
            height = 1;
        }
    }

    Node root;

    int getRootHeight() {
        if (root == null) {
            return 0;
        }
        return root.height;
    }

    int getHeight(Node target) {
        if (target == null) {
            return 0;
        }
        return target.height;
    }

    int max(int x, int y) {
        return x > y ? x : y;
    }

    // right rotate the subtree's root with target node
    Node rightRotate(Node target) {
        Node left = target.left;
        Node right = left.right;

        //perform rotate —— get a tree
        left.right = target;
        target.left = right;

        //update height
        target.height = max(getHeight(target.left), getHeight(target.right)) + 1;
        left.height = max(getHeight(left.left), getHeight(left.right)) + 1;

        // Return new root
        return left;
    }

    // left rotate subtree rooted with x
    Node leftRotate(Node x) {
        Node y = x.right;
        Node T2 = y.left;

        // Perform rotation
        y.left = x;
        x.right = T2;

        //  Update heights
        x.height = max(getHeight(x.left), getHeight(x.right)) + 1;
        y.height = max(getHeight(y.left), getHeight(y.right)) + 1;

        // Return new root
        return y;
    }

    // Get Balance factor of node N
    int getBalance(Node N) {
        if (N == null) {
            return 0;
        }
        return getHeight(N.left) - getHeight(N.right);
    }

    Node insert(Node node, int key) {

        /* 1.  Perform the normal BST insertion */
        if (node == null)
            return (new Node(key));

        if (key < node.key)
            node.left = insert(node.left, key);
        else if (key > node.key)
            node.right = insert(node.right, key);
        else // Duplicate keys not allowed
            return node;

        /* 2. Update height of this ancestor node */
        node.height = 1 + max(getHeight(node.left),
                getHeight(node.right));

        /* 3. Get the balance factor of this ancestor
              node to check whether this node became
              unbalanced */
        int balance = getBalance(node);

        // If this node becomes unbalanced, then there
        // are 4 cases Left Left Case
        if (balance > 1 && key < node.left.key)
            return rightRotate(node);

        // Right Right Case
        if (balance < -1 && key > node.right.key)
            return leftRotate(node);

        // Left Right Case
        if (balance > 1 && key > node.left.key) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }

        // Right Left Case
        if (balance < -1 && key < node.right.key) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }

        /* return the (unchanged) node pointer */
        return node;
    }

    // A utility function to print preorder traversal
    // of the tree.
    // The function also prints height of every node
    void preOrder(Node node) {
        if (node != null) {
            System.out.print(node.key + " ");
            preOrder(node.left);
            preOrder(node.right);
        }
    }

    public static void main(String[] args) {
        AVLTree tree = new AVLTree();

        /* Constructing tree given in the above figure */
        tree.root = tree.insert(tree.root, 10);
        tree.root = tree.insert(tree.root, 20);
        tree.root = tree.insert(tree.root, 30);
        tree.root = tree.insert(tree.root, 40);
        tree.root = tree.insert(tree.root, 50);
        tree.root = tree.insert(tree.root, 25);

        System.out.println("Preorder traversal" +
                " of constructed tree is : ");
        tree.preOrder(tree.root);
    }
}

}
  1. Splay tree
  2. Red-black tree
  3. B+ tree

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值