二叉树:二叉搜索树

所谓二叉树,就是一个节点最多只能有两个子节点,而二叉搜索树就是一个经典并简单的二叉树.规则是一个节点的左子节点一定比自己小,右子节点一定大于等于自己(当然也可以反过来).在树基本平衡的时候插入,搜索和删除速度都很快,时间复杂度为O(logN).但是,如果插入的是有序的数据,那效率就会变成O(N),在这个时候,树其实变成了一个链表.

tree代码:

public class Tree {
private Node root;

/**
* 插入节点
* @param data
*/
public void insert(int data){
Node node = new Node(data);

if(this.root == null){
this.setRoot(node);
return;
}

Node current = this.root;

while(true){
if(current.getData() > data){
if(current.hasLeft()){
current = current.getLeft();
}else{
current.setLeft(node);
return;
}
}else if(current.getData() < data){
if(current.hasRight()){
current = current.getRight();
}else{
current.setRight(node);
return;
}
}else{
return;
}
}
}

/**
* 删除节点
* @param key
*/
public void remove(int key){
Node node = this.findNode(key);

if(node == null){
return;
}

Node parent = node.getParent();

//要删除的节点没有子节点
if(!node.hasLeft() && !node.hasRight()){
if(parent == null){
this.setRoot(null);
}else if(node.isLeft()){
parent.setLeft(null);
}else{
parent.setRight(null);
}
//要删除的节点只有一个子节点
}else if(!node.hasRight() || !node.hasLeft()){
Node child = node.hasLeft() ? node.getLeft() : node.getRight();

if(parent == null){
this.setRoot(child);
}else if(node.isLeft()){
parent.setLeft(child);
}else{
parent.setRight(child);
}
//要删除的节点有两个子节点
}else{
Node successor = this.getSuccessor(node);

if (parent == null) {
this.setRoot(successor);
} else if (node.isLeft()) {
parent.setLeft(successor);
} else {
parent.setRight(successor);
}
}
}

/**
* 查找
* @param key
*/
public void find(int key){
Node node = this.findNode(key);

if(node != null){
System.out.println("node data is : " + node.getData());
}
}

/**
* 查找节点
* @param key
* @return
*/
private Node findNode(int key){
Node current = this.root;

while(current.getData() != key){
if(current.getData() > key){
if(current.hasLeft()){
current = current.getLeft();
}else{
return null;
}
}else if(current.getData() < key){
if(current.hasRight()){
current = current.getRight();
}else{
return null;
}
}
}

return current;
}

/**
* 找到继任节点,找出删除节点中右树最小的节点,如果删除节点的右节点
* 没有子节点,则返回null
* @param node
* @return
*/
private Node getSuccessor(Node node){
Node current = node.getRight();

while(current.hasLeft()){
current = current.getLeft();
}

if(node.getRight() != current){
Node parent = current.getParent();

if(current.hasRight()){
parent.setLeft(current.getRight());
}else{
parent.setLeft(null);
}

current.setRight(node.getRight());
}

current.setLeft(node.getLeft());

return current;
}

private void setRoot(Node node){
this.root = node;

if(node != null){
node.setParent(null);
}
}
}


node代码:

public class Node {
private int data;
private Node left;
private Node right;
private Node parent;

public Node(int data){
this.data = data;
}

public int getData() {
return data;
}

public void setData(int data) {
this.data = data;
}

public Node getLeft() {
return left;
}

public void setLeft(Node left) {
this.left = left;

if(this.left != null){
this.left.parent = this;
}
}

public Node getParent() {
return parent;
}

public void setParent(Node parent) {
this.parent = parent;
}

public Node getRight() {
return right;
}

public void setRight(Node right) {
this.right = right;

if(this.right != null){
this.right.parent = this;
}
}

public boolean hasRight(){
return this.right != null;
}

public boolean hasLeft(){
return this.left != null;
}

public boolean isRoot(){
return this.parent == null;
}

public boolean isRight(){
return this.parent.right == this;
}

public boolean isLeft(){
return this.parent.left == this;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值