查找算法

Oudasheng 2019-12-30

目前不断更新中,算法描述图有时间补上

//查找使用ASL平均查找长度来判断算法的性能  ASL=ΣPiCi (i∈[1,n])

//线性表的查找
template<class T>
class Search {
public:
    //顺序查找:
    //条件: 无
    //思想:从后往前与要查找的值比较,设置一个哨兵简化算法
    //查找成功的情况下 平均查找长度ASL=(n+1)n/2n=(n+1)/2   
    //查找不成功ASL=n+1
    int SeqSearch(T a[],int n,T key){
        int i;
        a[0] = key;  //设置哨兵,如果返回的值为0的话说明查找失败
        for ( i = n; a[i] != key; i--);
        return i;
    }

    //折半查找:
    //条件: 关键码有序
    //思想:设置变量low,high分别指向最高和最低值,令mid=(high+low)/2,将mid与key比较,可以根据大小判断位于哪个区域,逐渐缩小
    //以十个元素为例,查找第5个元素需要比较1次,第2、8元素需要2次,1、3,6,9需要3次,4、7需要4次,可以将其看为一个完全二叉树,称为判定树
    //那么深度与判定树的深度相同
    //查找成功 Σj*2^(j-1)/n [1,h] (Σ2^t [1,h] <= n)  当n>50 ASL≈log2(n+1) - 1
    //查找失败 ASL=log2 n + 1   注意:关键码排序即使最好的方法时间复杂度也是nlog2 n
    int Search_Bin(T a[], int n, T key) {  //非递归式
        int low = 1;
        int high = n;
        while (low <= high) {             //保证低位不大于高位,如果大于则查找失败返回0
            int mid = (low + high) / 2;   //找到最高与最低的中间值,并于key进行比较,如果大于则将低位改为mid+1,小于高位改为mid-1,类推
            if (key == a[mid]) {
                return mid;
            }
            else if (key < a[mid]) {
                high = mid - 1;
            }
            else {
                low = mid + 1;
            }
        }
        return 0;
    }
    int BinSearch(T r[], int low, int high, int k) { //递归式
        if (low < high) {               //通过low<high确定是否查找成功
            int mid = (low + high) / 2;
            if (r[mid] == k) {
                return mid;
            }
            else if (r[mid] > k) {            //通过比较中间值的高低来确定范围
                return BinSearch(r, low, mid - 1,k);  
            }
            else {
                return BinSearch(r, mid + 1, high, k);
            }
        }
        else{              //设置错误的返回码
            return 0;
        }
    }

    //分块查找:
    //思想:设置一个索引表,索引表标明了一定范围的关键码,根据索引来确定范围,再在范围中进行顺序或折半查找
    //将长为n的表分为b块,每块有s条记录
    //如果使用顺序查找ASL = (n/s+s)/2+1
    //折半查找log2(n/s+1)+s/2
    //这部分源码有机会补上

};

//树表的查找
    //二叉排序树:
    //左孩子小于根节点,右孩子大于根节点,他的左右子树也是二叉排序树,按照树的中序遍历就可得到一个有序数列
    //二叉排序树方便进行查找的元素的插入和删除
template<class T>
class Node {
public:
    T data;
    Node<T>* lch;
    Node<T>* rch;
    Node:lch(NULL), rch(NULL){};
};

相关推荐