数据结构之二叉树原理和实现

1. 二叉树的概念
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
** 二叉树的递归遍历**
在这里插入图片描述

  • 前序遍历:先输出父节点,再遍历左子树和右子树
    (1)先输出当前节点,初始的时候是root节点
    (2)如果当前左子树不为空,则递归继续前序遍历
    (3)如果当前右子树不为空,则递归继续前序遍历
    结果:1->2->3->5->4

  • 中序遍历:先遍历左子树,再输出父节点,最后遍历右子树
    (1)如果当前左子树不为空,则递归继续中序遍历
    (2)输出当前节点
    (3)如果当前右子树不为空,则递归继续中序遍历
    结果:2->1->5->3->4

  • 后序遍历:先遍历左子树,再遍历右子树,最后输出父节点
    (1)如果当前左子树不为空,则递归继续后序遍历
    (2)如果当前右子树不为空,则递归继续中序遍历
    (3)输出当前节点
    结果:2->5->4->3->1

  • 源代码:

	package Tree;
	import java.util.Arrays;
	public class BinarlyTree {
	public static void main(String[] args) {
		//创建二叉树,并加入节点
		BinTree bt = new BinTree();
		HeroNode ND1 = new HeroNode(1,"宋江");
		HeroNode ND2 = new HeroNode(2,"吴用");
		HeroNode ND3 = new HeroNode(3,"卢俊义");
		HeroNode ND4 = new HeroNode(4,"林冲");
		HeroNode ND5 = new HeroNode(5,"关胜");
		bt.setRoot(ND1);
		ND1.setLeft(ND2);
		ND1.setRight(ND3);
		ND3.setLeft(ND5);
		ND3.setRight(ND4);
		//前序遍历测试1-》2-》3—》4
		System.out.println("前序遍历结果:");
		bt.PretOrder();
		//中序遍历测试2-》1-》3—》4
		System.out.println("中序遍历结果:");
		bt.MidtOrder();
		//后序遍历测试2-》4-》3—》1
		System.out.println("后序遍历结果:");
		bt.LasttOrder();	
	}
}
	//创建树,定义跟节点及遍历方法
class BinTree{
		private HeroNode root;
		public void setRoot(HeroNode root) {
			this.root = root;
		}
		//树的前序遍历,先输出root节点,然后是左子树,最后是右子树
		public void PretOrder() {
			if(this.root!=null) {
				this.root.PreOrder();
			}else {
				System.out.println("二叉树为空");
			}
		}
		//树的中序遍历,先输出左子树,然后是root节点,最后是右子树
		public void MidtOrder() {
			if(this.root!=null) {
				this.root.MidOrder();
			}else {
				System.out.println("二叉树为空");
			}
		}
	
		//树的后序遍历,先输出左子树,然后是右子树,最后是root节点,
		public void LasttOrder() {
			if(this.root!=null) {
				this.root.LastOrder();
			}else {
				System.out.println("二叉树为空");
			}
		}
	 }	
	//创建树节点
class HeroNode {
		public int id;
		public String name;
		HeroNode left; //默认为空
		HeroNode right;
		public HeroNode(int id, String name) {
			super();
			this.id = id;
			this.name = name;
		}
		public int getId() {
			return id;
		}
		public void setId(int id) {
			this.id = id;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public HeroNode getLeft() {
			return left;
		}
		public void setLeft(HeroNode left) {
			this.left = left;
		}
		public HeroNode getRight() {
			return right;
		}
		public void setRight(HeroNode right) {
			this.right = right;
		}
		@Override
		public String toString() {
			return "HeroNode [id=" + id + ", name=" + name + "]";
		}
		//树的前序遍历,先输出root节点,然后是左子树,最后是右子树
		public void PreOrder() {
			System.out.println(this); //谁调用就指向谁
			if(this.left!=null) {
				this.left.PreOrder();
			}
			if(this.right!=null) {
				this.right.PreOrder();
			}	
		}
		//树的中序遍历,先输出左子树,然后是root节点,最后是右子树
				public void MidOrder() {
					if(this.left!=null) {
						this.left.MidOrder();
					}
					System.out.println(this); //谁调用就指向谁
					if(this.right!=null) {
						this.right.MidOrder();
					}	
				}
				//树的后序遍历,先输出左子树,然后是右子树,最后是root节点,
				public void LastOrder() {
					if(this.left!=null) {
						this.left.LastOrder();
					}
					if(this.right!=null) {
						this.right.LastOrder();
					}	
					System.out.println(this); //谁调用就指向谁
				}					
	}

  • 测试结果:
    在这里插入图片描述
    二叉树节点的查找
			//树节点的前序查找
					public HeroNode PretSearch(int id) {
						//首先判断当前节点是不是匹配
						if(root != null) {
							return root.PreSearch(id);
						}else {
							return null;
						}
					}
					//树节点的中序查找
					public HeroNode MidtSearch(int id) {
						//首先判断当前节点是不是合适
						if(root != null) {
							return root.MidSearch(id);
						}else {
								return null;
							}
					}
					//树节点的后序查找
					public HeroNode LattSearch(int id) {
								//首先判断当前节点是不是合适
						if(root != null) {
							return root.LatSearch(id);
						}else {
								return null;
								}
					}	

           //树的节点查找,根据编号大小分别进行前序、中序、后序查找
				//前序查找
				public HeroNode PreSearch(int id) {
					//首先判断当前节点是不是合适
					if(this.id == id) {
						return this;
					}
					//如果没有找到,则向左子树进行查找
					HeroNode temp = null; //方便结果的返回
					//先判断左子树为不为空
					if(this.left!=null) {
						//不为空的话则递归前序遍历查找,
						temp = this.left.PreSearch(id);
						
					 }
					//判断在左子树是否找到,找到返回结束遍历
					if(temp!=null) {
						return temp;
					}
					//如果左子树中没有找到,则遍历右子树
					if(this.right!=null) {
						//不为空的话则递归前序遍历查找,
						temp = this.right.PreSearch(id);
					}
					//无论找到与否,返回当前temp才知道,
					return temp;		
				}
		//中序查找节点
				public HeroNode MidSearch(int id) {
					HeroNode temp = null; //方便结果的返回
					//首先遍历当前节点的左子树节点
					//先判断左子树为不为空
					if(this.left!=null) {
						//有元素的话则递归中序遍历查找,
						temp = this.left.MidSearch(id);	
					 }
					//判断在左子树是否找到,找到返回结束遍历
					if(temp!=null) {
						return temp;
					}
					//其次查找当前节点是否匹配
					if(this.id == id) {
						return this;
					}
					//如果没有找到,则遍历右子树
					if(this.right!=null) {
						//不为空的话则递归前序遍历查找,
						temp = this.right.MidSearch(id);
					}
					//无论找到与否,返回当前temp才知道,
					return temp;		
				}
		 //后序查找节点
				public HeroNode LatSearch(int id) {
					HeroNode temp = null; //方便结果的返回
					//首先遍历当前节点的左子树节点
					//先判断左子树为不为空
					if(this.left!=null) {
						//有元素的话则递归中序遍历查找,
						temp = this.left.LatSearch(id);	
					 }
					//判断在左子树是否找到,找到返回结束遍历
					if(temp!=null) {
						return temp;
					}
					//如果左子树没有找到,则遍历右子树
					if(this.right!=null) {
						//不为空的话则递归前序遍历查找,
						temp = this.right.LatSearch(id);
					}
					//判断在右子树是否找到,找到返回结束遍历
					if(temp!=null) {
						return temp;
					}
					//最后在当前节点进行查找
					if(this.id==id) {
						return this;
					}
					return temp; //未找到就返回空
				}					

二叉树节点的删除
在这里插入图片描述
代码:

			//节点的删除
					public void DeleteNode(int id) {
						//首先是判断树为不为空
						if(root!=null) {
							//判断当前root节点符不符合
							if(root.getId()==id) {
								root = null;
							 }else {
								root.Delete(id);
							}
						}else {
							System.out.println("此树为空");
						}
					}
			//在node中的delete方法
			//按编号删除节点,每次需要遍历到该节点的子节点才能删除操作
							public void Delete(int id) {
						//首先是判断树为不为空,其次判断当前root节点符不符合,在Tree删除中完成
								//1.判断左子树符不符合要删除的节点
								if(this.left!=null && this.left.id==id) {
									this.left = null;
									return;
								}
								//2.判断右子树符不符合要删除的节点
								if(this.right!=null &&this.right.id==id) {
									this.right = null;
									return;
								}
								//均未找到,则继续遍历递归删除
								//3.左子树递归删除
								if(this.left!=null) {
									this.left.Delete(id);
								}
								//4.右子树递归删除
								if(this.right!=null) {
									this.right.Delete(id);
								}
							}

顺序存储二叉树

  • 在堆排序中会用到顺序存储二叉树
    在这里插入图片描述
    在这里插入图片描述
  • 代码:数组 arr = {1,2,3,4,5,6,7},前序遍历则为{1,2,4,5,3,6,7}
				package Tree;
				//顺序存储二叉树,用数组方式实现
				public class ArrayTree {
					static int[]arr = {1,2,3,4,5,6,7};
					public static void main(String[] args) {
						PreOreder(0);
				 
					}
				   public static void PreOreder(int index) {
					   if( arr==null||arr.length==0) {
						   System.out.println("数组为空");
					   }
					   System.out.print(arr[index]+" ");//打印当前节点
					   //遍历父节点的左边子树节点,其数组下标关系为2*n+1
					   if(index*2+1<arr.length) {
						   PreOreder(index*2+1);
					   }
					  //遍历父节点的右边子树节点,其数组下标关系为2*n+2
					   if(index*2+2<arr.length) {
						   PreOreder(index*2+2);
					   }
				   }
				}
  • 测试结果:
    在这里插入图片描述
    线索化二叉树
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值