二分搜索树常用方法

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, 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 int size() {
		return size;
	}

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

	public void add(E e) {
		root = add(root, e);
	}

	// 向以node为根的二分搜索树中插入元素E,递归算法
	// 返回插入新节点后二分搜索树的根
	private Node add(Node node, E e) {

		if (node == null) {
			size++;
			return new Node(e);
		}
		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 node;
	}

	// 看二分搜索树中是否包含元素e
	public boolean contains(E e) {
		return contains(root, e);
	}

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

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

	// 前序遍历以node为根的二分搜索树,递归算法
	private void preOrder(Node node) {
		if (node == null)
			return;

		System.out.println(node.e);
		preOrder(node.left);
		preOrder(node.right);
	}

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

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

	// 中序遍历以node为根的二分搜索树,递归算法
	private void inOrder(Node node) {
		if (node == null)
			return;

		inOrder(node.left);
		System.out.println(node.e);
		inOrder(node.right);
	}

	// 二分搜索树的后序遍历
	public void postOrder() {
		postOrder(root);
	}

	// 后序遍历以node为根的二分搜索树,递归算法
	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.e);

			if (cur.left != null)
				q.add(cur.left);
			if (cur.right != null)
				q.add(cur.right);
		}
	}

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

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

	// 寻找二分搜索树的最大元素
	public E maximum() {
		if (size == 0)
			throw new IllegalArgumentException("BST is empty!");

		return maximum(root).e;
	}

	// 返回以node为根的二分搜索树的最大值所在的节点
	private Node maximum(Node node) {
		if (node.right == null)
			return node;

		return maximum(node.right);
	}

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

	// 删除掉以node为根的二分搜索树中的最小节点
	// 返回删除节点后新的二分搜索树的根
	private Node removeMin(Node node) {

		if (node.left == null) {
			Node rightNode = node.right;
			node.right = null;
			size--;
			return rightNode;
		}
		node.left = removeMin(node.left);
		return node;
	}

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

	// 删除掉以node为根的二分搜索树中的最大节点
	// 返回删除节点后新的二分搜索树的根
	private Node removeMax(Node node) {

		if (node.right == null) {
			Node leftNode = node.left;
			node.left = null;
			size--;
			return leftNode;
		}
		node.right = removeMin(node.right);
		return node;
	}

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

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

			node.left = node.right = null;

			return successor;
		}
	}

	public String toString() {
		StringBuilder res = new StringBuilder();
		generateBSTString(root, 0, res);
		return res.toString();
	}

	// 生成以node为根节点,深度为depth的描述二叉树的字符串
	private void generateBSTString(Node node, int depth, StringBuilder res) {
		if (node == null) {
			res.append(generateDepthString(depth) + "null\n");
			return;
		}
		res.append(generateDepthString(depth) + node.e + "\n");
		generateBSTString(node.left, depth + 1, res);
		generateBSTString(node.right, depth + 1, res);
	}

	private String generateDepthString(int depth) {
		StringBuilder res = new StringBuilder();
		for (int i = 0; i < depth; i++) {
			res.append("--");
		}
		return res.toString();
	}
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
统计学习是计算机及其应用领域的一门重要的学科。本书全面系统地介绍了统计学习的主要方法,特别是监督学习方法,包括感知机、k近邻法、朴素贝叶斯法、决策、逻辑斯谛回归与最大熵模型、支持向量机、提升方法、em算法、隐马尔可夫模型和条件随机场等。除第1章概论和最后一章总结外,每章介绍一种方法。叙述从具体问题或实例入手,由浅入深,阐明思路,给出必要的数学推导,便于读者掌握统计学习方法的实质,学会运用。为满足读者进一步学习的需要,书中还介绍了一些相关研究,给出了少量习题,列出了主要参考文献。 《统计学习方法》是统计学习及相关课程的教学参考书,适用于高等院校文本数据挖掘、信息检索及自然语言处理等专业的大学生、研究生,也可供从事计算机应用相关专业的研发人员参考。 《统计学习方法》 第1章统计学习方法概论 1.1统计学习 1.2监督学习 1.2.1基本概念 1.2.2问题的形式化 1.3统计学习三要素 1.3.1模型 1.3.2策略 1.3.3算法 1.4模型评估与模型选择 1.4.1训练误差与测试误差 1.4.2过拟合与模型选择 1.5i~则化与交叉验证 1.5.1正则化 1.5.2交叉验证 1.6泛化能力 1.6.1泛化误差 1.6.2泛化误差上界 1.7生成模型与判别模型 .1.8分类问题 1.9标注问题 1.10回归问题 本章概要 继续阅读 习题 参考文献 第2章感知机 2.1感知机模型 2.2感知机学习策略 2.2.1数据集的线性可分性 2.2.2感知机学习策略 2.3感知机学习算法 2.3.1感知机学习算法的原始形式 2.3.2算法的收敛性 2.3.3感知机学习算法的对偶形式 本章概要 继续阅读 习题 参考文献 第3章众近邻法 3.1 k近邻算法 3.2 k近邻模型 3.2.1模型 3.2.2距离度量 ·3.2.3 k值的选择 3.2.4分类决策规则 3.3k近邻法的实现:kd 3.3.1构造af 3.3.2搜索af 本章概要 继续阅读 习题 参考文献 第4章朴素贝叶斯法 4.1朴素贝叶斯法的学习与分类 4.1.1基本方法 4.1.2后验概率最大化的含义 4.2朴素贝叶斯法的参数估计 4.2.1极大似然估计 4.2.2学习与分类算法 4.2.3贝叶斯估计 本章概要 继续阅读 习题 参考文献 第5章决策 5.1决策模型与学习 5.1.1决策模型 5.1.2决策与isthen规则 5.1.3决策与条件概率分布 5.1.4决策学习 5.2特征选择 5.2.1特征选择问题 5.2.2信息增益 5.2.3信息增益比 5.3决策的生成 5.3.11d3算法 5.3.2 c4.5的生成算法 5.4决策的剪枝 5.5cart算法 5.5.1cart生成 5.5.2cart剪枝 本章概要 继续阅读 习题 参考文献 第6章逻辑斯谛回归与最大熵模型 6.1逻辑斯谛回归模型 6.1.1逻辑斯谛分布 6.1.2项逻辑斯谛回归模型 6.1.3模型参数估计 6.1.4多项逻辑斯谛回归 6.2最大熵模型 6.2.1最大熵原理 6.2.2最大熵模型的定义 6.2.3最大熵模型的学习 6.2.4极大似然估计 6.3模型学习的最优化算法 6.3.1改进的迭代尺度法 6.3.2拟牛顿法 本章概要 继续阅读 习题 参考文献 第7章支持向量机 7.1线性可分支持向量机与硬间隔最大化 7.1.1线性可分支持向量机 7.1.2函数间隔和几何间隔 7.1.3间隔最大化 7.1.4学习的对偶算法 7.2线性支持向量机与软间隔最大化 7.2.1线性支持向量机 7.2.2学习的对偶算法 7.2.3支持向量 7.2.4合页损失函数 7.3非线性支持向量机与核函数 7.3.1核技巧 7.3.2定核 7.3.3常用核函数 7.3.4非线性支持向量分类机 7.4序列最小最优化算法 7.4.1两个变量二次规划的求解方法 7.4.2变量的选择方法 7.4.3smo算法 本章概要 继续阅读 习题 参考文献 第8章提升方法 8.1提升方法adaboost算法 8.1.1提升方法的基本思路 8.1.2adaboost算法 8.1.3 adaboost的例子 8.2adaboost算法的训练误差分析 8.3 adaboost算法的解释 8.3.1前向分步算法 8.3.2前向分步算法与ad9boost 8.4提升 8.4.1提升模型 8.4.2提升算法 8.4.3梯度提升 本章概要 继续阅读 习题 参考文献 第9章em算法及其推广 9.1em算法的引入 9.1.1em算法 9.1.2em算法的导出 9.1.3em算法在非监督学习中的应用 9.2em算法的收敛性 9.3em算法在高斯混合模型学习中的应用 9.3.1高斯混合模型 9.3.2高斯混合模型参数估计的em算法 9.4em算法的推广 9.4.1f函数的极大极大算法 9.4.2gem算法 本章概要 继续阅读 习题 参考文献 第10章隐马尔可夫模型 10.1隐马尔可夫模型的基本概念 10.1.1隐马尔可夫模型的定义 10.1.2观测序列的生成过程 10.1.3隐马尔可夫模型的3个基本问题 10.2概率计算算法 10.2.1直接计算法 10.2.2前向算法 10.2.3后向算法 10.2.4一些概率与期望值的计算 10.3学习算法 10.3.1监督学习方法 10.3.2baum-welch算法 10.3.3baum-welch模型参数估计公式 10.4预测算法 10.4.1近似算法 10.4.2维特比算法 本章概要 继续阅读 习题 参考文献 第11章条件随机场 11.1概率无向图模型 11.1.1模型定义 11.1.2概率无向图模型的因子分解 11.2条件随机场的定义与形式 11.2.1条件随机场的定义 11.2.2条件随机场的参数化形式 11.2.3条件随机场的简化形式 11.2.4条件随机场的矩阵形式 11.3条件随机场的概率计算问题 11.3.1前向后向算法 11.3.2概率计算 11.3.3期望值的计算 11.4条件随机场的学习算法 11.4.1改进的迭代尺度法 11.4.2拟牛顿法 11.5条件随机场的预测算法 本章概要 继续阅读 习题 参考文献 第12章统计学习方法总结 附录a梯度下降法 附录b牛顿法和拟牛顿法 附录c拉格朗日对偶性

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值