二叉树的三种遍历机制

最常用的三种遍历方法:前序(preorder)、中序(inorder)和后序(postorder),二叉搜索树最常用的是中序遍历。

中序遍历

中序遍历二叉搜索树会使所有的节点按关键字升序被访问到。如果希望在二叉树中创建有序的数据序列,这是一种方法。
遍历树最简单的方法是递归。用递归方法遍历整棵树要用一个节点做参数。初始化时这个节点是根。步骤如下:

    1. 调用自身来遍历节点的左子树;
    1. 访问此节点
    1. 调用自身来遍历节点的右子树。
      遍历可以应用于任何二叉树,而不只是二叉搜索树。遍历原理不关心节点的关键字值;它只看节点是否有子节点。
      中序遍历代码如下:
private void inOrder(nodes localRoot){
	if(localRoot != null){
		inOrder(localRoot.leftChild);
		System.out.print(localRoot.data + " ");
		inOrder(localRoot.rightChild);
	}
}

开始时,用根作为参数来调用方法:

inOrder(root);

前序和后序遍历

前序遍历代码如下:

private void preOrder(nodes localRoot){
	if(localRoot != null){
		System.out.print(localRoot.data + " ");
		preOrder(localRoot.leftChild);
		preOrder(localRoot.rightChild);
	}
}

后序遍历代码如下:

private void postOrder(nodes localRoot){
	if(localRoot != null){
		postOrder(localRoot.leftChild);
		postOrder(localRoot.rightChild);
		System.out.print(localRoot.data + " ");
	}
}

应用

树的节点定义

public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}

Tree类的基本方法:

class Tree{
	private Node root;
	public void find(int key){
	}
	public void insert(int id, double data){
	}
	public void delete(int id){
	}
}
find()例程:
public Node find(int key){
	Node current = root;
	while(current.data != key){
		if(key < current.data)
			current = currnet.leftChild;
		else
			current = current.rightChild;
		if(current == null) return null;
	}
	return current;
}

效率:查找节点的时间取决于这个节点所在的层数,其时间复杂度为O(logN).

insert()例程
public void insert(double data){
	Node newNode = new Node();
	newNode.data = data;
	if(root == null)
		root = new Node;
	else{
		Node current = root;
		Node parrent;
		while(true){
			parrent = current;
			if(data < current.data){
				current = current.leftChild;
				if(current == null){
					parent.leftChild = newNode;
					return;
				}
			}
			else{
			 	current = current.rightChild;
			 	if(current == null){
			 		parent.rightChild = newNode;
			 		return;
			 	}
			}
		}
	}
}
查找最大值最小值
public Node minimum(){
	Node current,last;
	current = root;
	while(current != null){
		last = current;
		current = current.leftChild;
	}
	return last;
}
删除节点
public boolean delete(int key){
	Node current = root;
	Node parent = root;
	boolean isLeftChild = true;
	while(current.data != key){
		parent = current;
		if(key < current.data){
			isleftChild = true;
			current = current.leftChild;
		}
		else{
			isLeftChild = false;
			current = current.rightChild;
		}
		if(current == null) return false;
	}
	//1.删除没有子节点的节点
	if(current.leftChild == null && current.rightChildren = null){
		if(current == root) root = null;
		else if(isleftChildren) parent.leftChildren = null;
		else parent.rightChildren = null;
	}
	//2.删除有一个子节点的节点
	//如果没有右孩子,用左子树替代
	else if(current.rightChild == null)
		if(current == root)
			root = current.leftChild;
		else if(isLeftChild)
			parent.leftChild = current.leftChild;
		else parent.rightChild = current.leftChild;   
	//如果没有左孩子,用右子树替代
	else if(current.leftChild == null)
		if(current == root)
			root = current.rightChild;
		else(isLeftChild)
			parent.leftChild = current.rightChild;
		else parent.right = current.rightChild;
	//3.删除有两个孩子的节点
	else{// two children, so replace with inorder successor
		//get the successor of node to delete(current)
		Node succesor = getSuccessor(current);
		//connect parent of current to successor instead
		if(current == root)
			root = successor;
		else if(isLeftChild)
			parent.leftChild = successor;
		else parent.rightChild = successor;
		//connect successor to current.leftChild
		successor.leftChild = current.leftChild;
	}
	//successor cannot have a left child
	return true;
}
private node getSuccessor(node delNode){
	Node successorParent = delNode;
	Node successor = delNode;
	Node current = delNode.rightChild;
	while(current != null){
		sussessorParent = successor;;
		successor = current;
		current = current.leftChild;
	}
	if(successor != delNode.rightChild){
		successorParrent.leftChild = successor.rightChild;
		successor.rightChild = delNode.rightChild;
	}
	return successor;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值