1二叉搜索树的定义:树中不能有相同的数据
若它的左子树不为空,则左子树的所有结点的值都小于根结点的值;
若它的右子树不为空,则右子树的所有结点的值都大于根结点的值;
他的右左子树也是二叉搜索树
上代码:
static class Node
{ int data;
public Node(int data)
{
this.data=data;
}
Node left;
Node right;
}
static class Searchtree {
Node root=null;
public Node search(int data)
{ if(root==null)
{
return null;
}
Node current=root;
while(current!=null)
{
if(current.data==data)
{
return current;
}else if(current.data>data)
{
current=current.left;
}else
{
current=current.right;
}
}
return null;
}
public boolean put(int data)//二叉搜索树的插入,每次一定都插到了叶子节点处的位置,注意一种情况
{ Node node=new Node(data); //如果原来的二叉搜索树里面有data数据,那一定就插入失败啦.况且还要定义一个节点,定义上一个节点
if(root==null)
{ root=node;
// root.data=data;
return true;
}
Node front=null;
Node current=root;
while(current!=null){
if(current.data==data)
{
return false;//二叉搜索树的数据是不可以和data值相同
}else if(current.data > data){
front=current;
current=current.left;
}else{
front=current;
current=current.right;
}
}
if(front.data>data) {//此时的front一定是叶子结点
front.left=node;
}
else {
front.right=node;
}
return true;
}
public void show()//二叉树的层序遍历
{
Queue <Node> queue=new LinkedList();
if(root==null) return;
Node current=root;
queue.offer(root);
while(!queue.isEmpty())
{
Node top=queue.poll();
System.out.println(top.data);
if(top.left!=null)
{
queue.offer(top.left);
}
if(top.right!=null)
{
queue.offer(top.right);
}
}
}
下面我们来介绍一下,二叉搜索树的删除(难点)
先找到对应删除的节点
删除操作真的非常复杂(先查找要删除的节点,查找到后,还要知道双亲结点)
cur表示要删除的节点
1 cur.left==null
(1) cur==root;
(2) cur=parent.left;
(3) cur=parent.right;
2 cur.right==null
(1) cur==root;
(2) cur=parent.left;
(3) cur=parent.right;
3 cur.right!=null&&cur.left!=null
1)重点:就要用到替罪羊方法(找右树最左面的节点)(也可以找左树最右面的节点)然后互换;
这个法则又分为进入循环和没有进行到循环
2)注意当我们找右树最左边的节点的时候Node,虽然他是右树最左边的结点,但是他的右树可能还是有数据的
parent=current;
child=current.left;
//不可以这么写
parent=current.right;
child=parent.left;
删除的代码如下:
public void delete(Node current,Node parent)
{
if(current.left==null)
{
if(current==root)
{
root=root.right;
return;
}
else if(current==parent.left)
{
parent.left=current.right;
return;
}
else{
parent.right=current.right;
return;
}
}
else if(current.right==null)
{
if(current==root)
{
root=root.left;
return;
}else if(current==parent.left)
{
parent.left=current.left;
return;
}
else
{
parent.right=current.left;
return;
}
}
else
{
Node parent1=current;
Node current1=current.right;
while(current1.left!=null)
{
current=current.left;
parent1=current1;
}
current.data=current1.data;
if(parent1.right==current1)
{
parent1.right=current1.right;
return;
}
else
{
parent1.left=current1.right;
return;
}
}
}
public void removeall(int data)
{ if(root==null) return;
Node current=root;
Node parent=null;
while(current!=null)
{
if(current.data==data)
{
delete(current,parent);
return;
}
else if(current.data<data)
{ parent=current;
current=current.right;
}else
{
parent=current;
current=current.left;
}
}
}
public void show()
{
Queue <Node> queue=new LinkedList();
if(root==null) return;
Node current=root;
queue.offer(root);
while(!queue.isEmpty())
{
Node top=queue.poll();
System.out.print(" "+top.data);
if(top.left!=null)
{
queue.offer(top.left);
}
if(top.right!=null)
{
queue.offer(top.right);
}
}
}
}
变成完全二叉树的情况最好logN,不好的情况下会变成单分支的树,高度变成但分值的树
但是AVL树要不断进行旋转