2.6 树和二叉树

树是什么

​ 线性结构中,一个节点至多只有一个头节点,至多只有一个尾节点,彼此连接起来是一条完整的线。

比如链表和数组;

​ 而树,非线性结构的典型例子,不再是一对一,而变成了一对多(而图则可以是 多对多),树如下图所示:

基本概念

如下图:

  • 根节点 :A
  • 父节点 : A是B、C的父节点;B是D、E的父节点;C是F的父节点
  • 兄弟节点 : B、C互为兄弟节点(有共同的父节点A);DE互为兄弟节点(有共同的父节点B);F没有兄弟节点
  • 子节点(孩子):B、C是A的子节点;D、E是B的子节点;F是C的子节点
  • 叶子节点:D、E、F没有子节点,所以它们是叶子节点
  • 层 : A是第一层 ; B、C是第二层; D、E、F是第三层
  • 深度(高度):最大层数就是深度,所以深度为 3

二叉树

二叉树中,每个结点最多有两个分支,即每个结点最多有两个子结点,分别称作左子结点和右子结点。

满二叉树

定义为除了叶子结点外,所有结点都有 2 个子结点。如下图:

完全二叉树

定义为除了最后一层以外,其他层的结点个数都达到最大,并且最后一层的叶子结点都靠左排列。如下图:

树的基本操作

  • 前序遍历:对树中的任意结点来说,先打印这个结点,然后前序遍历它的左子树,最后前序遍历它的右子树。
  • 中序遍历,对树中的任意结点来说,先中序遍历它的左子树,然后打印这个结点,最后中序遍历它的右子树。
  • 后序遍历,对树中的任意结点来说,先后序遍历它的左子树,然后后序遍历它的右子树,最后打印它本身。

二叉查找树(二叉搜索树)

  • 在二叉查找树中的任意一个结点,其左子树中的每个结点的值,都要小于这个结点的值。
  • 在二叉查找树中的任意一个结点,其右子树中每个结点的值,都要大于这个结点的值。
  • 在二叉查找树中,会尽可能规避两个结点数值相等的情况。
  • 对二叉查找树进行中序遍历,就可以输出一个从小到大的有序数据队列。

例题

给定一棵树,按照层次顺序遍历并打印这棵树。例如:

则打印 20、17、22、12、19、26、24、18。请注意,这并不是前序遍历

解:

import java.util.LinkedList;

public class TreeTest {

	public static void main(String[] args) {

		Node<Integer> node = new Node<Integer>(20,
				new Node<Integer>(17, new Node<Integer>(12, null, null), new Node<Integer>(19, null, null)),
				new Node<Integer>(22, null,
						new Node<Integer>(26, new Node<Integer>(24, null, null), new Node<Integer>(18, null, null))));

		//
		levelTraverse(node);
	}

	/**
	 * 核心思路 队列
	 * 
	 * -->入队的顺序 是从第一层开始,由左至右进行
	 * 
	 * @param root
	 */
	public static void levelTraverse(Node root) {

		if (root == null) {

			return;

		}

		LinkedList<Node> queue = new LinkedList<Node>();

		Node current = null;

		queue.offer(root); // 根节点入队

		while (!queue.isEmpty()) { // 只要队列中有元素,就可以一直执行,非常巧妙地利用了队列的特性

			current = queue.poll(); // 出队队头元素

			System.out.print(" " + current.data);

			// 左子树不为空,入队

			if (current.left != null)

				queue.offer(current.left);

			// 右子树不为空,入队

			if (current.right != null)

				queue.offer(current.right);

		}

	}

	static class Node<T> {
		T data;
		Node left;
		Node right;

		public Node() {
		}

		public Node(T data, Node left, Node right) {
			this.data = data;
			this.left = left;
			this.right = right;
		}

		public T getData() {
			return data;
		}

		public void setData(T data) {
			this.data = data;
		}

		public Node getLeft() {
			return left;
		}

		public void setLeft(Node left) {
			this.left = left;
		}

		public Node getRight() {
			return right;
		}

		public void setRight(Node right) {
			this.right = right;
		}

	}
}

posted @ 2020-10-24 11:32  Nixon  阅读(91)  评论(0编辑  收藏  举报