查找--------二叉树查找(递归和非递归)

 折半查找 (二分查找)

//折半查找
public class BinarySearch {
	   public int binarySearch(int[] arr, int n, int key){
		   int low=1;//从1开始
		   int high=n;
		   while(low<=high){
			   int mid = (low+high)/2; 
			   if (arr[mid]<key) {
				low=mid+1;//进入右半区继续查找
			   }else if (arr[mid]>key) {
				high=mid-1;//进入左半区继续查找
			   }else {
				return mid;
			  }
		   }
		   return 0;
	   }
	   public static void main(String[] args) {
		   int[] arr = {0,1,16,24,35,47,59,62,73,88,99};
	        int n=arr.length-1;
	        int key=62;
	        BinarySearch aSearch = new BinarySearch();
	        System.out.println(aSearch.binarySearch(arr, n, key));
	}
}

二叉树查找

package Search;

/**
 * 二叉排序树(二叉查找树)
 * 若是泛型,则要求满足T extends Comparable<T> static问题
 * @author Yongh
 *
 */
class Node {
    int data;
    Node lChild, rChild;
 
    public Node(int data) {
        this.data = data;
        lChild = null;
        rChild = null;
    }
}
 
public class BSTree {
    private Node root;
 
    public BSTree() {
        root = null;
    }
 
    /*
     * 查找
     */
    public boolean SearchBST(int key) {
        return SearchBST(key, root);
    }
 
    private boolean SearchBST(int key, Node node) {
        if (node == null)
            return false;
        if (node.data == key) {
            return true;
        } else if (node.data < key) {
            return SearchBST(key, node.rChild);
        } else {
            return SearchBST(key, node.lChild);
        }
    }
 
    /*
     * 查找,非递归
     */
    public boolean SearchBST2(int key) {
        Node p = root;
        while (p != null) {
            if (p.data > key) {
                p = p.lChild;
            } else if (p.data < key) {
                p = p.rChild;
            } else {
                return true;
            }
        }
        return false;
    }
 
    /*
     * 插入,非递归
     */
    public boolean InsertBST(int key) {
        Node newNode = new Node(key);
        if (root == null) {
            root = newNode;
            return true;
        }
        Node f = null; // 指向父结点
        Node p = root; // 当前结点的指针
       //找准插入的位置
        while (p != null) {
            if (p.data > key) {
                f = p;
                p = p.lChild;
            } else if (p.data < key) {
                f = p;
                p = p.rChild;
            } else {
                System.out.println("数据重复,无法插入!");
                return false;
            }
        }
        //找到不为null的位置了,比较大小再插入值
        if (f.data > key) {
            f.lChild = newNode;
        } else if (f.data < key) {
            f.rChild = newNode;
        }
        return true;
    }

 /**
     * 
     * 插入方法 非递归
     * 
     */
     public void insert(int data){
    	 Node newNode = new Node(data);
    	 if (root==null) {
			root = newNode;
			return;
		}else{
			Node current = root;
			Node parent;
			while(true){
				parent = current;
				if (data < current.data) {
					current = current.lChild;
					if (current == null) {
						parent.lChild = newNode;
						return;
					}
				}else {
					current = current.rChild;
					if (current == null) {
						parent.rChild = newNode;
						return;
					}
				}
			}
		}
     }
 
    /*
     * 插入,参考别人博客,递归
     * 思路:类似查找,
     *       但若方法中的node为null的话,将无法插入新数据,需排除null的情况
     */
    public boolean InsertBST2(int key) {
        if (root == null) {
            root = new Node(key);
            return true;
        }
        return InsertBST2(key, root);
    }
 
    private boolean InsertBST2(int key, Node node) {
        if (node.data > key) {
            if (node.lChild == null) { // 有null的情况下,才有父结点
                node.lChild = new Node(key);
                return true;
            } else {
                return InsertBST2(key, node.lChild);
            }
        } else if (node.data < key) {
            if (node.rChild == null) {
                node.rChild = new Node(key);
                return true;
            } else {
                return InsertBST2(key, node.rChild);
            }
        } else {
            System.out.println("数据重复,无法插入!");
            return false;
        }
    }
 
    /*
     * 这样的插入是错误的(node无法真正被赋值)
     */
    /*
    private boolean InsertBST2(int key, Node node) {
        if(node!=null) {
            if (node.data > key)
                return InsertBST2(key, node.lChild);
            else if (node.data < key)
                return InsertBST2(key, node.rChild);
            else
                return false;//重复
        }else {
            node=new Node(key);
            return true;
        }          
    }
    */
 
    /*
     * 删除操作,先找到删除结点位置及其父结点
     * 因为需要有父结点,所以暂时没想到递归的方法(除了令Node对象带个parent属性)
     */
    public boolean deleteBST(int key) {
        if (root == null) {
            System.out.println("空表,删除失败");
            return false;
        }
        Node f = null; // 指向父结点
        Node p = root; // 指向当前结点
        while (p != null) {
            if (p.data > key) {
                f = p;
                p = p.lChild;
            } else if (p.data < key) {
                f = p;
                p = p.rChild;
            } else {
                delete(p, f);
                System.out.println("删除成功!");
                return true;
            }
        }
        System.out.println("该数据不存在");
        return false;
    }
 
    /*
     * 删除结点P的操作
     * 必须要有父结点,因为Java无法直接取得变量p的地址(无法使用*p=(*p)->lChild)
     */
    private void delete(Node p, Node f) {// p为删除结点,f为其父结点
        if (p.lChild == null) { // 左子树为空,重接右子树
            if (p == root) { // 被删除结点为根结点,该情况不能忽略
                root = root.rChild;
                p = null;
            } else {
                if (f.data > p.data) { // 被删结点为父结点的左结点,下同
                    f.lChild = p.rChild;
                    p = null; // 释放结点别忘了
                } else {// 被删结点为父结点的右结点,下同
                    f.rChild = p.rChild;
                    p = null;
                }
            }
        } else if (p.rChild == null) { // 右子树为空,重接左子树
            if (p == root) { // 被删除结点为根结点
                root = root.lChild;
                p = null;
            } else {
                if (f.data > p.data) {
                    f.lChild = p.lChild;
                    p = null;
                } else {
                    f.rChild = p.lChild;
                    p = null;
                }
            }
        } else { // 左右子树都不为空,删除位置用前驱结点替代
            Node q, s;
            q = p;
            s = p.lChild;
            while (s.rChild != null) { // 找到待删结点的最大前驱s
                q = s;
                s = s.rChild;
            }
            p.data = s.data; // 改变p的data就OK
            if (q != p) {
                q.rChild = s.lChild;
            } else {
                q.lChild = s.lChild;
            }
            s = null;
        }
    }
 
    /*
     * 中序遍历
     */
    public void inOrder() {
        inOrder(root);
        System.out.println();
    }
 
    public void inOrder(Node node) {
        if (node == null)
            return;
        inOrder(node.lChild);
        System.out.print(node.data + " ");
        inOrder(node.rChild);
    }
 
    /*
     * 测试代码
     */
    public static void main(String[] args) {
        BSTree aTree = new BSTree();
        BSTree bTree = new BSTree();
        int[] arr = { 62, 88, 58, 47, 35, 73, 51, 99, 37, 93 };
        for (int a : arr) {
            aTree.InsertBST(a);
            bTree.InsertBST2(a);
        }
        aTree.inOrder();
        bTree.inOrder();
        System.out.println(aTree.SearchBST(35));
        System.out.println(bTree.SearchBST2(99));
        aTree.deleteBST(47);
        aTree.inOrder();
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值