JAVA实现二叉树的创建、前序、中序、后序、层次遍历以及查找删除二叉树中元素节点

24 篇文章 2 订阅
5 篇文章 0 订阅

什么是树?

树 (数据结构名词):
树状图是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树

在这里插入图片描述

什么是二叉树?

树有很多种, 每个节点最多只能有两个子节点的叫二叉树
二叉树的子节点分为左节点和右节点
二叉树示意图
在这里插入图片描述
如果二叉树的所有叶子节点都在最后一层, 并且结点总数=2^n-1, n为层数, 则我们称之为满二叉数
满二叉树示意图
在这里插入图片描述
如果该二叉树的所有叶子节点(没有子节点的节点)都在最后一层或者倒数第二层, 而且最后一层的叶子节点在左边连续, 倒数第二层的叶子节点在右边连续, 我们称之为完全二叉树
完全二叉树示意图
在这里插入图片描述
遍历二叉树
前序、中序和后序三种遍历方式
前序遍历, 先输出父节点, 再遍历左子树和右子树
中序遍历, 先遍历左子树, 再输出父节点, 再遍历右子树
后序遍历, 先遍历左子树, 再遍历右子树, 最后输出父节点**

代码实现遍历

package tree;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class BST<E extends Comparable<E>> {

	private class Node {
		public E e;
		public Node left;
		public Node right;

		public Node(E e) {
			this.e = e;
			left = null;
			right = null;
		}
	}

	private Node root;
	private int size;

	public BST() {
		root = null;
		size = 0;
	}

	public boolean isEmpty() {
		return size == 0;
	}

	/**
	 * 向二分搜索树中添加元素
	 * 
	 * @param e
	 */
	public void add(E e) {
		if (root == null) {
			root = new Node(e);
			size++;
		} else {
			add(root, e);
		}
	}

	/**
	 * 向以node为根的二分搜索树中插入元素E,递归算法
	 * 
	 * @param node
	 * @param e
	 */
	private Node add(Node node, E e) {
		if (node == null) {
			size++;
			return new Node(e);
		}
//		if(e.equals(node.e)) {
//			return;
//		}else if(e.compareTo(node.e) < 0 && node.left == null) {
//			node.left = new Node(e);
//			size ++;
//			return;
//		}else if(e.compareTo(node.e) > 0 && node.right == null) {
//			node.right = new Node(e);
//			size ++;
//			return;
//		}
		if (e.compareTo(node.e) < 0) {
			node.left = add(node.left, e);
		} else if (e.compareTo(node.e) > 0) {
			node.right = add(node.right, e);
		}
		return new Node(e);
	}

	/**
	 * 查看二叉树中是否包含元素
	 * 
	 * @param e
	 * @return
	 */
	public boolean contains(E e) {
		return contains(root, e);
	}

	/**
	 * 查看以node为根的二分搜索树中是否包含元素e 递归算法发
	 * 
	 * @param node
	 * @param e
	 * @return
	 */
	private boolean contains(Node node, E e) {
		if (node == null) {
			return true;
		}
		if (e.compareTo(node.e) == 0) {
			return true;
		} else if (e.compareTo(node.e) < 0) {
			return contains(node.left, e);
		} else { // e.compareTo(node.e) > 0
			return contains(node.right, e);
		}
	}

	// 二分搜索树的前序遍历
	public void preOrder() {
		preOder(root);
	}

	// 前序遍历以node为根的二分搜索树,递归算法
	private void preOder(Node node) {
		if (node == null) {
			return;
		}
		System.out.println(node.e);
		preOder(node.left);
		preOder(node.right);
	}

	/**
	 * 二分搜索树非递归前序遍历
	 */
	public void preOrderNR() {
		Stack<Node> stack = new Stack<>();
		stack.push(root);
		while (!stack.isEmpty()) {
			Node cur = stack.pop();
			System.out.println(cur);
			if (cur.left != null) {
				stack.push(cur.left);
			}
			if (cur.right != null) {
				stack.push(cur.right);
			}
		}
	}

	/**
	 * 二分搜索树的中序遍历
	 */
	public void inOrder() {
		inOrder(root);
	}

	/**
	 * 中序遍历以node为根的二分搜索树,递归算法
	 * 
	 * @param root2
	 */
	private void inOrder(Node root) {
		if (root == null) {
			return;
		}
		inOrder(root.left);
		System.out.println(root);
		inOrder(root.right); // 二分搜索树的中序遍历结果是顺序的(排序树)
	}

	/**
	 * 二分搜索树的后序遍历 -------------内存的释放
	 */
	public void postOrder() {
		postOrder(root);
	}

	/**
	 * 后续遍历以node为根的二分搜索树,递归算法
	 * 
	 * @param root2
	 */
	private void postOrder(Node node) {
		if (node == null) {
			return;
		}
		postOrder(node.left);
		postOrder(node.right);
		System.out.println(node.e);

	}

	/**
	 * 二分搜索树的层序遍历
	 */
	public void levelOrder() {
		Queue<Node> q = new LinkedList<>();
		q.add(root);
		while (!q.isEmpty()) {
			Node cur = q.remove();
			System.out.println(cur);
			if (cur.left != null) {
				q.add(cur.left);
			}
			if (cur.right != null) {
				q.add(cur.right);
			}
		}
	}

	/**
	 * 寻找二分搜索树的最小元素
	 * 
	 * @throws IllegalAccessException
	 */
	public E minimum() throws IllegalAccessException {
		if (size == 0) {
			throw new IllegalAccessException("BST is empty");
		}
		return minimum(root).e;
	}

	/**
	 * 返回node为根的二分搜索树的最小值所在的节点
	 * 
	 * @param node
	 * @return
	 */
	private Node minimum(Node node) {
		if (node.left == null) {
			return node;
		}
		return minimum(node.left);
	}

	/**
	 * 寻找二分搜索树的最大元素
	 * 
	 * @throws IllegalAccessException
	 */
	public E maxmum() throws IllegalAccessException {
		if (size == 0) {
			throw new IllegalAccessException("BST is empty");
		}
		return maxmum(root).e;
	}

	/**
	 * 返回node为根的二分搜索树的最大值所在的节点
	 * 
	 * @param node
	 * @return
	 */
	private Node maxmum(Node node) {
		if (node.right == null) {
			return node;
		}
		return minimum(node.right);
	}

	/**
	 * 从二分搜索树中删除最小值所在的节点,返回最小值
	 * 
	 * @return
	 * @throws IllegalAccessException
	 */
	public E removeMin() throws IllegalAccessException {
		E ret = minimum();
		removeMin(root);
		return ret;
	}

	/**
	 * 删除最小值
	 * 
	 * @param node
	 * @return
	 */
	private Node removeMin(Node node) {
		if (node.left == null) {
			Node rigthNode = node.right;
			node.right = null;
			size--;
			return rigthNode;
		}
		node.left = removeMin(node.left);
		return node;
	}

	/**
	 * 从二分搜索树中删除最小值所在的节点,返回最小值
	 * 
	 * @return
	 * @throws IllegalAccessException
	 */
	public E removeMax() throws IllegalAccessException {
		E ret = removeMax();
		removeMax(root);
		return ret;
	}

	/**
	 * 删除最小值
	 * 
	 * @param node
	 * @return
	 */
	private Node removeMax(Node node) {
		if (node.right == null) {
			Node rigthNode = node.left;
			node.left = null;
			size--;
			return rigthNode;
		}
		node.right = removeMin(node.right);
		return node;
	}

	/**
	 * 重二分搜索树中删除元素为e的节点
	 * 
	 * @param e
	 */
	public void remove(E e) {
		root = remove(root, e);
	}

	/**
	 * 删除已node为根的二分搜索树中值为e的节点,递归算法
	 * 
	 * @param node
	 * @param e
	 * @return
	 */
	private Node remove(Node node, E e) {
		if (node == null) {
			return null;
		}
		if (e.compareTo(node.e) < 0) {
			node.left = remove(node.left, e);
		} else if (e.compareTo(node.e) > 0) {
			node.right = remove(node.right, e);
		} else { // e == node.e
			if (node.left == null) {
				Node rigthNode = node.right;
				node.right = null;
				size--;
				return rigthNode;
			}
			if (node.right == null) {
				Node leftNode = node.left;
				node.left = null;
				size--;
				return leftNode;
			}
		}
		// 待删除节点的左右子树都不为空的情况
					// 找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
					// 用这个节点顶替待删除的节点
					Node succesor = minimum(node.right);
					succesor.right = removeMin(node.right);
					succesor.left = node.left;
					node.left = node.right = null;
					return succesor;
	}

	/**
	 * 构建二叉树的输出结果
	 */
	public String toString() {
		StringBuilder res = new StringBuilder();
		generateBSTString(root, 0, res);
		return res.toString();
	}

	private void generateBSTString(Node node, int depth, StringBuilder res) {

		if (node == null) {
			res.append(generateBSTString(depth) + "null\n");
			return;
		}
		res.append(generateBSTString(depth) + node.e + "\n");
		generateBSTString(node.left, depth + 1, res);
		generateBSTString(node.right, depth + 1, res);
	}
	private String generateBSTString(int depth) {
		StringBuilder res = new StringBuilder();
		for (int i = 0; i < depth; i++) {
			res.append("----------");
		}
		return res.toString();
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值