算法导论学习笔记(四):搜索算法

转载请注明原作者 @yoshino
更新不及时,有空慢慢写吧,原文是写在Bear上粘贴来的,可能格式有点乱。
具体的工程在我的github上。


默认都是查找target值,返回索引值,若返回值为-1说明没有找到

顺序查找(Order Search)

  • 没什么好说的,就是遍历。
  • 代码实现:
public void OrderSearch(int[] num, int target){
        int pos=-1;
        for (int i = 0; i 

二分查找(Binary Search)

  • 又称为折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
  • 时间复杂度O(log2n)
  • 代码实现:
private int[] initBinarySearch(int[] num) {//采用冒泡排序把无序表变成有序的
        for (int i = 0; i < num.length; i++)
            for (int j = 0; j < num.length; j++) {
                if (num[i] < num[j]) {
                    int temp = num[i];
                    num[i] = num[j];
                    num[j] = temp;
                }
            }
        return num;
    }

    public void BinarySearch(int[] n, int target) {
        int[] num = initBinarySearch(n);
        int low = 0;
        int high = num.length - 1;
        int mid = (low + high) / 2;
        int pos = -1;
        while ((low <= high) && (low <= num.length - 1) && (high <= num.length - 1)) {
            if (num[mid] < target) {
                low = mid + 1;
                mid = (low + high) / 2;
            }
            if (num[mid] > target) {
                high = mid - 1;
                mid = (low + high) / 2;
            }
            if (num[mid] == target) {
                pos = mid;
                break;
            }
        }
        System.out.println(pos);
    }

插值查找

  • 其实是二分查找的优化法,基于自适应的方法,代码和二分查找类似,仅仅改变mid的算法,同样的方式还有斐波那契查找
  • 查找成功或者失败的时间复杂度均为O(log 2 (log 2 n))
mid=low+ (target-num[low])/(num[high]-num[low]) *(high-low)

二叉树查找(Binary Search Tree)

  • 二叉查找树满足下面性质:
  1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 任意节点的左、右子树也分别为二叉查找树。
  4. 没有键值相等的节点(no duplicate nodes)。
  • 这部分的参考资料来自二叉搜索树的Java实现,作者:darkhorse-pxf
  • 代码实现:
private Node root=null;
    private class Node {
        public Node parent=null;
        public Node leftChild=null;
        public Node rightChild=null;
        int key;

        public Node(int data) {
            this.key=data;
        }
    }
    private void buildTree(int[] datas) {
        for (int i = 0; i < datas.length; i++) {
            Node node=new Node(datas[i]);
            insertNode(node);
        }
    }
    private void insertNode(Node node) {    //插入结点
        Node next=this.root;
        Node cur=null;    //用来保存当前结点
        while(next!=null){    //当到达叶子结点时,确认位置!
            cur=next;
            if(node.key>=cur.key){
                next=next.rightChild;
            }else{
                next=next.leftChild;
            }
        }
        node.parent=cur;    //插入该结点!
        if(cur==null){
            this.root=node;  //该树为空树,所以这个是根节点
        }else if(node.key>=cur.key){
            cur.rightChild=node;
        }else{
            cur.leftChild=node;
        }
    }
    private Node searchNode(Node node){    
        if(node==null){
            System.out.println("empty input!");
        }else{
            if(root==null){
                System.out.println("empty tree!");
            }else{                        //开始查找
                boolean isFound=false;
                Node x=root;
                Node y=null;
                while(!isFound&&x!=null){    //当查到或者到了叶子节点还没查到时,终结!
                    y=x;
                    if(node.key==x.key){
                        isFound=true;
                    }else{                    //通过比较大小往下面查找
                        if(node.key>x.key){
                            x=x.rightChild;
                        }else{
                            x=x.leftChild;
                        }
                    }
                }
                if(isFound){    //没找到的话,在最后返回null
                    return y;
                }
            }
        }
        return null;
    }
    public void BinaryTreeSearch(int[] data,int target){
        buildTree(data);//建立二叉搜索树
        System.out.println("The number you want to find is "+target);
        Node node;
        if((node=searchNode(new Node(target)))==null){
            System.out.println("The num does not exist!");
        }else{
            System.out.println("We find "+node.key+" in this tree successfully!");
        }
    }

你可能感兴趣的:(算法导论学习笔记(四):搜索算法)