二叉树
二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加。但是他也有自己的缺点:删除操作复杂。
很多语言的map、set结构就是用二叉搜索树实现的 ,优先队列一般是用大顶堆实现的吧,一般的大顶堆是二叉树吧
转载地址 :http://blog.csdn.net/ma0ogrubby/article/details/52210147
package BinaryTree;
import java.util.Stack;
public class BinaryTree {
/**
* 二叉树的节点数据结构
*/
private class TreeNode {
private int key = 0;
private String data = null;
private boolean isVisted = false;
private TreeNode leftChild = null;
private TreeNode rightChild = null;
// public TreeNode(){}
public TreeNode(int key,String data){
this.key = key;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
}
private TreeNode root = null;
public BinaryTree(){
root = new TreeNode(1,"rootNode(A)");
}
/**
* 创建二叉树
* * A
* B C
* D E F
* @param args
*/
public void createBinTree(TreeNode root){
TreeNode newNodeB = new TreeNode(2,"B");
TreeNode newNodeC = new TreeNode(3,"C");
TreeNode newNodeD = new TreeNode(4,"D");
TreeNode newNodeE = new TreeNode(5,"E");
TreeNode newNodeF = new TreeNode(6,"F");
root.leftChild = newNodeB;
root.rightChild = newNodeC;
root.leftChild.leftChild=newNodeD;
root.leftChild.rightChild=newNodeE;
root.rightChild.rightChild=newNodeF;
}
public boolean isEmpty(){
return root == null;
}
public int size(){
return size(root);
}
private int size(TreeNode subTree){
if(subTree == null){
return 0;
}else{
return 1+size(subTree.leftChild)+size(subTree.rightChild);
}
}
public int height(){
return height(root);
}
private int height(TreeNode subTree) {
if(subTree == null){
return 0;
}else{
int i = height(subTree.leftChild);
int j = height(subTree.rightChild);
return (i>j)?(j+1):(i+1);
}
}
/**
* 前序遍历
* 递归左节点、右节点
* @param subTree
*/
private void preOrder(TreeNode subTree) {
if(subTree!=null){
visted(subTree);
preOrder(subTree.leftChild);
preOrder(subTree.rightChild);
}
}
/**
* 中序遍历
* 递归
* @param subTree
*/
private void inOrder(TreeNode subTree) {
if(subTree!=null){
inOrder(subTree.leftChild);
visted(subTree);
inOrder(subTree.rightChild);
}
}
/**
* 后序遍历
* 递归
* @param subTree
*/
public void postOrder(TreeNode subTree) {
if (subTree != null) {
postOrder(subTree.leftChild);
postOrder(subTree.rightChild);
visted(subTree);
}
}
private void visted(TreeNode subTree) {
subTree.isVisted=true;
System.out.println("key:"+subTree.key+"--name:"+subTree.data);
}
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.createBinTree(bt.root);
System.out.println("SIZE:"+bt.size());
System.out.println("HEIGHT:"+bt.height());
System.out.println("*******(前序遍历)[ABDECF]遍历*****************");
// 基本思想:先访问根结点,再先序遍历左子树,最后再先序遍历右子树即根—左—右。
bt.preOrder(bt.root);
System.out.println("*******(中序遍历)[DBEACF]遍历*****************");
// 基本思想:先中序遍历左子树,然后再访问根结点,最后再中序遍历右子树即左—根—右。
bt.inOrder(bt.root);
System.out.println("*******(后序遍历)[DEBFCA]遍历*****************");
// 基本思想:先后序遍历左子树,然后再后序遍历右子树,最后再访问根结点即左—右—根。
bt.postOrder(bt.root);
/** stack 的方法说明
* - push() - 在栈顶添加元素 - peek() - 返回栈顶的元素,但是不删除栈顶元素 - pop() - 和peek()一样返回栈顶元素,但是要将栈顶元素移除掉
* - empty() - 检查栈是否为空 - search() - 返回元素在堆栈中的位置
*/
System.out.println("***非递归实现****(前序遍历)[ABDECF]遍历*****************");
bt.nonRecPreOrder(bt.root);
System.out.println("***非递归实现****(中序遍历)[DBEACF]遍历*****************");
bt.nonRecInOrder(bt.root);
System.out.println("***非递归实现****(后序遍历)[DEBFCA]遍历*****************");
bt.noRecPostOrder(bt.root);
}
// 前序遍历的非递归实现
private void nonRecPreOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node=p;
while(node!=null||stack.size()>0){
while(node!=null){
visted(node);
stack.push(node);
node=node.leftChild;
}
while(stack.size()>0){
node=stack.pop();
node=node.rightChild;
}
}
}
// 中序遍历的非递归实现
public void nonRecInOrder(TreeNode p){
Stack<TreeNode> stack =new Stack<BinaryTree.TreeNode>();
TreeNode node = p;
while(node!=null||stack.size()>0){
//存在左子树
while(node != null){
stack.push(node);
node = node.leftChild;
}
//栈非空
if(stack.size()>0){
node = stack.pop();
visted(node);
node = node.rightChild;
}
}
}
// 后序遍历的非递归实现
public void noRecPostOrder(TreeNode p){
Stack<TreeNode> stack=new Stack<BinaryTree.TreeNode>();
TreeNode node = p;
while(p!=null){
//左子树入栈
for(;p.leftChild!=null;p=p.leftChild){
stack.push(p);
}
//当前结点无右子树或右子树已经输出
while(p!=null&&(p.rightChild==null||p.rightChild==node)){
visted(p);
//纪录上一个已输出结点
node =p;
if(stack.empty())
return;
p = stack.pop();
}
//处理右子树
stack.push(p);
p = p.rightChild;
}
}
}
转载地址 :http://blog.csdn.net/ma0ogrubby/article/details/52210147