数据结构--树

Posted 菜鸟_Admin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--树相关的知识,希望对你有一定的参考价值。

无论是链表,栈还是队列,它们都是线性结构的,每个节点的左边最多一个节点,右边也最多一个节点,对于大量的输入数据,线性表的访问时间太慢,不宜使用。这里我要说一种非线性的数据结构,其大部分操作的运行时间平均为O(logn)。

我们涉及到的这种数据结构叫做树。在计算机科学中,树是非常有用的抽象概念。我们形象的去描述一棵树,一个家族的老祖可能有两个儿子,这两个儿子一个有一个儿子,一个有三个儿子,像这样发展下去的一个族谱,就是一个树。下面是常见的一种树:二叉树。

 

本文中以二叉树为例,将二叉树的数据结构定义,深度计算,几种遍历方式进行JAVA编码实现。

1.二叉树的数据结构

public class BinaryTreeNode {
    private int data;
    private BinaryTreeNode leftNode;
    private BinaryTreeNode rightNode;

}

 

2.深度计算,二叉树的深度计算通过其本身的结构特性可进行递归。

public static int getDepth(BinaryTreeNode treeNode) {
if (treeNode == null) {
return 0;
}
int data=treeNode.getData();
System.out.println(data);
int left = getDepth(treeNode.getLeftNode());
int right = getDepth(treeNode.getRightNode());
int depth = Math.max(left, right) + 1;
return depth;
}

3.二叉树的遍历:前,中,后续。广度优先。

/**
     * 广度优先遍历
     * @param treeNode
     */
    public static void visitBreadth(BinaryTreeNode treeNode)
    {
        Deque<BinaryTreeNode> queueList =new ArrayDeque<BinaryTreeNode>();
        queueList.add(treeNode);
        while (queueList.size()!=0) {
            BinaryTreeNode currNode=queueList.peekFirst();
            System.out.println(currNode.getData());
            if (currNode.getLeftNode()!=null) {
                queueList.add(currNode.getLeftNode());
            }
            if (currNode.getRightNode()!=null) {
                queueList.add(currNode.getRightNode());
            }
            queueList.removeFirst();
        }
    }
    
    //前序遍历  
    public void preOrder(BinaryTreeNode subTree){  
        if(subTree!=null){  
            System.out.println(subTree.getData());
            postOrder(subTree.getLeftNode());  
            postOrder(subTree.getRightNode()); 
        }  
    }  
      
    //中序遍历  
    public void inOrder(BinaryTreeNode subTree){  
        if(subTree!=null){  
             postOrder(subTree.getLeftNode());  
             System.out.println(subTree.getData());
             postOrder(subTree.getRightNode());  
        }  
    }  
      
    //后续遍历  
    public void postOrder(BinaryTreeNode subTree) {  
        if (subTree != null) {  
            postOrder(subTree.getLeftNode());  
            postOrder(subTree.getRightNode());  
            System.out.println(subTree.getData());
        }  
    }  

4.测试

public static void main(String[] args) {
        BinaryTreeNode rootNode=new BinaryTreeNode(1);
        rootNode.setLeftNode(new BinaryTreeNode(2));
        rootNode.setRightNode(new BinaryTreeNode(3));
        rootNode.getRightNode().setRightNode(new BinaryTreeNode(5));
        rootNode.getRightNode().setLeftNode(new BinaryTreeNode(4));
        rootNode.getRightNode().getLeftNode().setLeftNode(new BinaryTreeNode(6));
        rootNode.getRightNode().getLeftNode().setRightNode(new BinaryTreeNode(7));
        /*int depth=getDepth(rootNode);
        System.out.println(depth);*/
        visitBreadth(rootNode);
    }

广度优先遍历结果:1 2 3 4 5 6 7

 

5.关于广度优先遍历

 

 广度优先遍历各个节点,需要使用到队列(Queue)这种数据结构,queue的特点是先进先出,其实也可以使用双端队列,区别就是双端队列首位都可以插入和弹出节点。整个遍历过程如下:

      首先将A节点插入队列中,queue(A);

      将A节点弹出,同时将A的子节点B,C插入队列中,此时B在队列首,C在队列尾部,queue(B,C);

      将B节点弹出,同时将B的子节点D,E插入队列中,此时C在队列首,E在队列尾部,queue(C,D,E);

      将C节点弹出,同时将C的子节点F,G,H插入队列中,此时D在队列首,H在队列尾部,queue(D,E,F,G,H);

      将D节点弹出,D没有子节点,此时E在队列首,H在队列尾部,queue(E,F,G,H);

直到遍历完成。需要借助一个双向队列作为辅助空间存在。

以上是关于数据结构--树的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中绘制回归树

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

使用 Apollo 客户端的片段组合:约定和样板

Discord.py 如何制作干净的对话树?

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构