二叉树相关知识——java

1. 普通二叉树创建

       点击查看二叉树创建方式



2.二叉排序树(BinarySearchTree)

       二叉排序树又名二叉查找树、二叉搜索树

  1. 每个结点都有一个作为搜索依据的关键码(key),所有结点的关键码互不相同。
  2. 左子树(如果非空)上所有结点的关键码都小于根结点的关键码。
  3. 右子树(如果非空)上所有结点的关键码都大于根结点的关键码。
  4. 左子树和右子树也是二叉搜索树。
  5. 结点左子树上所有关键码小于结点关键码;
  6. 右子树上所有关键码大于结点关键码;
  7. 若从根结点到某个叶结点有一条路径,路径左边的结点的关键码不一定小于路径上的结点的关键码。
  8. 如果对一棵二叉搜索树进行中序遍历,可以按从小到大的顺序,将各结点关键码排列起来,所以也称二叉搜索树为二叉排序树。 下图为二叉搜索树的一个图
                                                                       

二叉排序树的插入
在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。   
插入过程:
若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;   
当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。

二叉排序树的查找
假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:
  ① 置初值: q = root ;
  ② 如果 K = q -> key ,则查找成功,算法结束;
  ③ 否则,如果 K < q -> key ,而且 q 的左子树非空,则将 q 的左子树根送 q ,转步骤②;否则,查找失败,结束算法;
  ④ 否则,如果 K > q -> key ,而且 q 的右子树非空,则将 q 的右子树根送 q ,转步骤②;否则,查找失败,算法结束。

二叉排序树的删除
假设被删结点是*p,其双亲是*f,不失一般性,设*p是*f的左孩子,下面分三种情况讨论:   
⑴ 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可。   
⑵ 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR 成为其双亲结点的左子树即可。   
⑶ 若结点*p的左、右子树均非空,先找到*p的中序前趋(或后继)结点*s(注意*s是*p的左子树中的最右下的结点,它的右链域为空),然后有两种做法:① 令*p的左子树直接链到*p的双亲结点*f的左链上,而*p的右子树链到*p的中序前趋结点*s的右链上。② 以*p的中序前趋结点*s代替*p(即把*s的数据复制到*p中),将*s的左子树链到*s的双亲结点*q的左(或右)链上。


构建二叉排序树代码

public class BST {

	class Node{
		public int data;
		public Node left;
		public Node right;
		Node(int data){
			this.data=data;
			this.left=null;
			this.right=null;
		}
	}
	private Node root;

	public BST(){
		root=null;
	}
	/**
	 * 递归构建二叉搜索树
	 * @param node  每次从根节点开始遍历
	 * @param data
	 */
	public void addNode(Node node,int data){
		if(root==null){
			root = new Node(data);
		}else{
			if(data<node.data){
				if(node.left==null){
					node.left=new Node(data);
				}else{
					addNode(node.left,data);
				}
			}else{
				if(node.right==null){
					node.right=new Node(data);
				}else{
					addNode(node.right,data);
				}
			}
		}
	}

	/**
	 * 非递归构建二叉查找树
	 * @param data
	 */
	public void addNodeRound(int data){
		if(null==root){
			root = new Node(data);
		}else{
			Node node = new Node(data);
			Node current = root;//子节点,当前结点
			Node parent;//父节点,记录父节点,然后才能够判断到底添加到哪里
			for(;;){
				parent = current;
				if(current.data>data){//插入数据比父节点小-->左侧
					current=current.left;
					if(null==current){
						parent.left=node;
						return;
					}

				}else if(current.data<data){
					current=current.right;
					if(null==current){
						parent.right=node;
						return;
					}
				}
			}
		}
	}
}


查找对应的结点

    /**
     * 递归查找某个值对应的节点
     * @param node
     * @param data
     * @return
     */
    public Node findDG(Node node, int data) {
        if (node == null)
            return null;

        if (node.data < data) {
            node = node.right;
            return findDG(node, data);
        } else if (node.data > data) {
            node = node.left;
            return findDG(node, data);
        } else {
            return node;
        }
    }

	/**
	 * 非递归查找某个值对应的节点
	 * @param data
	 * @return
	 */
	public Node find(int data) {
		Node current = root;
		while (current.data != data) {
			if (current.data < data) {
				current = current.right;
			} else {
				current = current.left;
			}
			if (current == null)
				return null;
		}
		return current;
	}

查找最小值对应的结点

	/**
	 * 查找最小值对应节点
	 * @return
	 */
	public Node findMinNode(){
		Node current;
		Node parent;
		if(root==null)
			return null;
		else{
			parent = root;
			current = parent.left;
			while(current!=null){
				parent=current;
				current=current.left;
			}
			return parent;
		}
	}

递归非递归遍历

 点击查看遍历方式

点击查看遍历详细流程解释


附上自己写的代码连接:免费下载链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值