二叉树及其基本操作

二叉查找树Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树

  1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若它的右子树不空,则右子树上所有结点的值均大于或者等于它的根结点的值;
  3. 它的左、右子树也分别为二叉排序树。

二叉查找树的表示:
class Node {
    int data;
    Node leftChild = null;
    Node rightChild = null;
}
二叉查找树的常用方法:
1. 查找(lookup)
/*
Given a binary tree, return true if a node with the target data is found in the tree. Recurs down the tree, chooses the left or right branch by comparing the target to each node.
*/
static boolean lookup(Node rootNode, int target) {
    // 1. Base case == empty tree
    // in that case, the target is not found so return false
    if (rootNode == null) return false;
    else if (target == rootNode.data) return true;
    else if (target < rootNode.data) return(lookup(rootNode.leftChild, target));
    else return(lookup(rootNode.rightChild, target));
}
2. 最大(max)
	/*
	return the node with maximum key value. It should be last right child of the tree, or the root if the root does not have any child
	*/
	
	public Node maxNode(Node rootNode) {
		while (rootNode.righttChild != null) {
			rootNode = rootNode.rightChild;
		}
		return rootNode;
	}

3. 最小 (min)
	/*
	return the node with minimum key value. It should be last left child of the tree, or the root if the root does not have any child
	*/
	
	public Node minNode(Node rootNode) {
		while (rootNode.leftChild != null) {
			rootNode = rootNode.leftChild;
		}
		return rootNode;
	}

4. 插入(insert)
public static Node insert(Node root, int data) {
	// 1. If the tree is empty, the new node is the root
	if (root == null) {
		return new Node(data);
	}else {
		// 2. Otherwise, recur down the tree
		if (data <= root.data) root.leftChild = insert(root.leftChild, data);
		else root.rightChild = insert(root.rightChild, data);
	}
	return root;
}

5. in-order tree walk
public void inorder(Node rootNode) {
		if (rootNode != null) {
			inorder(rootNode.leftChild);
			print(nodeNode.data);
			inorder(rootNode.rightChild);
		}
	}

6. successor and predecessor
一个node的successor可以通过in-order walk看出来,因为in-order walk实际上是把二叉查找树做了一个排序。 predecesor 刚好和successor 相反。

Search consists of two cases.
1) If node x has a non-empty right subtree, then x’s successor is the minimum in the right subtree of x.
2) If node x has an empty right subtree, then as long as we move to the left up the tree (move up through right children), we are visiting smaller keys. x’s successor y is the node that x is the predecessor of (x is the maximum in y’s left subtree). In other words, x’s successor y, is the lowest ancestor of x whose left child is also an ancestor of x.
public Node Successor(Node node) {
		if (node.rightChild != null) {
			return minNode(node.rightChild);
		}
		
		Node parentNode = node.parent;
		while (parentNode != null && node == parentNode.rightChild) {
			node = parentNode;
			parentNode = parentNode.parent;
		}
		return parentNode;

	}

If node has two children, its predecessor is the maximum value in its left subtree. If it does not have a left child a node's predecessor is its first left ancestor.

7.  删除 (delete)

删除一个node x 需要考虑下面几种情况:
case 1: if x has no children,  then remove x;
case 2: if x has one child, then make p[x] point to child;
case 3: if x has two children (subtrees) , then swap x with its successor, perform case 0 or case 1 to delete it.

伪代码:

delete(x)
    if x.left = NIL and x.right = NIL //case 1
        if x.parent.left = x
           x.parent.left = NIL
        else
           x.parent.right = NIL
    else if x.left = NIL //case 2a
            connect x.parent to x.right
    else if x.right = NIL //case 2b
            connect x.parent to x.left
    else //case 3
            y = successor(x)
	        connect y.parent to y.right
            replace x with y

8. 求节点的个数(size)
/*
Compute the number of nodes in a tree.
*/
int size(Node rootNode) {
      if (node == NULL) {
      return(0);
      } else {
             return(size(rootNode.leftChild) + 1 + size(rootNode.rightChild));
      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值