版权声明:本文为博主原创文章,未经博主允许不得转载。 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);
}
}
}