package cn.dataStructures.BinarySerachTree;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class BST1 <E extends Comparable<E>>{
private class Node{
public Node left,right;
public E e;
public Node(E e){
this.e=e;
left=null;
right=null;
}
}
public int size;
public Node root;
public BST1(){
root=null;
size=0;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
//向树中添加元素
public void add(E e){
// if(root==null){
// root=new Node(e);
// size++;
// return;
// }
root=add(root,e);
}
private Node add(Node node,E e){
if(node==null){
size++;
return new Node(e);
}
else if(e.compareTo(node.e)<0){
Node left=add(node.left,e);//如果小于树中的元素,则向该节点的左子树插入元素,此节点为根节点,
//再继续判断是否为空,如果是直接创建新节点并将值插入
size++;
}
else if(e.compareTo(node.e)>0){
Node right=add(node.right,e);
size++;
}
return node;
}
//查询元素
public boolean contains(E e){
return contains(root,e);
}
private boolean contains(Node node,E e){
if(node==null){
return false;
}
if(e.compareTo(node.e)==0){
return true;
}
else if(e.compareTo(node.e)>0){
return contains(node.right,e);
}
else if(e.compareTo(node.e)<0){
return contains(node.left,e);
}
return false;
}
//遍历元素--前序遍历---先遍历节点元素--》左子树--》右子树
public void preOrder(){
preOrder(root);
}
public void preOrder(Node node){
if(node==null){
return;
}
System.out.println(node.e);
preOrder(node.left);
preOrder(node.right);
}
//前序遍历非递归----利用栈结构
public void preOrderNR(){
Stack<Node> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
Node cur=stack.pop();
System.out.println(cur.e);
if(cur.left!=null){
stack.push(cur.right);
}
if(cur.left!=null){
stack.push(cur.left);
}
}
}
// 前序遍历---层序遍历(广度优先遍历)-队列
public void leveOrder(){
Queue<Node> q=new LinkedList<>();
q.add(root);
while(!q.isEmpty()){
Node cur=q.remove();
System.out.println(cur.e);
if(cur.left!=null){
q.add(cur.left);
}
if(cur.right!=null){
q.add(cur.right);
}
}
}
//中序遍历--先遍历左子树--》节点元素--》右子树
public void inOrder(){
inOrder(root);
}
public void inOrder(Node node){
if(node==null){
return;
}
inOrder(node.left);
System.out.println(node.e);
inOrder(node.right);
}
//后序遍历--先遍历左子树--》右子树--》节点元素
public void postOrder(){
postOrder(root);
}
public void postOrder(Node node){
if(node==null){
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.println(node.e);
}
//寻找最小节点
public E minimum(){
if(size==0){
throw new IllegalArgumentException("树为空!");
}
Node minNode=minimum(root);
return minNode.e;
}
private Node minimum(Node node){
if(node.left==null){
return node;
}
return minimum(node.left);
}
//寻找最大节点
public E maximum(){
if(size==0){
throw new IllegalArgumentException("树为空!");
}
Node maxNode=maximum(root);
return maxNode.e;
}
private Node maximum(Node node){
if(node.right==null){
return node;
}
return maximum(node.right);
}
//删除二叉树中最小值所在的节点,并返回这个值
public E removeMin(){
E ret=minimum();//调用寻找最小节点的方法(其中已经包含根结点)
root=removeMin(root);
return ret;
}
private Node removeMin(Node node){
//删除以node为跟根的二叉树最小节点
if(node.left==null){
Node rightNode=node.right;
node.right=null;
size--;
return rightNode;
}
removeMin(node.left);
return node;//返回删除最小节点后二叉树新的根
}
//删除二叉树最大值所在的节点并返回这个值
public E removeMax(){
E ret=maximum();
root=removeMax(root);
return ret;
}
private Node removeMax(Node node){
if(node.right==null){
Node leftNode=node.left;
node.left=null;
size--;
return leftNode;
}
removeMax(node.right);
return node;
}
//删除树中任意位置的节点
//思想:先找到这个要删除的节点,通过元素的比较来找该节点,找到该节点后需要对其判断该节点的左子树和右子树是否为空,或者都不为空,这三种情况分别进行操作
public void remove(E e){
root=remove(root,e);
}
private Node remove(Node node,E e){
if(node==null){
return null;
}
if(e.compareTo(node.e)<0){
node.left=remove(node.left,e);
return node;//返回新的二叉树的根
}
if(e.compareTo(node.e)>0){
node.right=remove(node.right,e);
return node;
}
else//e.compareTo(node.e)==0
{
if(node.left==null){
Node rightNode=node.right;
size--;
node.right=null;
return rightNode;//将rightNode的节点设为最新二叉树的根节点
}
if(node.right==null){
Node leftNode=node.left;
size--;
node.left=null;
return leftNode;
}
else{
Node successor=new Node(minimum(node.right).e);//把改节点右子树的最小节点赋值给successor
size++;
successor.right=removeMin(node.right);//吧succssor的右子树设置为要删除节点的右子树
successor.left=node.left;//把要删除的节点node的左子树赋值给successor的左子树
node.left=node.right=null;//将要删除的左子树和右子树置空
size--;
return successor;
}
}
}
}
二叉树代码实现
猜你喜欢
转载自blog.csdn.net/lpq1201/article/details/80510506
今日推荐
周排行