zoukankan      html  css  js  c++  java
  • 二叉排序树

    概念

        二叉排序树,又称二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树:
    ①若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值。
    ② 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值。
    ③ 它的左右子树也分别为二叉排序树。

    查找、插入和删除操作

    package binaryTree;
    
    public class TreeNode {
    	int val;
    	TreeNode left;
    	TreeNode right;
    
    	TreeNode(int val) {
    		this.val = val;
    	}
    }
    

    举例

    package binaryTree;
    
    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class BST {
    
    	// 若查找成功p指向该数据元素结点,否则p指向查找路径上访问的最后一个结点;
    	private static TreeNode p;
    
    	/**
    	 * 查找操作
    	 * 
    	 * 思路:根据二叉排序树的性质,分左右子树进行递归查找;
    	 * 
    	 * @param root
    	 *            当前结点;
    	 * @param f
    	 *            当前节点的父结点;
    	 * @param p
    	 * 
    	 * @param key
    	 *            关键值
    	 */
    	private static boolean BST_search(TreeNode root, TreeNode f, int key) {
    		if (root == null) {
    			p = f;
    			return false;
    		} else if (key == root.val) {
    			p = root;
    			return true;
    		} else if (key > root.val) {
    			return BST_search(root.right, root, key);
    		} else {
    			return BST_search(root.left, root, key);
    		}
    	}
    
    	/**
    	 * 插入操作;
    	 * 
    	 * 思路:先查找原二叉树是否存在,不存在插入,存在则不插入;
    	 * 
    	 * @param key
    	 *            关键值
    	 */
    	private static boolean BST_insert(TreeNode root, int key) {
    
    		p = null;
    		if (!BST_search(root, null, key)) { // 不存在,则插入,p是查找的最后一个节点;
    			TreeNode node = new TreeNode(key);
    			if (p == null) { // 根节点;
    				root = node;
    			} else if (p.val < key) { // node作为右结点;
    				p.right = node;
    			} else { // 作为左节点;
    				p.left = node;
    			}
    			return true;
    		} else { // 已经存在;
    			return false;
    		}
    	}
    
    	private static void clear() {
    		p = null;
    	}
    
    	/**
    	 * 删除操作;
    	 * 分情况:1、待删除的点为叶子结点(直接删除);2、只有左或者右分支(子承父业);3、左右分支都存在(找中序遍历待删结点的前驱或者后继结点代替);
    	 * 
    	 * @param root
    	 *            当前结点;
    	 * @param key
    	 *            关键字;
    	 * @return
    	 */
    	private static boolean BST_delete(TreeNode root, int key) {
    		if (root == null) { // 树为空,则不存在关键字为key的值;
    			return false;
    		} else {
    			if (key == root.val) { // 找到;
    				return deleteNode(root);
    
    			} else if (root.val > key) { // 到左子树中去查找;
    				return BST_delete(root.left, key);
    			} else {// 到右子树中去查找;
    				return BST_delete(root.right, key);
    			}
    		}
    	}
    
    	/**
    	 * 删除结点;
    	 * 
    	 * @param root
    	 * @return
    	 */
    	private static boolean deleteNode(TreeNode root) {
    		if (root.left == null && root.right == null) { // 叶子结点;
    			root = null;
    
    		} else if (root.left == null) {// 左子树为空,则右子树的根结点代替;
    			root = root.right;
    
    		} else if (root.right == null) { // 右子树为空,则左子树的根结点代替;
    			root = root.left;
    
    		} else { // 左右子树都存在;
    			// 首先找到该结点的中序遍历的前驱结点,即左子树的最右端的结点;
    			TreeNode f = root;
    			TreeNode p = f.left;// 左子树的根结点;
    			while (p.right != null) {
    				f = p;
    				p = p.right;
    			}
    			// 找到最终的的前驱f;
    			root.val = p.val;
    			if (f == root) { // 重新连接q的左子树;
    				f.left = p.left;
    			} else { // 重新连接q的右子树;
    				f.right = p.left;
    			}
    			p = null;
    
    		}
    		return true;
    	}
    
    	/**
    	 * 中序遍历
    	 * 
    	 * @param root
    	 */
    	private static void inOrderTraverse(TreeNode root, ArrayList<Integer> list) {
    		if (root == null) {
    			return;
    		}
    
    		inOrderTraverse(root.left, list);
    		list.add(root.val);
    		inOrderTraverse(root.right, list);
    
    	}
    
    	public static void main(String[] args) {
    
    		TreeNode root = null;
    		ArrayList<Integer> list = new ArrayList<Integer>();
    		int[] arr = { 80, 56, 92, 34, 60, 86, 101, 22, 49, 58, 72, 42 };
    
    		for (int i : arr) {
    			if (root == null) {
    				root = new TreeNode(i);// 根节点显示给出单独;;
    			} else {
    				BST_insert(root, i);
    			}
    		}
    
    		// 原二叉排序树;
    		inOrderTraverse(root, list);
    		System.out.println("删除前:"+list);
    
    		// 清空p;
    		clear();
    
    		// 删除56这个结点;
    		BST_delete(root, 56);
    
    		// 清空List;
    		list.clear();
    		// 删除后结构没有改变;
    		inOrderTraverse(root, list);
    		System.out.println("删除结点56后:"+list);
    
    	}
    }
    
    
    

    运行结果:

    多思考,多尝试。
  • 相关阅读:
    .NET_.NET 发布(publish)网站_012
    Oracle 11g Release 1 (11.1) 单行函数——日期函数
    Oracle 11g Release 1 (11.1) SQL_层级查询(概)
    C# 清理非托管资源
    NChain 0.1 项目——但愿是根救命稻草
    人工智能——神经网络
    概念——都有哪些 Web 服务方式
    从 Fibonacci 数列看“动态规划”思想
    QR 码
    Oracle 11g Release 1 (11.1) 表空间——创建和扩展永久表空间
  • 原文地址:https://www.cnblogs.com/LynnMin/p/9504446.html
Copyright © 2011-2022 走看看