0
点赞
收藏
分享

微信扫一扫

数据结构---与树相关的知识

古月无语 2022-03-12 阅读 40

与树有关的一系列知识: 树,二叉树,满二叉树,完全二叉树,文章还没完,我会后序补充的

有些图是网上找的,没有自己画

一: 树(了解就行)

1.1 概念

1.2 一些与树相关的重要概念

节点的度: 一个节点含有子树的个数称为该节点的度
比如:上图中节点A的度为2,节点D的度为3.

树的度: 一颗树中,所有节点度的最大值称为树的度
比如:上图中树的度为3

叶子节点或终端节点: 度为0的节点称为叶子节点或者终端节点
比如:上图中的叶子节点有:F,G,H,I,J.

双亲节点或父节点: 如果一个节点含有子节点,这个节点就称为子节点的父节点或者双亲节点.
比如:上图中的A是B,C的父节点.

孩子节点或子节点: 一个节点含有的子树的根节点称为该节点的子节点.
比如:上图中的B,C是A的孩子节点.

根节点: 树种没有双亲的节点.(位于食物链顶端的节点)
比如:上图中的A节点.

节点的层次: 从根开始定义起,根为第一层,根的子节点为第二层,依次类推

树的高度或深度: 树中节点的最大层次.
比如:上图中树的深度为4

非终端节点或分支节点: 度不为0的节点
比如:上图中的B,D节点

兄弟节点: 具有相同父节点的节点称为兄弟节点
比如:上图中的G,H,I节点

堂兄弟节点: 双亲在同一层的节点互为堂兄弟
比如:上图中的D,E节点

节点的祖先: 从根节点到该节点所经分支上的所有节点
比如:G节点的祖先节点是A,B,D节点.而A节点是所有节点的祖先节点.

子孙节点: 以某节点为根的子树中任一节点都称为该节点的子孙.
比如:上图中D节点的子孙节点是G,H,I.而所有节点都是A的子孙节点.

森林: 有m(m>0)棵互不相交的树组成的集合称为森林.

1.3 树的表示形式

树有很多种表现形式,但是最常用的是这里的孩子兄弟表示法
a.双亲表示法

class Node{
	int value;		//存储的数据
	Node parent;	//指向父节点
}

b.孩子表示法

class Node{
	int value;		//存储的数据
	Node left;		//指向左孩子,常常代表左孩子为根的整棵左子树
	Node right;		//指向右孩子,常常代表右孩子为根的整棵右子树
}

c.孩子双亲表示法

class Node{
	int value;		//存储的数据
	Node left;		//指向左孩子,常常代表左孩子为根的整棵左子树
	Node right;		//指向右孩子,常常代表右孩子为根的整棵右子树
	Node parent;	//当前节点的父节点.
}

d.孩子兄弟表示法

class Node{
	int value;			//树中存储的数据
	Node firstChild;	//第一个孩子的引用
	Node nextBrother;	//下一个兄弟的引用
}

二: 二叉树(非常重要,重点掌握)

2.1 概念

满足: 1.为空树时,是二叉树 2.由根节点+左子树+右子树组成.

注意: 对于任意的二叉树都是由以下集中情况复合而成的.
在这里插入图片描述

2.2 两种特殊的二叉树

2.2.1 满二叉树

2.2.2 完全二叉树

完全二叉树是由满二叉树引出来的.满二叉树是一种特殊的完全二叉树.

设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到饱和(即1~h-1层为一个满二叉树),第 h 层所有的结点都从左往右依次排列,这样的树就是完全二叉树。

2.3 二叉树的性质

2.4 二叉树的基本操作

2.4.1手动快速创建一棵简单的二叉树

这段代码并不是创建二叉树的方式,真正创建二叉树方法后序会重点讲解.

//孩子表示法来表示二叉树.
public class BinaryTree{
	public static class BTNode{
		BTNode left;	//引用当前孩子的左孩子
		BTNode right;   //引用当前孩子的右孩子
		int value;		//值域
		//有参构造方法
		BTNode(int value){
			this.value = value;
		}
	}
	private BTNode root;	//二叉树的根节点
	public void createBinaryTree(){
		BTNode node1 = new BTNode(1);	//创建节点node1,它的值为1
		BTNode node1 = new BTNode(2);
		BTNode node1 = new BTNode(3);
		BTNode node1 = new BTNode(4);
		BTNode node1 = new BTNode(5);
		BTNode node1 = new BTNode(6);
		root = node1;		    //根节点就是node1节点
		node1.left = node2;		//node1的左孩子是node2
		node1.right = node4;	//node1的右孩子是node4
		node2.left = node3;		//node2的左孩子是node3
		node4.left = node5;		//node4的左孩子是node5
		node4.right = node6;	//node5的右孩子是node6
	}
}

由以上代码创建出来的二叉树为下图所示:

2.4.2 二叉树的遍历

a. 前中后序遍历(递归操作)

学习二叉树结构,最简单的方式就是遍历.

指的是对节点中的值域进行打印.
NLR:前序遍历----------------根节点---->根的左子树---->根的右子树
1–>2–>3–>4–>5–>6

public void preOrder(BtNode reeRoot){
	//先判断是否为空
	if(treeRoot==null){
		return;
	}
	//1.先遍历根节点
	System.out.print(treeRoot.value+" ");
	//2.再遍历根节点的左子树----->根节点的左子树也是二叉树(遍历根的左子树与遍历原树的规则相同)
	preOrder(treeRoot.left);		//递归遍历根的左子树
	//3.最后遍历根节点的右子树----->根的右子树也是二叉树(遍历根的右子树与遍历原树的规则相同)
	preOrder(treeRoot.right);	//递归遍历根的右子树
}

LNR:中序遍历----------------根的左子树---->根节点---->根的右子树
3–>2–>1–>5–>4–>6

public void inOrder(BtNode reeRoot){
	if(treeRoot==null){
		return;
	}
	inOrder(treeRoot.left);		
	System.out.print(treeRoot.value+" ");
	inOrder(treeRoot.right);	
}

LRN:后序遍历----------------根的左子树---->根的右子树---->根节点
3–>2–>5–>6–>4–>1

public void postOrder(BtNode reeRoot){
	if(treeRoot==null){
		return;
	}
	postOrder(treeRoot.left);		
	postOrder(treeRoot.right);	
	System.out.print(treeRoot.value+" ");
}

b. 前中后序遍历(非递归)

前序遍历

public List<Integer> preorderTraversal(TreeNode root) {
     List<Integer> list=new ArrayList<>();
     Stack<TreeNode> s=new Stack<>();
     TreeNode cur=root;
     s.push(cur);
     while(!s.empty()){
         cur=s.pop();
         while(cur!=null){
              list.add(cur.val);
              if(cur.right!=null){
                  s.push(cur.right);
              }
              cur=cur.left;
         }
     }
     return list;
}

中序遍历

public List<Integer> inorderTraversal(TreeNode root) {
      List<Integer> list=new ArrayList<>();
      if(root==null){
          return list;
      }
      TreeNode cur=root;
      Stack<TreeNode> s=new Stack<>();
      while(!s.empty()||cur!=null){
          while(cur!=null){
              s.push(cur);
              cur=cur.left;
          }
          cur=s.pop();
          list.add(cur.val);
          cur=cur.right;
      }
      return list;
}

后序遍历

public List<Integer> postorderTraversal(TreeNode root) {
      List<Integer> list=new ArrayList<>();
      if(root==null){
          return list;
      }
      TreeNode cur=root;
      TreeNode prev=null;
      Stack<TreeNode> s=new Stack<>();
      while(!s.empty()||cur!=null){
          while(cur!=null){
              s.push(cur);
              cur=cur.left;
          }
          TreeNode top=s.peek();
          if(top.right==null || top.right==prev){
              list.add(top.val);
              prev=top;
              s.pop();
          }else{
              cur=top.right;
          }
      }
      return list;
 }

c. 层次遍历

比如上图经过层次遍历的结果就是:1--->2--->4--->3--->5--->6.

2.4.3 还原二叉树

a.通过前序和中序的结果还原二叉树

还原思想:

来看个例题:

题解:

b.通过中序和后序的结果还原二叉树

还原思想:

来看个例题:

题解:

c.通过层次遍历的结果还原二叉树.

这个相对来说就很简单了,自上而下,自左向右进行还原就行.
比如层次遍历结果是abcde,还原二叉树.
我们直接给出图形就行:

2.4.4 二叉树的基本操作方法

方法名作用
int size(Node root)获取树中节点的个数
int getLeafNodeCount(Node root)获取叶子节点的个数
int getLevelNodeCount(Node root)获取第k层节点的个数
int getHeight(Node root)获取二叉树的高度
Node find(Node root,int value)检测值为value的元素是否存在
boolean is CompleteTree(Node root)判断一棵树是不是完全二叉树
举报

相关推荐

0 条评论