JAVA数据结构与算法(四)树

JAVA数据结构与算法(三)树

定义
树(Tree)是n(n≥0)个结点的有限集T,并且当n>0时满足下列条件:
(1)有且仅有一个特定的称为根(Root)的结点;
(2)当n>1时,其余结点可以划分为m(m>0)个互不相交的有限集T1、T2 、…、Tm,每个集Ti(1≤i≤m)均为树,且称为树T的子树(SubTree)。
特别地,不含任何结点(即n=0)的树,称为空树。
树的术语
1.结点:包含了数据项和指向其他结点的分支
2.结点的度:结点所拥有的子树棵树。例如上图中,B的度为1,C的度为2,D的度为3
3.叶结点&终端结点:即度为0的结点,例如上图中,F,G,H,I,J均为叶结点
4.分支结点&非终端结点:除了叶结点以外的其他结点

5.子女结点:若结点x有子树,则子树的根结点即为结点x的子女。例如上图中,A有两个子女,分别为B,C
6.父结点:若结点x有子女,它即为子女的父结点
7.根结点:没有父结点的结点称为根结点
8.兄弟结点:同一父结点的子女互称为兄弟。例如上图中,D,E,F互为兄弟
9.祖先结点:从根结点到该结点所经历分支上的所有结点。例如上图中,G的祖先结点为A,B,D
10.子孙结点:某一结点的子女,以及这些子女的子女都是该结点的子孙。例如上图中,结点B的子孙D,G
11.结点所处的层次:从根到该结点所经路径上的分支条数.根结点在第1层,它的子女在第二层。树中任一12.结点的层次为它的父结点的层次加1。结点所处层次亦称为结点的深度
13.树的高度:叶结点的高度为1,非叶结点的高度等于它子女结点高度的最大值加1。该树的高度为4

14.树的度:树中结点的度的最大值。例如上图中该树的高度为3
树的存储与表示
顺序存储:将数据结构存储在固定的数组中,然在遍历速度上有一定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储
JAVA数据结构与算法(四)树_第1张图片
JAVA数据结构与算法(四)树_第2张图片
链式存储
JAVA数据结构与算法(四)树_第3张图片
常见的一些树的应用场景
1.xml,html等,那么编写这些东西的解析器的时候,不可避免用到树
2.路由协议就是使用了树的算法
3.mysql数据库索引
4.文件系统的目录结构
5.所以很多经典的AI算法其实都是树搜索,此外机器学习中的decision tree也是树结构

创建一颗树

class TreeNode{
	int data;
	TreeNode leftChild;
	TreeNode rightChild;
}

省略get set方法
树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次,我们把这种对所有节点的访问称为遍历(traversal)。
那么树的两种重要的遍历模式是 深度优先遍历和广度优先遍历, 深度优先一般用 递归 ,广度优先一般用 队列 。一般情况下能用递归实现的算法大部分也能用堆栈来实现。

深度优先遍历
1.1 对于一颗二叉树,深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。这三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)
先序遍历
在先序遍历中,我们先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树
根节点->左子树->右子树

	public static void preOrder(Node head){
		if(head==null){
			return;
		}
		System.out.println(head.getData()+" ");
		preOrder(head.leftChild);
		preOrder(head.rightChild);
	}

中序遍历
在中序遍历中,我们递归使用中序遍历访问左子树,然后访问根节点,最后再递归使用中序遍历访问右子树
左子树->根节点->右子树

public static void  inOrder(Node head){
		if(head==null){
			return;
		}
		preOrder(head.leftChild);
		System.out.println(head.getData()+" ");
		preOrder(head.rightChild);
	}

后序遍历
在后序遍历中,我们先递归使用后序遍历访问左子树和右子树,最后访问根节点
左子树->右子树->根节点

	public static void  posOrder(Node head){
		if(head==null){
			return;
		}
		preOrder(head.leftChild);
		preOrder(head.rightChild);
		System.out.println(head.getData()+" ");
	}

广度优先遍历
从树的root开始,从上到下从从左到右遍历整个树的节点

public void levelOrderTraversal(Node node){
      if(node==null){
            System.out.print("empty tree"); 
            return;
      }
      ArrayList<Integer> lists=new ArrayList<Integer>();
      Queue<Node> queue=new LinkedList<Node>();
      queue.offer(node);
      while(!queue.isEmpty()){
    	  Node tree=queue.poll();
          if(tree.leftChild!=null){
              queue.offer(tree.leftChild);
          }
          if(tree.rightChild!=null){
              queue.offer(tree.rightChild);
          }
          lists.add((Integer) tree.data);
      }
  }

你可能感兴趣的:(数据结构与算法)