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