搜索树
搜索:
两种模型:
1.纯Key模型 “看篮子里有没有苹果,没有就可以放一个苹果”
2.Key-Value模型 “通过姓名查找电话,姓名不重复电话可重复”
搜索的结构:
1.搜索树
2.哈希表
3.跳表(了解)
Java中:
Map和Set
搜索-专题
搜索树:
特殊的树(二叉搜索树)纯Key模型
搜索树的中序遍历是有序的(重要)
1.查找/搜索
2.插入
3.删除
在搜索结构中,Key不允许重复
哪些方法是static哪些方法不是static?
类——静态
对象——非静态
搜索树的操作:
1.纯Key模型的搜索树的查找、插入、删除
public class BinarySearchTree{
private static Node{
int key;
Node left;
Node right;
Node(int key){
this.key=key;
}
}
private Node root=null;
public Node search(int key){ //查找
Node cur=root;
while(cur!=null){
if(key==cur.key){
return cur;
}else if(key<cur.key){
return cur.left;
}else{
return cur.right;
}
}
return null;
}
public Node insert(int key){ //插入
//先插入再查找,如果值重复不能插入
Node cur=root;
if(cur==null){
root=new Node(key);
return node;
}
while(cur!=null){
Node parent=null;
if(key==cur.key){
return false;
}else if(key<cur.key){
parent=cur;
cur=cur.left;
}else{
parent=cur;
cur=cur.right;
}
}
Node node=new Node(key);
if(key<parent.key){
parent.left=node;
}else{
parent.right=node;
}
return true;
}
}
2.Key-Value模型的搜索树的查找
public class Contact{
private static class Node{
String name;
String phone;
Node left;
Node right;
}
private Node root=Null;
public String search(String name){
Node cur=root;
while(cur!=null){
int r=name.compareTo(cur.name); //引用类型不能用>=<来比较大小
if(r==0){
return cur.phone;
}else if(r<0){
cur=cur.left;
}else{
cur=cur.right;
}
}
return null
}
}
3.搜索树的删除
设待删除结点为 cur, 待删除结点的双亲结点为 parent
1. cur.left == null
- cur 是 root,则 root = cur.right
- cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
- cur 不是 root,cur 是 parent.right,则 parent.right = cur.right
2. cur.right == null
- cur 是 root,则 root = cur.left
- cur 不是 root,cur 是 parent.left,则 parent.left = cur.left
- cur 不是 root,cur 是 parent.right,则 parent.right = cur.left
3. cur.left != null && cur.right != null
替换法:或者左子树中最大的,或者右子树中最小的。将其替换到要删除的位置,然后删除其。
public boolean remove(int key){ //删除
Node cur=root; //要删除先查找
Node parent=null;
while(cur!=null){
if(key==cur.key){ //找到了进行删除
reMove(cur,parent);
return true;
}else if(key<cur.key){
parent=cur;
cur=cur.left;
}else{
parent=cur;
cur=cur.right;
}
return false;
}
private void reMove(Node cur,Node parent){
if(cur.left==null){
if(cur==root){
root=cur.right;
}else if(parent.left==cur){
parent.left=cur.right;
}else{
parent.right=cur.right;
}
}else if(cur.right==null){
if(cur==root){
root=cur.left;
}else if(parent.left==cur){
parent.left=cur.left;
}else{
parent.right=cur.left;
}
}else{ //替换法
Node goat=cur.right;
Node goatParent=null;
while(goat.left!=null){ //找到替罪羊
goatParent=goat;
goat=goat.left;
}
cur.key=goat.key //替换
if(goatParent.left==goat){
goatParent.left=goat.right;
}else{
goat.Parent.right=goat.right;
}
}
}
链表和树的对比:
ListNode——TreeNode
LinkedList——Tree
ListNode head——TreeNode root