这里介绍二叉树的先序遍历、中序遍历以及后序遍历算法,这三种遍历方式的主要区别在于:父节点的输出顺序,父节点的输出顺序决定了使用那种遍历算法。
// 前序遍历
public void preOrder(){
System.out.println(this); // 输出当前节点
if (this.left!=null) { //打印左子树
this.left.preOrder();
}
if (this.right!=null) { //打印右子树
this.right.preOrder();
}
}
// 中序遍历
public void middleOrder(){
if (this.left!=null){
this.left.middleOrder();
}
System.out.println(this);
if (this.right!=null){
this.right.middleOrder();
}
}
// 后序遍历
public void postOrder(){
if (this.left!=null){
this.left.postOrder();
}
if (this.right!=null){
this.right.postOrder();
}
System.out.println(this);
}
查找方式依据使用的遍历方式的不同可分为:先序遍历查找、中序遍历查找和后序遍历查找。
此处代码编写我的需求是查依据雇员的姓名进行查找,也就是依据节点的name属性查找。
// 前序查找
public EmployeeNode preOrderSearch(String name){
System.out.println("进入前序遍历");
if (this.getName().equals(name)){ // 比较当前节点
return this;
}
EmployeeNode tempNode=null;
if(this.getLeft()!=null){ // 左子树递归查找
tempNode= this.getLeft().preOrderSearch(name);
}
if (tempNode!=null){ // 判断左子树是否找到
return tempNode;
}
if(this.getRight()!=null){ // 右子树递归查找
tempNode= this.getRight().preOrderSearch(name);
}
return tempNode;
}
// 中序查找
public EmployeeNode middleOrderSearch(String name){
EmployeeNode tempNode=null;
if (this.getLeft()!=null){ //左子树递归查找
tempNode=this.getLeft().middleOrderSearch(name);
}
if (tempNode!=null){ // 说明左子树已经找到
return tempNode;
}
System.out.println("进入中序遍历");
if (this.getName().equals(name)){ //比较当前节点
return this;
}
if (this.getRight()!=null){ //右子树递归查找
tempNode=this.getRight().middleOrderSearch(name);
}
return tempNode;
}
// 后序查找
public EmployeeNode postOrderSearch(String name){
EmployeeNode tempNode=null;
if (this.getLeft()!=null){ //左子树递归查找
tempNode=this.getLeft().postOrderSearch(name);
}
if (tempNode!=null){ // 说明左子树已经找到
return tempNode;
}
if (this.getRight()!=null){ //右子树递归查找
tempNode=this.getRight().postOrderSearch(name);
}
if (tempNode!=null){ // 说明右子树已经找到
return tempNode;
}
System.out.println("进入后序遍历");
if (this.getName().equals(name)){ //比较当前节点
return this;
}
return tempNode;
}
普通二叉树是没有顺序规则可言的,只要当前节点最多只有两个子节点的树就称为二叉树,所以在删除时对于子树调整的规则也没有很严格,这里先简单认识一下如何删除满足删除条件的叶节点或者删除此节点为根节点的子树。此处使用的二叉树是单向二叉树,通过子节点是无法回溯到父节点的,所以我们在进行删除操作时只能判断某节点的子节点是否是需要删除的节点。
// 删除操作
public void delete(String name){
if(this.left!=null && this.left.getName().equals(name)){ // 判断当前节点的左节点是否满足删除条件
this.left=null;
return;
}
if(this.right!=null && this.right.getName().equals(name)){ // 判断当前节点的右节点是否满足删除条件
this.right=null;
return;
}
if (this.left!=null ){ // 进行左节点递归删除
this.left.delete(name);
}
if(this.right!=null){ // 进行右节点递归删除
this.left.delete(name);
}
}
package com.north.tree;
// 二叉树相关内容
public class BinaryTreeDemo {
public static void main(String[] args){
System.out.println("Hello BinaryTree.");
BinaryTree tree=new BinaryTree();
EmployeeNode root = new EmployeeNode(1, "杨俊荣");
EmployeeNode node2 = new EmployeeNode(2, "周杰伦");
EmployeeNode node3 = new EmployeeNode(3, "方文山");
EmployeeNode node4 = new EmployeeNode(4, "浪花兄弟");
EmployeeNode node5 = new EmployeeNode(5, "南拳妈妈");
root.setLeft(node2);
root.setRight(node3);
node2.setLeft(node4);
node2.setRight(node5);
tree.setRoot(root);
String name="杨俊荣";
// 删除
System.out.println("删除前,前序遍历:");
tree.preOrder();
tree.delete(name);
System.out.println("删除后,前序遍历:");
tree.preOrder();
// 遍历
// tree.preOrder();
// System.out.println("---------------------------------------------");
// tree.middleOrder();
// System.out.println("---------------------------------------------");
// tree.postOrder();
// System.out.println("---------------------------------------------");
// 查找
// EmployeeNode searchResult=tree.preOrderSearch(name);
// System.out.println(tree.preOrderSearch(name));
// System.out.println(tree.preOrderSearch("周杰伦"));
// System.out.println(tree.preOrderSearch("方文山"));
// System.out.println(tree.preOrderSearch("杨俊荣"));
// System.out.println(tree.preOrderSearch("浪花兄弟"));
// System.out.println(tree.middleOrderSearch(name));
// System.out.println(tree.postOrderSearch(name));
}
}
// 构建二叉树
class BinaryTree{
private EmployeeNode root;
public void setRoot(EmployeeNode root) {
this.root = root;
}
// 前序遍历
public void preOrder(){
if (this.root!=null){
this.root.preOrder();
}else{
System.out.println("二叉树为空,无法遍历!");
}
}
// 中序遍历
public void middleOrder(){
if (this.root!=null){
this.root.middleOrder();
}else{
System.out.println("二叉树为空,无法遍历!");
}
}
// 后序遍历
public void postOrder(){
if (this.root!=null){
this.root.postOrder();
}else{
System.out.println("二叉树为空,无法遍历!");
}
}
// 前序查找
public EmployeeNode preOrderSearch(String name){
if (this.root!=null){
return this.root.preOrderSearch(name);
}else {
return null;
}
}
// 中序查找
public EmployeeNode middleOrderSearch(String name){
if (this.root!=null){
return this.root.middleOrderSearch(name);
}else {
return null;
}
}
// 后序查找
public EmployeeNode postOrderSearch(String name){
if (this.root!=null){
return this.root.postOrderSearch(name);
}else {
return null;
}
}
// 删除
public void delete(String name){
if(this.root!=null){
if(this.root.getName().equals(name)) {
this.root = null;
}else {
this.root.delete(name);
}
} else{
System.out.println("二叉树为空,无法删除!");
}
}
}
// 构建树节点
class EmployeeNode{
private int number;
private String name;
private EmployeeNode left;
private EmployeeNode right;
// 构造器
public EmployeeNode(int number, String name) {
this.number = number;
this.name = name;
}
// get、set方法
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EmployeeNode getLeft() {
return left;
}
public void setLeft(EmployeeNode left) {
this.left = left;
}
public EmployeeNode getRight() {
return right;
}
public void setRight(EmployeeNode right) {
this.right = right;
}
// 重写toString 方法
@Override
public String toString() {
return "EmployeeNode{" +
"number=" + number +
", name='" + name + '\'' +
'}';
}
// 前序遍历
public void preOrder(){
System.out.println(this); // 输出当前节点
if (this.left!=null) { //打印左子树
this.left.preOrder();
}
if (this.right!=null) { //打印右子树
this.right.preOrder();
}
}
// 中序遍历
public void middleOrder(){
if (this.left!=null){
this.left.middleOrder();
}
System.out.println(this);
if (this.right!=null){
this.right.middleOrder();
}
}
// 后序遍历
public void postOrder(){
if (this.left!=null){
this.left.postOrder();
}
if (this.right!=null){
this.right.postOrder();
}
System.out.println(this);
}
// 前序查找
public EmployeeNode preOrderSearch(String name){
System.out.println("进入前序遍历");
if (this.getName().equals(name)){ // 比较当前节点
return this;
}
EmployeeNode tempNode=null;
if(this.getLeft()!=null){ // 左子树递归查找
tempNode= this.getLeft().preOrderSearch(name);
}
if (tempNode!=null){ // 判断左子树是否找到
return tempNode;
}
if(this.getRight()!=null){ // 右子树递归查找
tempNode= this.getRight().preOrderSearch(name);
}
return tempNode;
}
// 中序查找
public EmployeeNode middleOrderSearch(String name){
EmployeeNode tempNode=null;
if (this.getLeft()!=null){ //左子树递归查找
tempNode=this.getLeft().middleOrderSearch(name);
}
if (tempNode!=null){ // 说明左子树已经找到
return tempNode;
}
System.out.println("进入中序遍历");
if (this.getName().equals(name)){ //比较当前节点
return this;
}
if (this.getRight()!=null){ //右子树递归查找
tempNode=this.getRight().middleOrderSearch(name);
}
return tempNode;
}
// 后序查找
public EmployeeNode postOrderSearch(String name){
EmployeeNode tempNode=null;
if (this.getLeft()!=null){ //左子树递归查找
tempNode=this.getLeft().postOrderSearch(name);
}
if (tempNode!=null){ // 说明左子树已经找到
return tempNode;
}
if (this.getRight()!=null){ //右子树递归查找
tempNode=this.getRight().postOrderSearch(name);
}
if (tempNode!=null){ // 说明右子树已经找到
return tempNode;
}
System.out.println("进入后序遍历");
if (this.getName().equals(name)){ //比较当前节点
return this;
}
return tempNode;
}
// 删除操作
public void delete(String name){
if(this.left!=null && this.left.getName().equals(name)){
this.left=null;
return;
}
if(this.right!=null && this.right.getName().equals(name)){
this.right=null;
return;
}
if (this.left!=null ){
this.left.delete(name);
}
if(this.right!=null){
this.left.delete(name);
}
}
}