栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

二叉树(java)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二叉树(java)

二叉树 1、概念

    树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树。

    二叉树的子节点分为左节点和右节点。

    如果该二叉树的所有叶子节点都在最后一层,并且结点总数=2’n-1 , n为层数,则我们称为满二叉树。

    如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为完全二叉树。

    二、二叉树遍历的方法 1、递归遍历

      前序遍历

      //前序遍历---先头,左,右
      		public void preorder(ThreeNode threeNode) {
      	if (threeNode != null ) {
      		System.out.println(threeNode);  //头
      		if (threeNode.left != null) {
      			threeNode.left.preorder(threeNode.left);  //左
      		}
      		if (threeNode.right != null) {
      			threeNode.right.preorder(threeNode.right);  //右
      		}
      	}
      }
      

      中序遍历

      //中序遍历---先左,头,右
      		public void middleOrder(ThreeNode threeNode) {
      	if (threeNode != null ) {
      		if (threeNode.left != null) {
      			threeNode.left.middleOrder(threeNode.left);  //左
      		}
      		System.out.println(threeNode);
      		if (threeNode.right != null) {
      			threeNode.right.middleOrder(threeNode.right);  //右
      		}
      	}
      }
      

      后序遍历

      //后序遍历---先左右头
      		public void postOrder(ThreeNode threeNode) {
      	if (threeNode != null ) {
      		if (threeNode.left != null) {
      			threeNode.left.postOrder(threeNode.left);  //左
      		}
      		if (threeNode.right != null) {
      			threeNode.right.postOrder(threeNode.right);  //右
      		}
      		System.out.println(threeNode);
      	}
      }
      
2、非递归遍历

    先序遍历

    先准备一个栈

    将头结点压入栈

    每次从栈弹出一个节点cur----处理cur

    先右在左的将节点压入栈----周而复始的操作

 public void noPreorder(ThreeNode threeNode){
		if (threeNode !=null){
			Stack stack = new Stack<>();
			stack.add(threeNode);
			while (!stack.isEmpty()){
				threeNode = stack.pop();  //没弹出一个节点,都要判断一个有没有孩子
				System.out.println(threeNode);  //弹出栈
				if (threeNode.getRight() !=null){
					stack.push(threeNode.getRight());  //将左孩子压入栈
				}
				if (threeNode.getLeft() !=null){
					stack.push(threeNode.getLeft());  //将右孩子压入栈
				}
			}
			System.out.println();
		}
	}

    中序遍历

    先准备一个栈

    先将整棵树的左边全压入栈

    从栈中弹出一个元素并判断是否有右边—有的话将指针指向弹出的右边—在判断是否有右边和左边—没有的话弹出–周而复始

public void noMiddleOrder(ThreeNode threeNode) {
		if (threeNode != null) {
			Stack stack = new Stack<>();
//自己写的-------------------------------
//			while (threeNode != null) {
//				stack.push(threeNode);
//				threeNode = threeNode.getLeft();
//			}
//			while (!stack.isEmpty()) {
//				threeNode = stack.pop();
//				System.out.println(threeNode);
//				if (threeNode.getRight() != null) {
//					threeNode = threeNode.getRight();
//					while (threeNode != null) {
//						stack.push(threeNode);
//						threeNode = threeNode.getLeft();
//					}
//				}
//			}
//			System.out.println();
//		}
//	}

//网上的方法------------
			while (!stack.isEmpty() || threeNode !=null){
				if (threeNode !=null){
					stack.push(threeNode);
					threeNode = threeNode.getLeft();
				}else {
					threeNode = stack.pop();
					System.out.println(threeNode);
					threeNode = threeNode.getRight();
				}
			}
			System.out.println();
		}
	}

    后序遍历

    先准备两个栈

    入第一个栈的出栈顺序是先—头,右,左----所以压入第一个栈的顺序是–先:头,左,右

    第二个的入栈顺序是:头,右,左----这样出栈的顺序相反—左右头–>对应的是后序

public void noPostOrder(ThreeNode threeNode) {
		if (threeNode !=null) {
			Stack stack = new Stack<>();  //放入栈---弹出顺序为---头,右,左
			Stack stack1 = new Stack<>();  //收集栈---收集栈刚好相反---左,右,头
			stack.add(threeNode);
			while (!stack.isEmpty()){
				threeNode = stack.pop();
				stack1.push(threeNode);
				if (threeNode.getLeft() !=null){
					stack.push(threeNode.getLeft());
				}
				if (threeNode.getRight() !=null){
					stack.push(threeNode.getRight());
				}
			}
			while (!stack1.isEmpty()){
				System.out.println(stack1.pop());
			}
			System.out.println();
		}
	}

4、宽度优先遍历

先准备一个队列队列是先进先出的先放—头、左、右

//宽度优先遍历
public void witchOrder(ThreeNode threeNode){
		if (threeNode ==null){
			return ;
		}
		Queue queue = new linkedList<>();
		queue.add(threeNode);
		while (!queue.isEmpty()){
			ThreeNode cur = queue.poll();  //弹出并捕捉
			System.out.println(cur);   //打印
			if (cur.getLeft() !=null){
				queue.add(cur.getLeft());
			}
			if (cur.getRight() != null){
				queue.add(cur.getRight());
			}
		}
		System.out.println();
	}
三、二叉树的查找

-

1、先序遍历查找
//先序遍历查找
	//先找头--然后找左边---最后找右边
public ThreeNode preorderSearch(ThreeNode threeNode,int num1) {
		if (threeNode ==null) {
			return null;
		}
		if (threeNode.num == num1) {
			return threeNode;
		}
		ThreeNode threeNode2 = null;
		if (threeNode.left != null) {
			threeNode2 =  threeNode.left.preorderSearch(threeNode.left, num1);
		}
		if (threeNode2 !=null) {
			return threeNode2;
		}
		if (threeNode.right != null){
			threeNode2 =  threeNode.left.preorderSearch(threeNode.right, num1);
		}
			return threeNode2;
	}
2、中序查找
	//中序查找
	//先左---头---右
	public ThreeNode middleOrderSearch(ThreeNode threeNode,int num1) {
		if (threeNode ==null) {
			return null;
		}
		ThreeNode threeNode2 = null;
		if (threeNode.left !=null) {
			threeNode2 = threeNode.left.middleOrderSearch(threeNode.left, num1);
			
		}
		
		if (threeNode2 !=null) {
			return threeNode2;
		}
		if (threeNode.num == num1){
			return threeNode;
		}
		if (threeNode.right != null){
			threeNode2 =  threeNode.right.preorderSearch(threeNode.right, num1);
		}
			return threeNode2;
	}
3、后序查找
//后序查找
	//先--左右--再头
	public ThreeNode postOrderSearch(ThreeNode threeNode,int num1) {
		if (threeNode ==null) {
			return null;
		}
		ThreeNode threeNode2 = null;
		if (threeNode.left != null) {
			threeNode2 = threeNode.left.postOrderSearch(threeNode.left, num1);
		}
		if (threeNode2 !=null) {
			return threeNode2;
		}
		if (threeNode.right != null) {
			threeNode2 = threeNode.right.postOrderSearch(threeNode.right, num1);		
		}
		if (threeNode.num == num1) {
			return threeNode;
		}
		return threeNode2;
	}
四、二叉树的删除
//删除树的结点
	public ThreeNode deleteNode(ThreeNode threeNode,int num1) {
		ThreeNode threeNode2 = null;
		if (threeNode.left != null) {
			if (threeNode.left.num == num1) {   //判断左子是不是要删除的
				threeNode2 = threeNode.left;
				threeNode.left = null;
				return threeNode;
			}
		}
		if (threeNode.right != null) {
			if (threeNode.right.num == num1) { //判断右子是不是要删除的
				threeNode2 = threeNode.right;
				threeNode.right = null;
				return threeNode;
			}
			
		}
		if (threeNode2 == null) {     //一直不是时threeNode2 就会是一直为null---然后进行递归删除
			if (threeNode.left != null) {
				threeNode.left.deleteNode(threeNode.left, num1);
			}
			if (threeNode2 == null) {
				if (threeNode.right != null) {
					threeNode.right.deleteNode(threeNode.right, num1);
				}
			}
		}
		return threeNode;
	}
全部代码(遍历,查找,删除)
public class BinaryTreeTest {
	public static void main(String[] args) {
		//ThreeNode root = new ThreeNode();
		//root.create(root);
		ThreeNode root = new ThreeNode(1, "zzj");
		ThreeNode threeNode2 = new ThreeNode(2, "lmg");
		ThreeNode threeNode3 = new ThreeNode(3, "xxl");
		ThreeNode threeNode4 = new ThreeNode(4, "dyf");
		ThreeNode threeNode5 = new ThreeNode(5, "zhh");
		ThreeNode threeNode6 = new ThreeNode(6, "jcd");
		ThreeNode threeNode7 = new ThreeNode(7, "lwh");

		//手动生成数---后面使用递归生成
		root.setLeft(threeNode2);
		root.setRight(threeNode3);
		threeNode2.setLeft(threeNode4);
		threeNode2.setRight(threeNode5);
		threeNode3.setLeft(threeNode6);
		threeNode3.setRight(threeNode7);


		//遍历树
		System.out.println("前序");
		root.preorder(root);
		System.out.println("--------------------------------上递归下非递归");
		root.noPreorder(root);

		System.out.println("中序");
		root.middleOrder(root);
		System.out.println("--------------------------------上递归下非递归");
		root.noMiddleOrder(root);
		
		System.out.println("后序");
		root.postOrder(root);
		System.out.println("--------------------------------上递归下非递归");
		root.noPostOrder(root);

		System.out.println("宽度优先遍历");
		root.witchOrder(root);
		
		System.out.println("先序查找");
		System.out.println(root.preorderSearch(root, 2));
		
		System.out.println("中序查找");
		System.out.println(root.middleOrderSearch(root, 4));
		
		System.out.println("后序查找");
		System.out.println(root.postOrderSearch(root, 5));
		
		System.out.println("===============================================================");
		root.witchOrder(root);
		root.deleteNode(root, 6);
		System.out.println("===============================================================");
		root.witchOrder(root);
	}
}

//创建二叉树
//先创建颗树的节点
class ThreeNode{
	private int num;
	private String name;
	private ThreeNode left;  //构造器不赋值---初值为null
	private ThreeNode right;
	
	//构造器
	public ThreeNode() {

	}
	public ThreeNode(int num, String name) {
		this.num = num;
		this.name = name;
	}

	//提供get set方法

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public ThreeNode getLeft() {
		return left;
	}

	public void setLeft(ThreeNode left) {
		this.left = left;
	}

	public ThreeNode getRight() {
		return right;
	}

	public void setRight(ThreeNode right) {
		this.right = right;
	}

	//递归建立二叉树
	public ThreeNode create(ThreeNode threeNode){
		Scanner scanner = new Scanner(System.in);

		int num1 = scanner.nextInt();
		String name1 = scanner.nextLine();
		if (num !=0 && !name.equals("")) {
			threeNode.num = num1;
			threeNode.name = name1;
			//左枝,右枝
			threeNode.left = create(threeNode.left);
			threeNode.right = create(threeNode.right);
		}else{
			threeNode = null;
		}
		return threeNode;
	}

	//前序遍历---先头,左,右
		public void preorder(ThreeNode threeNode) {
			if (threeNode != null ) {
				System.out.println(threeNode);  //头
				if (threeNode.left != null) {
					threeNode.left.preorder(threeNode.left);  //左
				}
				if (threeNode.right != null) {
					threeNode.right.preorder(threeNode.right);  //右
				}
			}
		}
		
		//中序遍历---先左,头,右
		public void middleOrder(ThreeNode threeNode) {
			if (threeNode != null ) {
				if (threeNode.left != null) {
					threeNode.left.middleOrder(threeNode.left);  //左
				}
				System.out.println(threeNode);
				if (threeNode.right != null) {
					threeNode.right.middleOrder(threeNode.right);  //右
				}
			}
		}
		
		//后序遍历---先左右头
		public void postOrder(ThreeNode threeNode) {
			if (threeNode != null ) {
				if (threeNode.left != null) {
					threeNode.left.postOrder(threeNode.left);  //左
				}
				if (threeNode.right != null) {
					threeNode.right.postOrder(threeNode.right);  //右
				}
				System.out.println(threeNode);
			}
		}


		//无递归遍历----------------------------------------------------------
	//1. 先序遍历
	//   - 先准备一个栈
	//   - 将头结点压入栈
	//   - 每次从栈弹出一个节点cur----处理cur
	//   - 先右在左的将节点压入栈----周而复始的操作
	public void noPreorder(ThreeNode threeNode){
		if (threeNode !=null){
			Stack stack = new Stack<>();
			stack.add(threeNode);
			while (!stack.isEmpty()){
				threeNode = stack.pop();  //没弹出一个节点,都要判断一个有没有孩子
				System.out.println(threeNode);  //弹出栈
				if (threeNode.getRight() !=null){
					stack.push(threeNode.getRight());  //将左孩子压入栈
				}
				if (threeNode.getLeft() !=null){
					stack.push(threeNode.getLeft());  //将右孩子压入栈
				}
			}
			System.out.println();
		}
	}

	//中序非递归
	//- 先准备一个栈
	//- 先将整棵树的左边全压入栈
	//- 从栈中弹出一个元素并判断是否有右边---有的话将指针指向弹出的右边---在判断是否有右边和左边---没有的话弹出--周而复始
	public void noMiddleOrder(ThreeNode threeNode) {
		if (threeNode != null) {
			Stack stack = new Stack<>();
//自己写的-------------------------------
//			while (threeNode != null) {
//				stack.push(threeNode);
//				threeNode = threeNode.getLeft();
//			}
//			while (!stack.isEmpty()) {
//				threeNode = stack.pop();
//				System.out.println(threeNode);
//				if (threeNode.getRight() != null) {
//					threeNode = threeNode.getRight();
//					while (threeNode != null) {
//						stack.push(threeNode);
//						threeNode = threeNode.getLeft();
//					}
//				}
//			}
//			System.out.println();
//		}
//	}

//网上的方法------------
			while (!stack.isEmpty() || threeNode !=null){
				if (threeNode !=null){
					stack.push(threeNode);
					threeNode = threeNode.getLeft();
				}else {
					threeNode = stack.pop();
					System.out.println(threeNode);
					threeNode = threeNode.getRight();
				}
			}
			System.out.println();
		}
	}

	//后序非递归
	//- 先准备两个栈
	//- 入第一个栈的出栈顺序是先---头,右,左----所以压入第一个栈的顺序是--先:头,左,右
	//- 第二个的入栈顺序是:头,右,左----这样出栈的顺序相反---左右头-->对应的是后序
	public void noPostOrder(ThreeNode threeNode) {
		if (threeNode !=null) {
			Stack stack = new Stack<>();  //放入栈---弹出顺序为---头,右,左
			Stack stack1 = new Stack<>();  //收集栈---收集栈刚好相反---左,右,头
			stack.add(threeNode);
			while (!stack.isEmpty()){
				threeNode = stack.pop();
				stack1.push(threeNode);
				if (threeNode.getLeft() !=null){
					stack.push(threeNode.getLeft());
				}
				if (threeNode.getRight() !=null){
					stack.push(threeNode.getRight());
				}
			}
			while (!stack1.isEmpty()){
				System.out.println(stack1.pop());
			}
			System.out.println();
		}
	}

	//宽度优先遍历
	public void witchOrder(ThreeNode threeNode){
		if (threeNode ==null){
			return ;
		}
		Queue queue = new linkedList<>();
		queue.add(threeNode);
		while (!queue.isEmpty()){
			ThreeNode cur = queue.poll();  //弹出并捕捉
			System.out.println(cur);   //打印
			if (cur.getLeft() !=null){
				queue.add(cur.getLeft());
			}
			if (cur.getRight() != null){
				queue.add(cur.getRight());
			}
		}
		System.out.println();
	}
	
	
	//先序遍历查找
	//先找头--然后找左边---最后找右边
	public ThreeNode preorderSearch(ThreeNode threeNode,int num1) {
		if (threeNode ==null) {
			return null;
		}
		if (threeNode.num == num1) {
			return threeNode;
		}
		ThreeNode threeNode2 = null;
		if (threeNode.left != null) {
			threeNode2 =  threeNode.left.preorderSearch(threeNode.left, num1);
		}
		if (threeNode2 !=null) {
			return threeNode2;
		}
		if (threeNode.right != null){
			threeNode2 =  threeNode.left.preorderSearch(threeNode.right, num1);
		}
			return threeNode2;
	}
	
	
	//中序查找
	//先左---头---右
	public ThreeNode middleOrderSearch(ThreeNode threeNode,int num1) {
		if (threeNode ==null) {
			return null;
		}
		ThreeNode threeNode2 = null;
		if (threeNode.left !=null) {
			threeNode2 = threeNode.left.middleOrderSearch(threeNode.left, num1);
			
		}
		
		if (threeNode2 !=null) {
			return threeNode2;
		}
		if (threeNode.num == num1){
			return threeNode;
		}
		if (threeNode.right != null){
			threeNode2 =  threeNode.right.preorderSearch(threeNode.right, num1);
		}
			return threeNode2;
	}
	
	
	//后序查找
	//先--左右--再头
	public ThreeNode postOrderSearch(ThreeNode threeNode,int num1) {
		if (threeNode ==null) {
			return null;
		}
		ThreeNode threeNode2 = null;
		if (threeNode.left != null) {
			threeNode2 = threeNode.left.postOrderSearch(threeNode.left, num1);
		}
		if (threeNode2 !=null) {
			return threeNode2;
		}
		if (threeNode.right != null) {
			threeNode2 = threeNode.right.postOrderSearch(threeNode.right, num1);		
		}
		if (threeNode.num == num1) {
			return threeNode;
		}
		return threeNode2;
	}
	

	
	//删除树的结点
	public ThreeNode deleteNode(ThreeNode threeNode,int num1) {
		ThreeNode threeNode2 = null;
		if (threeNode.left != null) {
			if (threeNode.left.num == num1) {   //判断左子是不是要删除的
				threeNode2 = threeNode.left;
				threeNode.left = null;
				return threeNode;
			}
		}
		if (threeNode.right != null) {
			if (threeNode.right.num == num1) { //判断右子是不是要删除的
				threeNode2 = threeNode.right;
				threeNode.right = null;
				return threeNode;
			}
			
		}
		if (threeNode2 == null) {     //一直不是时threeNode2 就会是一直为null---然后进行递归删除
			if (threeNode.left != null) {
				threeNode.left.deleteNode(threeNode.left, num1);
			}
			if (threeNode2 == null) {
				if (threeNode.right != null) {
					threeNode.right.deleteNode(threeNode.right, num1);
				}
			}
		}
		return threeNode;
	}
	@Override
	public String toString() {
		return "ThreeNode{" +
				"num=" + num +
				", name='" + name + ''' +
				'}';
	}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/710903.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号