Data Structure and Algorithm-Basic Tree Theory & Binary Tree

Let’s take a look at the following structures: Except for one structure in the picture below, the rest are not trees. We can find out whether this is very similar to the trees in our real life.

There are several important terms in the tree structure:

1. Node: The element in the tree.

2. Father-child relationship: edges connecting nodes

3. Subtree: When a node is greater than 1, the remaining nodes are divided into disjoint sets called subtrees.

4. Degree: The number of subtrees owned by a node is called the degree of the node.

5. Leaf: a node with degree 0

6. Children: The root of a node’s subtree is called a child node.

7. Parents: corresponding to the child node

8. Brother: the same parent node

9. Forest: A deep forest is composed of N mutually disjoint trees

There are several important terms in the tree structure:

Node height: the longest path from the node to the leaf node

The depth of the node: the number of edges from the root node to the node

The number of layers of the node: the depth of the node plus 1

Tree height: the height of the root node

Common binary trees : balanced binary tree, binary search tree, red-black tree, complete binary tree: (heap sort; big top heap, small top heap) full binary tree

Common N-ary tree : B tree (B-Tree, B+Tree)

The most important tree structure is the binary tree. Many classic algorithms and data structures are actually developed through binary trees.        

        Binary Tree : A special tree structure, each node has at most two subtrees.

        There are at most 2^(N-1) nodes on the Nth level of the binary tree. There are at most 2^N-1 nodes.

        Full binary tree : Except for leaf nodes, each node has two left and right child nodes.

        Complete binary tree : Except for the last level, the number of other nodes must reach the maximum, and the nodes of the last level must be arranged continuously to the left.

think? Why are we divided into full binary trees and complete binary trees? Because it can be seen from the definition that a complete binary tree is only a subset of a full binary tree

To understand the above problem, we need to start with the storage of tree structure:

        Array-based storage: use array subscripts. Suppose A is i, then B=2*i, C=2*i+1, and so on. But if it is the second picture below, what will happen if it is stored in an array?

        Answer: You will find that if you use an array to store it, a lot of space will be wasted. What should you do? The first thing that everyone thinks of must be a linked list. Yes, it needs to be implemented by using a linked list, but the performance of arrays is efficient and there is no need to open additional pointers, so if it is a complete binary tree, we can use arrays to implement it . , because array subscripts can be used to correspond to nodes, as shown in the figure above. If it is not a complete binary tree, if the left leaf is missing and there is only the right leaf, array storage will waste space. This is also the fundamental reason why it is necessary to divide a complete binary tree . Later heaps will also look at this structure.

Four traversal methods: 

        Important tips: Root node output! subtree

        Preposition: root left right

        Middle sequence: left root right BDCAEHGKF

        Prediction: Left Right Root DCBHKGFEA

Note: Each traversal starts from the root node, and then treats the area below the root as a subtree, and then traverses according to the formula root output. Just hit the root output!

code implementation tree

package tree;

class MyTreeNode{
	
	private char data;
	private MyTreeNode left;
	private MyTreeNode right;

	public MyTreeNode(char data, MyTreeNode left, MyTreeNode right) {
		super();
		this.setData(data);
		this.setLeft(left);
		this.setRight(right);
	}
	public char getData() {
		return data;
	}
	public void setData(char data) {
		this.data = data;
	}
	public MyTreeNode getLeft() {
		return left;
	}
	public void setLeft(MyTreeNode left) {
		this.left = left;
	}
	public MyTreeNode getRight() {
		return right;
	}
	public void setRight(MyTreeNode right) {
		this.right = right;
	}
	
}

public class BinaryTree {
	
	public static void main(String[] args) {
		MyTreeNode D = new MyTreeNode('D', null, null);
		MyTreeNode H = new MyTreeNode('H', null, null);
		MyTreeNode K = new MyTreeNode('K', null, null);
		MyTreeNode C = new MyTreeNode('C', D, null);
		MyTreeNode G = new MyTreeNode('G', H, K);
		MyTreeNode B = new MyTreeNode('B', null, C);
		MyTreeNode F = new MyTreeNode('F', G, null);
		MyTreeNode E = new MyTreeNode('E', null, F);
		MyTreeNode A = new MyTreeNode('A', B, E);
		
		BinaryTree binaryTree = new BinaryTree();
		System.out.println("前");
		binaryTree.pre(A);
		System.out.println();
		System.out.println("中");
		binaryTree.in(A);
		System.out.println();
		System.out.println("后");
		binaryTree.post(A);
		
	}
	
	public void print(MyTreeNode node){
		System.out.print(node.getData());
	}
	
	public void pre(MyTreeNode root){		//前序遍历 根(输出) 左 右 时间复杂度?O(n) N^2 O(2*n)=>O(n);
		print(root);
		if(root.getLeft() != null){
			pre(root.getLeft());	//认为是子树,分解子问题;
		}
		if(root.getRight() != null){
			pre(root.getRight());
		}
	}
	
	public void in(MyTreeNode root){		//中序遍历  左 根(输出)  右
		if(root.getLeft() != null){
			in(root.getLeft());	//认为是子树,分解子问题;
		}
		print(root);
		if(root.getRight() != null){
			in(root.getRight());
		}
	}
	
	public void post(MyTreeNode root){		//后序遍历  左  右 根(输出) 
		if(root.getLeft() != null){
			post(root.getLeft());	//认为是子树,分解子问题;
		}
		if(root.getRight() != null){
			post(root.getRight());
		}
		print(root);
	}
}

Guess you like

Origin blog.csdn.net/qq_67801847/article/details/132766068