树的应用 —— 二叉树的创建

如果想要对二叉树进行操作,必须先创建一棵二叉树。

如何创建一棵二叉树呢?从二叉树的定义就可以看出,它是递归定义的(除了根,左、右子树也各是一棵二叉树),因此也可以用递归程序来创建二叉树。

递归创建二叉树有两种方法:询问法和补空法。

【1 询问法】

按照先序遍历【根左右】的顺序,每次输入节点信息后,都询问是否创建该节点的左子树,如果是,则递归创建其左子树,否则其左子树为空;询问是否创建该节点的右子树,如果是,则递归创建其右子树,否则其右子树为空。

[算法步骤]

  1. 输入节点信息,创建一个节点T。
  2. 询问是否创建T的左子树,如果是,则递归创建其左子树,否则其左子树为NULL。
  3. 询问是否创建T的右子树,如果是,则递归创建其右子树,否则其右子树为NULL。

[完美图解]

一棵二叉树如下图所示。

多叉树查找 java 多叉树建立_多叉树查找 java

该二叉树的创建过程如下:

  1. 输入节点信息:A。创建节点A,如下图所示。
  2. 多叉树查找 java 多叉树建立_多叉树查找 java_02

  3. 是否添加A的左孩子? (Y/N):Y。
  4. 输入节点信息:B。创建节点B,作为A的左孩子,如下图所示。
  5. 多叉树查找 java 多叉树建立_子树_03

  6. 是否添加B的左孩子? (Y/N):Y。
  7. 输入节点信息:D。创建节点D,作为B的左孩子,如下图所示。
  8. 多叉树查找 java 多叉树建立_c++_04

  9. 是否添加D的左孩子? (Y/N):N。
  10. 是否添加D的右孩子? (Y/N):N。D左右孩子均为空,如下图所示。
  11. 多叉树查找 java 多叉树建立_数据结构_05

  12. 是否添加B的右孩子? (Y/N):Y。
  13. 输入节点信息:E。创建节点E,作为B的右孩子,如下图所示。
  14. 多叉树查找 java 多叉树建立_算法_06

  15. 是否添加E的左孩子? (Y/N):N
  16. 是否添加E的右孩子? (Y/N):N。E左右孩子均为空,如下图所示。
  17. 多叉树查找 java 多叉树建立_算法_07

  18. 是否添加A的右孩子? (Y/N):Y。
  19. 输入节点信息:C。创建节点C,作为A的右孩子,如下图所示。
  20. 多叉树查找 java 多叉树建立_子树_08

  21. 是否添加C的左孩子? (Y/N):Y。
  22. 输入节点信息:F。创建节点F,作为C的左孩子,如下图所示。
  23. 多叉树查找 java 多叉树建立_算法_09

  24. 是否添加F的左孩子? (Y/N):N。F的左孩子为空。
  25. 是否添加F的右孩子? (Y/N):Y。
  26. 输入节点信息:G。创建节点G,作为F的右孩子,如下图所示。
  27. 多叉树查找 java 多叉树建立_算法_10

  28. 是否添加G的左孩子? (Y/N):N
  29. 是否添加G的右孩子? (Y/N):N。G左右孩子均为空,如下图所示。
  30. 多叉树查找 java 多叉树建立_数据结构_11

  31. 是否添加C的右孩子? (Y/N):N。C右孩子为空,如下图所示。

多叉树查找 java 多叉树建立_子树_12

  1. 二叉树创建完毕。

[算法代码]

void createtree(Btree &T){ //创建二叉树函数(询问法)
	char check;  //判断是否创建左右孩子
	T = new Bnode;
	cout << "请输入节点信息:" << endl;  //输入根节点数据
	cin >> T->data;
	cout << "是否添加" << T->data << "的左孩子?(Y/N)" << endl; //询问创建T的左子树
	cin >> check;
	if(check == 'Y'){
		createtree(T->lchild);
	}
	else{
		T->lchild = NULL;
	}
	cout << "是否添加" << T->data << "的右孩子?(Y/N)" << endl; //询问创建T的右子树
	cin >> check;
	if(check == 'Y'){
		createtree(T->rchild);
	}
	else{
		T->rchild = NULL;
	}
}

【补空法】

补空法指如果左子树或右子树为空,则用特殊字符补空,例如“#”。

然后按照先序遍历的顺序,得到先序遍历序列,根据该序列递归创建二叉树。

[算法步骤]

  1. 输入补空后的二叉树先序遍历序列。
  2. 如果ch==‘#’,则T=NULL;否则创建一个新节点T,令T->data=ch;递归创建T的左子树;递归创建T的右子树。

[完美图解]

一棵二叉树,将该二叉树补空,在孩子为空时补上特殊符号“#”,如下图所示。

多叉树查找 java 多叉树建立_数据结构_13


二叉树补空后的先序遍历结果为ABD##E##CF#G###。【根左右】

该二叉树的创建过程如下。

  1. 读取先序序列的第1个字符“A”,创建一个新节点,如下图所示。然后递归创建A的左子树。
  2. 多叉树查找 java 多叉树建立_c++_14

  3. 读取先序序列的第2个字符“B”,创建一个新节点,作为A的左子树,如下图所示。然后递归创建B的左子树。
  4. 多叉树查找 java 多叉树建立_多叉树查找 java_15

  5. 读取先序序列的第3个字符“D”,创建一个新节点,作为B的左子树,如下图所示。然后递归创建D的左子树。
  6. 多叉树查找 java 多叉树建立_子树_16

  7. 读取先序序列的第4个字符“#”,说明D的左子树为空,如下图所示。然后递归创建D的右子树。
  8. 多叉树查找 java 多叉树建立_算法_17

  9. 读取先序序列的第5个字符“#”,说明D的右子树为空,如下图所示。然后递归创建B的右子树。
  10. 多叉树查找 java 多叉树建立_多叉树查找 java_18

  11. 读取先序序列的第6个字符“E”,创建一个新节点,作为B的右子树,如下图所示。然后递归创建E的左子树。
  12. 多叉树查找 java 多叉树建立_子树_19

  13. 读取先序序列的第7个字符“#”,说明E的左子树为空,如下图所示。然后递归创建E的右子树。
  14. 多叉树查找 java 多叉树建立_算法_20

  15. 读取先序序列的第8个字符“#”,说明E的右子树为空,如下图所示。然后递归创建A的右子树。
  16. 多叉树查找 java 多叉树建立_多叉树查找 java_21

  17. 读取先序序列的第9个字符“C”,创建一个新节点,作为A的右子树,如下图所示。然后递归创建C的左子树。
  18. 多叉树查找 java 多叉树建立_算法_22

  19. 读取先序序列的第10个字符“F”,创建一个新节点,作为C的左子树,如下图所示。然后递归创建F的左子树。
  20. 多叉树查找 java 多叉树建立_数据结构_23

  21. 读取先序序列的第11个字符“#”,说明F的左子树为空,如下图所示。然后递归创建F的右子树。
  22. 多叉树查找 java 多叉树建立_多叉树查找 java_24

  23. 读取先序序列的第12个字符“G”,创建一个新节点,作为F的右子树,如下图所示。然后递归创建G的左子树。
  24. 多叉树查找 java 多叉树建立_多叉树查找 java_25

  25. 读取先序序列的第13个字符“#”,说明G的左子树为空,如下图所示。然后递归创建G的右子树。
  26. 多叉树查找 java 多叉树建立_子树_26

  27. 读取先序序列的第14个字符“#”,说明G的右子树为空,如下图所示。然后递归创建C的右子树。
  28. 多叉树查找 java 多叉树建立_子树_27

  29. 读取先序序列的第15个字符“#”,说明C的右子树为空,如下图所示。序列读取完毕,二叉树创建成功。

多叉树查找 java 多叉树建立_算法_28

[算法代码]

void Createtree(Btree &T){ //创建二叉树函数(补空法)
	char ch;
	cin >> ch; //二叉树补空后,按先序遍历序列输入字符
	if(ch == '#'){
		T = NULL; //建空树
	}
	else{
		T = new Bnode;
		T-> data = ch; //生成根节点
		Createtree(T->lchild); //递归创建左子树
		Createtree(T->rchild); //递归创建右子树
	}
}