二叉排序树的构造、深度优先遍历、广度优先遍历

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012379844/article/details/77990946
        之前面试官总是会问到二叉树的遍历,自己回答的很不好。甚至可以说想都想不起来。真的应了老师应常说的那句话,你们学的东西都还给老师了啊。。。这两天在看mysql优化的时候看到了B树,然后去查阅B树的知识,又知道B树又跟二叉排序树脱不了关系。于是就整理了这篇关于二叉排序树的相关知识。
        首先我们知道,二叉排序树的特征有:(1)如果一个节点的左子树不空,那么左子树的所有节点的值均小于该节点的值;
                                                                     (2)如果一个节点的右子树不空,那么右子树的所有节点的值均大于该节点的值;
        1.构造排序二叉树的基本思想为(使用前序插入)
            (1)首先定义一个根节点,初始化为null
            (2)将插入的第一个元素通过节点类打包给根节点
            (3)将根节点赋给currentNode这个节点
            (4)继续插入元素,如果该元素大于currentNode.value,那么就将该元素赋给currentNode.right,把currentNode.right当作currentNode;否则将该元素赋给currentNode.left,把currentNode.left当作currentNode
            (5)重复(4)
       2.二叉树的遍历有两种方式:深度优先遍历、广度优先遍历
           2.1深度优先遍历

              沿着树的深度遍历二叉树。可以使用前序遍历(递归、非递归)、中序遍历(递归、非递归)、后续遍历(递归、非递归)

           2.2广度优先遍历

               一层一层的遍历,先访问一个节点,再访问该节点的邻接节点

      3.具体代码实现(参考文章http://blog.csdn.net/fantasy_lin_/article/details/52751559
package Tree;

import java.util.LinkedList;
import java.util.Queue;

/*
Created By guolujie in 2017年9月15日
 */
public class MyTree {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BinaryOrderTree<Integer> tree = new BinaryOrderTree<Integer>();
		tree.insertTreeNode(2);
		tree.insertTreeNode(1);
		tree.insertTreeNode(0);
		tree.insertTreeNode(9);
		tree.insertTreeNode(6);
		tree.insertTreeNode(7);
		tree.insertTreeNode(5);
		tree.insertTreeNode(8);
		tree.insertTreeNode(3);
		tree.insertTreeNode(4);
		System.out.print("前序遍历(递归):");
		tree.preOrderTraverse(tree.getRoot());
		System.out.println();
		System.out.print("中序遍历(递归):");
		tree.midOrderTraverse(tree.getRoot());
		System.out.println();
		System.out.print("后序遍历(递归):");
		tree.postOrderTraverse(tree.getRoot());
		System.out.println();
		System.out.print("前序遍历(非递归):");
		tree.preOrderTraverseNo(tree.getRoot());
		System.out.println();
		System.out.print("中序遍历(非递归):");
		tree.midOrderTraverseNo(tree.getRoot());
		System.out.println();
		System.out.print("后序遍历(非递归):");
		tree.postOrderTraverseNo(tree.getRoot());
		System.out.println();
		System.out.print("广度优先遍历:");
		tree.breadthFirstTraverse(tree.getRoot());
	}

}
//首先定义节点类
class TreeNode<E extends Comparable<E>>{
	E value;
	TreeNode<E> left;
	TreeNode<E> right;
	TreeNode(E value){
		this.value = value;
		left = null;
		right = null;
	}
}
//通过前序插入节点,构造二叉排序树
class BinaryOrderTree<E extends Comparable<E>>{
	private TreeNode<E> root;
    BinaryOrderTree() {
		root=null;
	}
    
    public void insertTreeNode(E value){
    	if(root==null)
    	{
    		root = new TreeNode<E>(value);
    		return;
    	}
    	TreeNode<E> currentNode = root;
    	while(true){
    		if(value.compareTo(currentNode.value)>0){
    			if(currentNode.right==null){
    				currentNode.right = new TreeNode<E>(value);
    				break;
    			}
    			currentNode = currentNode.right;
    		}
    		else{
    			if(currentNode.left==null){
    				currentNode.left = new TreeNode<E>(value);
    				break;
    			}
    			currentNode = currentNode.left;
    		}
    	}
    }
    public TreeNode<E> getRoot(){
    	return root;
    }
    //前序遍历(递归)
    public void preOrderTraverse(TreeNode<E> node){
    	System.out.print(node.value+" ");
    	if(node.left!=null)
    		preOrderTraverse(node.left);
    	if(node.right!=null)
    		preOrderTraverse(node.right);
    }
    //中序遍历(递归)
    public void midOrderTraverse(TreeNode<E> node){
    	if(node.left!=null)
    		midOrderTraverse(node.left);
    	System.out.print(node.value+" ");
    	if(node.right!=null)
    		midOrderTraverse(node.right);
    }
    //后序遍历(递归)
    public void postOrderTraverse(TreeNode<E> node){
    	if(node.left!=null)
    		postOrderTraverse(node.left);
    	if(node.right!=null)
    		postOrderTraverse(node.right);
    	System.out.print(node.value+" ");
    }
    //前序遍历(非递归)
    public void preOrderTraverseNo(TreeNode<E> root){
    	LinkedList<TreeNode<E>> list = new LinkedList<TreeNode<E>>();
    	TreeNode<E> currentNode = null;
    	list.push(root);
    	while(!list.isEmpty()){
    		currentNode = list.pop();
    		System.out.print(currentNode.value+" ");
    		if(currentNode.right!=null)
    			list.push(currentNode.right);
    		if(currentNode.left!=null)
    			list.push(currentNode.left);
    	}
    }
    public void midOrderTraverseNo(TreeNode<E> root){
    	LinkedList<TreeNode<E>> list = new LinkedList<TreeNode<E>>();
    	TreeNode<E> currentNode = root;
    	while(currentNode!=null||!list.isEmpty()){
    		while(currentNode!=null){
    			list.push(currentNode);
    			currentNode = currentNode.left;
    		}
    		currentNode = list.pop();
    		System.out.print(currentNode.value+" ");
    		currentNode = currentNode.right;
    	}
    }
    public void postOrderTraverseNo(TreeNode<E> root){
    	LinkedList<TreeNode<E>> list = new LinkedList<TreeNode<E>>();
    	TreeNode<E> currentNode = root;
    	TreeNode<E> rightNode = null;
    	while(currentNode!=null||!list.isEmpty()){
    		while(currentNode!=null){
    			list.push(currentNode);
    			currentNode = currentNode.left;
    		}
    		currentNode = list.pop();
    		while (currentNode.right == null || currentNode.right == rightNode) {
    			System.out.print(currentNode.value + " ");
    			rightNode = currentNode;
    			if (list.isEmpty()) {
    				return; //root以输出,则遍历结束
    			}
    			currentNode = list.pop();
    		}
    		list.push(currentNode); //还有右结点没有遍历
    		currentNode = currentNode.right;
    	}
    }
    
    //广度优先遍历,使用队列
    public void breadthFirstTraverse(TreeNode<E> root){
    	Queue<TreeNode<E>> queue = new LinkedList<TreeNode<E>>();
    	TreeNode<E> currentNode = null;
    	queue.offer(root);
    	while(!queue.isEmpty()){
    		currentNode=queue.poll();
    		System.out.print(currentNode.value+" ");
    		if(currentNode.left!=null)
    			queue.offer(currentNode.left);
    		if(currentNode.right!=null)
    			queue.offer(currentNode.right);
    	}
    } 
}


猜你喜欢

转载自blog.csdn.net/u012379844/article/details/77990946