倒霉的菜鸟

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

什么是树? 

树是n(n>=0)个结点的有限集。n=0时称为空树,在任意一棵非空树中,有且仅有一个特定的称为根(root)的结点, 当n>1时,其余结点可分为m个互不相交的有限集。 下图中第一张图就不是树, 因为d和e相交

 

 

树的存储结构?

树的存储结构一般有4种,

1)双亲表示法,就是在每个节点中标示出它的父节点

 

 

 2)孩子表示法,每个节点携带指针位指向自己的孩子

 

 

 这种方法中,每个节点除了数据域外,还要额外携带m个指针位(m为树的度)

3)双亲孩子表示法

 

 

 4),孩子兄弟表示法

 

 

 二叉树?

度<=2的树称为二叉树

二叉树的存储结构?

1)顺序存储

 

 

 2, 链式存储(使用孩子表示法)

 

 

 二叉树的遍历?

1)前序遍历(DLR), 规则是:若二叉树为空,则空操作返回,否则先访问根节点,然后前序遍历左子树,再前序遍历右子树

 

 

 代码实现:

 1 public class BinaryTree<E>{
 2     /**
 3      * 节点内部类
 4      * 这里我们用孩子表示法
 5      * 因此需要定义一个数据域和两个指针域
 6      */
 7     class Node<E>{
 8         private E data;
 9         private Node<E> leftChild;
10         private Node<E> rightChild;
11         
12         public Node(E data, Node<E> leftChild, Node<E> rightChild) {
13             this.data = data;
14             this.leftChild = leftChild;
15             this.rightChild = rightChild;
16         }
17     }
18     
19     //root节点
20     Node<E> root;
21 
22     /**
23      * 为了便于测试,我们在构造方法里生成一颗二叉树
24      * @param root
25      */
26     public BinaryTree(E root) {
27         this.root = new Node(root, null, null);
28         createBinaryTree();
29     }
30     
31     /**
32      * 创建一颗二叉树
33      */
34     private void createBinaryTree() {
35         //创建节点
36         Node<E> nodeB = new Node("B",null, null );
37         Node<E> nodeC = new Node("C",null, null );
38         Node<E> nodeD = new Node("D",null, null );
39         Node<E> nodeE = new Node("E",null, null );
40         Node<E> nodeF = new Node("F",null, null );
41         Node<E> nodeG = new Node("G",null, null );
42         Node<E> nodeH = new Node("H",null, null );
43         Node<E> nodeI = new Node("I",null, null );
44         //声明节点间的关系,来构建树
45         root.leftChild = nodeB;
46         root.rightChild = nodeC;
47         nodeB.leftChild = nodeD;
48         nodeD.leftChild = nodeG;
49         nodeD.rightChild = nodeH;
50         nodeC.leftChild = nodeE;
51         nodeC.rightChild = nodeF;
52         nodeE.rightChild = nodeI;
53     }
54     
55     /**
56      * 二叉树的前序遍历
57      * @param tree
58      */
59     public void preErgodic(Node<E> root) {
60         //如果二叉树为空,则空操作返回
61         if(root == null) {
62             return;
63         }else {
64             //否则先访问根节点
65             System.out.println(root.data.toString());
66             //再前序访问左子树
67             preErgodic(root.leftChild);
68             //再前序访问右子树
69             preErgodic(root.rightChild);
70         }
71     }
72 }

测试代码 

1 public static void main(String[] args) {
2         BinaryTree tree = new BinaryTree("A");
3         tree.preErgodic(tree.root);
4     }

输出结果:

 

 

 2)相对于前序遍历(DLR)来说, 中序遍历(LDR)就是先访问左子树,再访问中间节点,再访问右子树

 1 public void middleErgodic(Node<E> root) {
 2         //如果二叉树为空,则空操作返回
 3         if(root == null) {
 4             return;
 5         }else {
 6             //否则从根节点开始,先访问左子树
 7             middleErgodic(root.leftChild);
 8             //再访问根节点
 9             System.out.print(root.data.toString() + " ");
10             //再访问右子树
11             middleErgodic(root.rightChild);
12         }
13     }

输出结果:

 

 

 3)后续遍历(LRD)


 1 public void endErgodic(Node<E> root) {
 2         //如果二叉树为空,则空操作返回
 3         if(root == null) {
 4             return;
 5         }else {
 6             //否则从根节点开始,先访问左子树
 7             endErgodic(root.leftChild);
 8             //再访问右子树
 9             endErgodic(root.rightChild);
10             //再访问根节点
11             System.out.print(root.data.toString() + " ");
12         }
13     }

输出结果

 

 小结: 所谓前序后序中序其实就是 访问根节点是在访问左右节点的前面、后面还是中间

 

posted on 2021-10-08 10:35  倒霉的菜鸟  阅读(81)  评论(0编辑  收藏  举报