二叉树(一)——二叉树的构造及三种遍历算法的递归实现(java版)

来源:互联网 发布:java中super关键字 编辑:程序博客网 时间:2024/05/24 08:33

二叉树主要有顺序存储结构和链式存储结构两种,在本文中采取链式存储结构进行实现。
二叉树的的链式存储结构是指用一个链表来存储一颗二叉树,二叉树中每一个结点用链表中的一个链结点来存储。在二叉树中,标准村粗方式的结点结构如下:
这里写图片描述
其中,data表示数据域,用于存储对应的数据元素,lchild和rchild分别表示左指针域和右指针域。用于分别存储左孩子结点和右孩子结点,通常将这种链式存储结构称为二叉链。
由于在java语言中没有指针的概念,因此对这种链式存储形式,以以下形式进行定义,首先定义结点类:

class TreeNode<T>{    private T data = null;//数据部分    private TreeNode leftChild;//左孩子结点    private TreeNode rightChild;//右孩子结点    public TreeNode(){    }    public TreeNode(T data){        this.data = data;    }    public TreeNode(T data,TreeNode leftChild,TreeNode rightChild){        this.data = data;        this.leftChild = leftChild;        this.rightChild = rightChild;    }    //获取数据    public T getData(){        return data;    }    //修改数据    public void setData(T data){        this.data = data;    }    //获取左孩子结点    public TreeNode getLeftChild(){        return leftChild;    }    //修改左孩子结点    public void setLeftChild(TreeNode leftChild){        this.leftChild = leftChild;    }    //获取右孩子结点    public TreeNode getRightChild(){        return rightChild;    }    //修改右孩子结点    public void setRightChild(TreeNode rightChild){        this.rightChild = rightChild;    }}

构造如下图所示二叉树:
这里写图片描述
在该方法中,对二叉树的构造是利用在实例化一个对象时,对其进行构造,主函数中对二叉树的构造代码如下:

TreeNode<String> right12 = new TreeNode<String>("G", null, null);TreeNode<String> left1 = new TreeNode<String>("D", null, right12);TreeNode<String> left2 = new TreeNode<String>("E", null, null);TreeNode<String> right2 = new TreeNode<String>("F", null, null);TreeNode<String> left = new TreeNode<String>("B", left1, null);// 根节点左子树TreeNode<String> right = new TreeNode<String>("C", left2, right2);// 根节点右子树TreeNode<String> root = new TreeNode<String>("A", left,right);// 创建根节点

接下来,对二叉树进行先序、中序、后序遍历。在这三种遍历算法中,采取递归的方法,具体实现代码如下:

/*先序遍历递归算法*/public void preOrder(TreeNode node){    if (node != null){          System.out.println(node.getData());          preOrder(node.getLeftChild());          preOrder(node.getRightChild());    }}/*中序遍历递归算法*/public void inOrder(TreeNode node){    if(node != null){         inOrder(node.getLeftChild());         System.out.println(node.getData());         inOrder(node.getRightChild());    }}/*后序遍历递归算法*/public void postOrder(TreeNode node){    if(node != null){        postOrder(node.getLeftChild());        postOrder(node.getRightChild());        System.out.println(node.getData());    }}

对于先序遍历的递归算法,执行过程如下:
这里写图片描述
最后的打印顺序为:ABDGCEF
由于先序、中序、后序三者遍历的递归算法有类似之处,因此不一一给出每个递归算法的执行流程。
总结:
三种遍历算法中递归遍历左、右子树的顺序都是固定的,只是访问根结点的顺序不同。不管采用哪种遍历算法,每个结点都访问一次且仅访问一次,故时间复杂度都是O(n)。在递归遍历中,递归工作栈的栈深恰好为树的深度,所以在最坏的情况下,二叉树是有n个结点且深度为n的单支树,遍历算法的空间复杂度为O(n)。

0 0