学习笔记—查找

线性表查找

顺序查找

  存储结构可以是顺序表,也可以是链表。

  逐个比较查询,如果找到,返回数据或者索引,如果没有找到,返回null。

    /**
     * 时间复杂度  T(n) = O(n)
     * 空间复杂度  S(n) = O(1)
     * @param arr 待查找的数组
     * @param num    查找的值
     * @return 如果找到,返回索引;如果未找到,返回-1
     */
    public static int search(int [] arr,int num) {
        int index = -1;
        for(int i = 0; i < arr.length; i ++) {
            if(arr[i] == num) {
                index = i;
                break;
            }
        }
        return index;
    }

 

 

折半查找

   折半查找又称为二分查找。

  这种查找方法查找效率高,但查找表必须满足两个条件:

  (1) 查找表必须采用 顺序存储结构

  (2) 查找表内元素必须按大小有序排列

  不使用递归

    /**
     * 不使用递归的折半查找
     * T(n) = O (logn)
     * S(n) = O (1)
     * @param array 待查找的数组
     * @param key   查找的值
     * @return  如果找到,返回索引;如果未找到,返回-1
     */
    public static int binarySearch(int[] array,int key) {
        // 指定low 和 high
        int low = 0;
        int high = array.length - 1;
        // 折半查找
        while (low <= high) {
            // 求得mid
            int mid = (low + high) / 2;
            // 判断是否等于
            if(key == array[mid]) {
                return mid;
            } else if (key < array[mid]) {
                high = mid -1;
            } else {
                low = mid + 1;
            }
        }
        return -1;
    }

 

  使用递归

    /**
     * 使用递归的折半查找
     * T(n) = O (logn)
     * S(n) = O (1*logn)
     * @param array 待查找的数组
     * @param key   查找的值
     * @return  如果找到,返回索引;如果未找到,返回-1
     */
    public static int binarySearch(int [] array,int key) {
        // 指定low 和 high
        int low = 0;
        int high = array.length - 1;
        return binarySearch(array,key,low,high);
    }
    
    public static int binarySearch(int[] array,int key,int low, int high) {
        // 递归结束条件
        if(low > high) {
            return -1;
        }
        int mid = (low + high) / 2;
        if(key == array[mid]) {
            return mid;
        } else if(key < array[mid]) {
            return binarySearch(array,key,low,mid-1);
        } else {
            return binarySearch(array,key,mid+1,high);
        }
    }

 

查找树

 二叉查找/搜索/排序树  BST (binary search/sort tree)

  或者是一棵空树;

  或者是具有下列性质的二叉树:

  (1) 若它的左子树不空,则左子树上所有结点的值均不大于它的根结点的值;

  (2) 若它的右子树不空,则右子树上所有结点的值均不小于它的根结点的值;

  (3) 它的左、右子树也分别为二叉排序树。

  对二叉查找树进行中序遍历,可得到有序集合。

 

二叉平衡树(Self-balancing binary search tree)

  自平衡二叉查找树 又被称为AVL树(有别与ALV算法)

  或者是一棵空树;

  或它的左右两个子树的高度差(平衡因子)的绝对值不超过1,

  并且左右两个子树都是一棵平衡二叉树

  平衡二叉树必定是二叉排序树,反之则不一定。

  

  平衡因子(平衡度)结点的平衡因子是结点的左子树与右子树的高度差。

  

  平衡二叉树的目的是为了减少二叉查找树层次,提高查找速度

  

  平衡二叉树的常用实现方法有AVL、红黑树、替罪羊树、Treap、伸展树等

 

红黑树

  R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它是一种平衡二叉树。红黑树的每个结点上都有存储位表示结点的颜色,可以是红(Red)或黑(Black)。

 

  红黑树的特性:

  (1) 每个结点或者是黑色,或者是红色。

  (2) 根结点是黑色。

  (3) 每个叶子结点(NIL)是黑色。[注意:这里是叶子结点,是指为空(NI或NULL)的叶子结点!]

  (4) 如果一个结点是红色的,则它的子结点必须是黑色的。

  (5) 从一个结点到该结点的子孙结点的所有路径上包含相同数目的黑结点。

  确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

  红黑树的应用比较广泛,主要用它来存储有序的数据,它的时间复杂度是O(log2N),效率非常高。

  它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的:它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目。

  例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虚拟内存的管理,都是通过红黑树去实现的。

 

B树(blanced tree)

  与二叉平衡树相比,是多叉的

  可以降低树的深度,提高查找效率

 

  B树应文件系统的要求而发展起来,大量数据存放在外存中,通常存放在硬盘中。

  由于是海量数据,不可能一次调入内存。因此,要多次访问外存。但硬盘的驱动受机械运动的制约,速度慢。

  B-tree作为索引组织文件,提高访问速度、减少时间。

 

B+树

  在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;

  B+树总是到叶子结点才命中;

 

  数据库的索引的默认数据结构就是采用B+树。

 

B*树

  是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针

posted @ 2019-03-16 19:50  殇灬央  阅读(571)  评论(0编辑  收藏  举报
/* */