二叉树的java实现

网上看到的一个二叉树,自己放到myeclipse实现了一下,但具体的在什么场景下应用还不太清楚,网上也没有找到相应的文章介绍。又重新修改了一下,还是有些地方不太明白。在建立二叉树的时候传入的数组的顺序怎么确定?一个很困扰的问题!

package algorithm;

import java.util.Stack;

/**
* May 27, 2009
* version 1.1
*/

public class BinaryTree {
// Root node pointer. Will be null for an empty tree.
private Node root ;
private static class Node {
Node left ;
Node right ;
int data ;
Node( int newData) {
left = null ;
right = null ;
data = newData;
}
}
/**
Creates an empty binary tree -- a null root pointer.
*/

public BinaryTree() {
root = null ;
}
/**
Inserts the given data into the binary tree.
Uses a recursive helper.
*/
public void insert( int data) {
// System.out.println(data);
root = insert( root , data);
}
/**
Recursive insert -- given a node pointer, recur down and
insert the given data into the tree. Returns the new
node pointer (the standard way to communicate
a changed pointer back to the caller).
二叉搜索树
*/

private Node insert(Node node, int data) {
if (node== null ) {
node = new Node(data);
}else {
if (data <= node. data ) {
// System.out.println("left:"+data);
node. left = insert(node. left , data);
}else {
// System.out.println("right:"+data);
node. right = insert(node. right , data);

}
}
return (node); // in any case, return the new pointer to the caller
}

public void buildTree( int [] data){
for ( int i=0;i<data.length ;i++){
insert(data[i]);
}

}

public void printTree() {
afterErgodic( root );
System. out .println();
}

private void printTree(Node node) {
if (node == null ) return ;
// left, node itself, right
printTree(node. left );
System. out .print(node. data + " " );
printTree(node. right );
}

/**
* 先序遍历
* @param node
*/
public void preErgodic(Node node){
if(node==null){
return;
}
Stack sk=new Stack();
Node p=node;
while(p!=null){
//把p节点的左子树的左子树的值获取出来
//把p节点的右子节点入栈,最上面的是右叶子节点
//栈底的节点为根的右子节点
while(p!=null){
System.out.print(p.data+" ");
//右子树入栈
if(p.right!=null) sk.push(p.right);
//进入下一个左子树
p=p.left;
}
//遍历右子树,从右叶子节点开始,然后往上,若有左子节点,则执行上面的while步骤
if(!sk.isEmpty()){
//进入下一个右子树
p=(Node)sk.pop();
// System.out.print(p.data+ " ");
}
}
}

/**
* 中序遍历
* @param node
*/
public void centerErgodic(Node node){
if(node==null){
return;
}
Stack sk=new Stack();
Node p=node;
while(p!=null||!sk.isEmpty()){
//把p节点的左子节点入栈,最上面的是左叶子节点
while(p!=null){
sk.push(p);
p=p.left;
}
//第一步是先把左叶子节点出栈,此时右节点为null
//第二步是把左叶子节点的父节点出栈,此时的右节点则是右叶子节点
//第三步则是把左叶子节点的父节点的父节点出栈,此时右节点含有子节点
//第四步开始则是对右节点开始遍历,步骤则是重复前三步
//第五步则是重复执行第三步和第四步,直到sk里面无节点为止
if(!sk.isEmpty()){
p=(Node)sk.pop();
System.out.print(p.data+" ");
p=p.right;
}
}
}
/**
* 后序遍历
* @param node
*/
public void afterErgodic(Node node){
if(node==null){
return;
}
Stack sk=new Stack();
Node p=node;

while(p!=null||!sk.isEmpty()){
//先左后右不断深入
while(p!=null){
sk.push(p);//将根节点入栈
if(p.left!=null) p=p.left;
else p=p.right;
}

//这里主要是叶子节点的获取
if(!sk.isEmpty()){
p=(Node)sk.pop();
System.out.print(p.data+" ");
}

//满足条件时,说明栈顶根节点右子树已访问,应出栈访问之
//这里肯定是非叶子节点
while(!sk.isEmpty()&&((Node)sk.peek()).right==p){
p=(Node)sk.pop();
System.out.print(p.data+" ");
}
//转向栈顶根节点的右子树继续后序遍历
if(!sk.isEmpty()) p=((Node)sk.peek()).right;
else p=null;
}
}

/**
* 另外一种建立二叉树的方法,非递归形式
* @param data
*/
public void createBinary(int[] data){
Node temp = null;
for(int i=0;i<data.length;i++){
// 创建根节点
if(root==null){
root = temp = new Node(data[i]);
}else{
// 回到根结点
temp=root;
// 添加节点
while (temp.data != data[i]) {
if(temp.data>data[i]){//左子树
if (temp.left != null) {
// System.out.println(data[i]+" "+22);
//如果有左子树,则把左子树赋值给temp,此次while循环结束,开始下次循环。
//直到没有左子树为止,即新增加一个左子树
temp = temp.left;
}else{
//新增左子树
// System.out.println(data[i]+" "+11);
temp.left=new Node(data[i]);
//这里可以减少循环的次数,新增之后再判断时则会跳出循环
temp = temp.left;
}
}else{//右子树
if(temp.right!=null){
//同左子树
temp = temp.right;
}else{
temp.right=new Node(data[i]);
//同上
temp = temp.right;
}
}
}
}
}
// return root;
}


/**
* @param args
*/
public static void main(String[] args) {
BinaryTree bt=new BinaryTree();
//数据貌似不能是排好序的,但必须有顺序,貌似是前序遍历的顺序
int[] array={4, 2, 6, 1, 3, 5, 7};
// bt.buildTree(array);
bt.createBinary(array);
bt.printTree();
// # 4
// # / \
// # 2 6
// # / \ / \
// # 1 3 5 7
// # 前序遍历:4 2 1 3 6 5 7
// # 中序遍历:1 2 3 4 5 6 7
// # 后序遍历:1 3 2 5 7 6 4
}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
平衡二叉树(AVL树)是一种自平衡的二叉搜索树,它的左子树和右子树的高度差不超过1。在Java中,可以通过以下步骤实现平衡二叉树: 1. 定义节点类:首先定义一个节点类,包含节点值、左子节点和右子节点等属性。 ```java class Node { int value; Node left; Node right; public Node(int value) { this.value = value; this.left = null; this.right = null; } } ``` 2. 实现平衡二叉树类:创建一个平衡二叉树类,包含插入节点、删除节点、旋转操作等方法。 ```java class AVLTree { private Node root; // 插入节点 public void insert(int value) { root = insertNode(root, value); } private Node insertNode(Node root, int value) { if (root == null) { return new Node(value); } if (value < root.value) { root.left = insertNode(root.left, value); } else if (value > root.value) { root.right = insertNode(root.right, value); } else { // 如果存在相同值的节点,可以根据需求进行处理 return root; } // 更新节点的高度 root.height = 1 + Math.max(getHeight(root.left), getHeight(root.right)); // 平衡操作 int balance = getBalance(root); // 左左情况,进行右旋操作 if (balance > 1 && value < root.left.value) { return rightRotate(root); } // 右右情况,进行左旋操作 if (balance < -1 && value > root.right.value) { return leftRotate(root); } // 左右情况,先左旋再右旋 if (balance > 1 && value > root.left.value) { root.left = leftRotate(root.left); return rightRotate(root); } // 右左情况,先右旋再左旋 if (balance < -1 && value < root.right.value) { root.right = rightRotate(root.right); return leftRotate(root); } return root; } // 删除节点 public void delete(int value) { root = deleteNode(root, value); } private Node deleteNode(Node root, int value) { // 空树或未找到节点 if (root == null) { return root; } if (value < root.value) { root.left = deleteNode(root.left, value); } else if (value > root.value) { root.right = deleteNode(root.right, value); } else { // 找到要删除的节点 // 节点只有一个子节点或无子节点 if (root.left == null || root.right == null) { Node temp = null; if (temp == root.left) { temp = root.right; } else { temp = root.left; } // 无子节点的情况 if (temp == null) { temp = root; root = null; } else { // 一个子节点的情况 root = temp; } } else { // 节点有两个子节点,找到右子树中最小的节点 Node temp = minValueNode(root.right); // 将右子树中最小节点的值赋给要删除的节点 root.value = temp.value; // 删除右子树中最小的节点 root.right = deleteNode(root.right, temp.value); } } // 更新节点的高度 root.height = 1 + Math.max(getHeight(root.left), getHeight(root.right)); // 平衡操作 int balance = getBalance(root); // 左左情况,进行右旋操作 if (balance > 1 && getBalance(root.left) >= 0) { return rightRotate(root); } // 左右情况,先左旋再右旋 if (balance > 1 && getBalance(root.left) < 0) { root.left = leftRotate(root.left); return rightRotate(root); } // 右右情况,进行左旋操作 if (balance < -1 && getBalance(root.right) <= 0) { return leftRotate(root); } // 右左情况,先右旋再左旋 if (balance < -1 && getBalance(root.right) > 0) { root.right = rightRotate(root.right); return leftRotate(root); } return root; } // 获取节点的高度 private int getHeight(Node node) { if (node == null) { return 0; } return node.height; } // 获取节点的平衡因子 private int getBalance(Node node) { if (node == null) { return 0; } return getHeight(node.left) - getHeight(node.right); } // 右旋操作 private Node rightRotate(Node y) { Node x = y.left; Node T2 = x.right; x.right = y; y.left = T2; y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1; x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1; return x; } // 左旋操作 private Node leftRotate(Node x) { Node y = x.right; Node T2 = y.left; y.left = x; x.right = T2; x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1; y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1; return y; } // 获取最小值节点 private Node minValueNode(Node node) { Node current = node; while (current.left != null) { current = current.left; } return current; } } ``` 以上是一个简单的平衡二叉树Java实现,包括插入节点、删除节点、旋转操作等方法。你可以根据需要进行调整和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值