排序二叉树

排序二叉树

简介

二叉树的定义,不再介绍;而排序二叉树指的是根据一定排列顺序插入节点组成的一个二叉树;而排列顺序一般指定:小的在左边、大的在右边,数值不重复

算法实现

主要包含有节点的插入、遍历、查询、删除。

定义节点类

private class Node {
		//节点的值
		private Integer key; 
		//左节点
		private Node left;
		//右节点
		private Node right;
		
		public Node() {
			super();
		}
		public Node(Integer key) {
			super();
			this.key = key;
		}
		public Integer getKey() {
			return key;
		}
		public Node setKey(Integer key) {
			this.key = key;
			return this;
		}
		public Node getLeft() {
			return left;
		}
		public Node setLeft(Node left) {
			this.left = left;
			return this;
		}
		public Node getRight() {
			return right;
		}
		public Node setRight(Node right) {
			this.right = right;
			return this;
		}
		@Override
		public String toString() {
			return "Node [key=" + key + ", left=" + left + ", right=" + right + "]";
		}
		
	}

插入节点

    /**
	 * 插入节点(封装对外)
	 * @author Kellan_Song
	 * @param key 节点值
	 */
	public static Node insert(Node tree, int key) {
		if (tree == null) {
			tree = new Node(key);
		} else {
			insertNode(tree, new Node(key));
		}
		return tree;
	}
	
    /**
	 * 在排序二叉树中插入节点(内部调用)
	 * @author Kellan_Song
	 * @param node 节点树
	 * @param new_node 新节点
	 */
	private static void insertNode(Node node, Node new_node) {
		//新节点小于父节点,放左边
		if (new_node.getKey() < node.getKey()) {
			if (node.getLeft() != null) {
				insertNode(node.getLeft(), new_node);
			} else {
				node.setLeft(new_node);
			}
		} 
		//新节点大于父节点
		if (new_node.getKey() > node.getKey()) { 
			if (node.getRight() != null) {
				insertNode(node.getRight(), new_node);
			} else {
				node.setRight(new_node);
			}
		}
	}

遍历

二叉树的遍历主要有三种:

  • 前序遍历:中间节点优先输出,再输出左节点,最后输出右节点;
  • 中序遍历:左节点 - 中间节点 - 右节点
  • 后序遍历:左节点 - 右节点 - 中间节点
    /**
	 * 前序遍历:指的是中间节点优先输出
	 * @author Kellan_Song
	 * @param node
	 */
	private static void before_print(Node node) {
		if (node != null) {
			System.out.print(" " + node.getKey());
			before_print(node.getLeft());
			before_print(node.getRight());
		}
	}
	
	/**
	 * 中序遍历:指的是左节点优先输出后,再输出中间节点,右节点最后输出
	 * @author Kellan_Song
	 * @param node
	 */
	private static void mid_print(Node node) {
		if (node != null) {
			mid_print(node.getLeft());
			System.out.print(" " + node.getKey());
			mid_print(node.getRight());
		}
	}
	
	/**
	 * 后序遍历:指的是 左节点优先输出,再输出右节点,中间节点最后输出
	 * @author Kellan_Song
	 * @param node
	 */
	private static void after_print(Node node) {
		if (node != null) {
			after_print(node.getLeft());
			after_print(node.getRight());
			System.out.print(" " + node.getKey());
		}
	}

最大值、最小值

    /**
	 * 获取二叉树中最小值
	 * @author Kellan_Song
	 * @param tree
	 * @return
	 */
	public static Integer minNum(Node tree) {
		Node node = lastLeft(tree);
		return node == null ? null : node.getKey();
	}
	/**
	 * 获取二叉树中最大值
	 * @author Kellan_Song
	 * @param tree
	 * @return
	 */
	public static Integer maxNum(Node tree) {
		Node node = lastRight(tree);
		return node == null ? null : node.getKey();
	}
    /**
	 * 获取最左节点
	 * @author Kellan_Song
	 * @param node
	 * @return
	 */
	private static Node lastLeft(Node node) {
		return node == null ? null : node.getLeft() != null ? lastLeft(node.getLeft()) : node;
	}
	
	/**
	 * 获取最右节点
	 * @author Kellan_Song
	 * @param node
	 * @return
	 */
	private static Node lastRight(Node node) {
		return node == null ? null : node.getRight() != null ? lastRight(node.getRight()) : node;
	}

查询

    /**
	 * 查询是否包含某值
	 * @author Kellan_Song
	 * @param node 排序二叉树
	 * @param n 查询值
	 * @return
	 */
	public static boolean contain(Node node, int n) {
		if (node == null) return false;
		if (node.getKey() < n) {
			return contain(node.getRight(), n);
		} else if (node.getKey() > n) {
			return contain(node.getLeft(), n);
		} else {
			return true; 
		}
	}

删除节点

删除节点分三种情况:

  • 删除节点为叶子节点(无左右节点):直接移除
  • 删除节点只有左节点或者只有右节点:则将存在的左节点\右节点指向于删除节点
  • 删除节点既有左节点,又有右节点:这种情况比较复杂,无法直接赋值,有两种方式(1)删除目标节点的左节点下的最右节点,并赋值于目标节点;(2)删除目标节点的右节点下的最左节点,并赋值于目标节点。
public static Node removeNode(Node node, int n) {
		if (node != null) {
			if (node.getKey() < n) {
				node.setRight(removeNode(node.getRight(), n));
			} else if (node.getKey() > n) {
				node.setLeft(removeNode(node.getLeft(), n));
			} else {
				if (node.getLeft() == null && node.getRight() == null) {
					node = null;
				} else if (node.getLeft() != null && node.getRight() == null) {
					node = node.getLeft();
				} else if (node.getLeft() == null && node.getRight() != null) {
					node = node.getRight();
				} else {
					Node node_temp = lastLeft(node.getRight());
					node.setRight(removeNode(node.getRight(), node_temp.getKey()));
					node.setKey(node_temp.getKey());
				}
			}
		}
		return node;
	}

验证

public class BTreeTest {
	
	
	public static void main(String[] args) {
		
		Node root = null;
		
		int arr[] = {8,3,1,6,4,7,10,14,13};
		for (int i = 0; i < arr.length; i++) {
			root = insert(root, arr[i]);
		}
		System.out.println("前序遍历:");
		before_print(root);
		System.out.println("\n中序遍历:");
		mid_print(root);
		System.out.println("\n后序遍历:");
		after_print(root);
		
		System.out.println("\n最小值:" + minNum(root));
		System.out.println("最大值:" + maxNum(root));
		
		System.out.println("是否存在3:" + contain(root, 3));
		
		root = removeNode(root, 3);
		System.out.println("删除3结果:");
		mid_print(root);
	}
}

输出结果:

前序遍历:
 8 3 1 6 4 7 10 14 13
中序遍历:
 1 3 4 6 7 8 10 13 14
后序遍历:
 1 4 7 6 3 13 14 10 8
最小值:1
最大值:14
是否存在3:true
删除3结果:
 1 4 6 7 8 10 13 14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值