学习笔记——查找

好久不见. 提交于 2019-11-29 16:36:33

目录

 

顺序查找

折半查找

二叉排序树

散列表


顺序查找

算法思想不必赘述。

ASL成功=Σ(i=1~n)pi*ci,其中ci是查找到元素i需要进行比较的次数,pi一般取1/n。

ASL不成功=n,即遍历所有元素都没有找到目标关键字,有的序列会增加一个元素用来判断是否达到尾部或者防止溢出,这时候ASL不成功=n+1

折半查找

int Bsearch(int a[],int low,int high,int mid)
{
    int mid;
    while(left<=right)
    {
        mid=(left+right)/2;
        if(a[mid]==key)
            return mid;
        else if(a[mid]<k)
            left=mid+1;
        else right=mid-1;
    }
    return 0;
}

ASL成功=Σ目标关键词在判定树中的层数/数组长度

ASL不成功=Σ(叶子节点层数+1)/空指针数

二叉排序树

定义:若左子树不为空,则左子树上的节点都小于根节点的关键字;若右子树不为空,则右子树上的节点都大于根节点的关键字。

/*查找关键字的算法*/
BTNode BSTSearch(BTNode* bt,int key)
{
    if(bt==NULL)
        return NULL;
    else
    {
        if(bt->data==key)
            return bt;
        else if(bt->data<key)
            return BSTSearch(bt->lchild,key);
        else
            return BSTSearch(bt->rchild,key);
    }
}
/*插入关键字的算法*/(只能插入在叶子节点的左右孩子处,即bt==null处)
BTNode BSTInsert(BTNode* bt,int key)
{
    if(bt==NULL)
    {
        bt=(*BTNode)malloc(sizeof(BTNode));
        bt->lchild=NULL;
        bt->rchild=NULL;
        bt->data=key;
        return 1;
    }
    else
    {
        if(bt->data==key)    //关键字已存在,插入失败
            return 0;
        else if(bt->data<key)
            return BSTSearch(bt->lchild,key);
        else
            return BSTSearch(bt->rchild,key);
    }
}
/*创建排序树*/(就是反复调用插入关键字算法)
void CreateBST(BTNode *&bt,int key[],int n)
{
    bt=NULL;
    for(int i=0;i<n;i++)
        BSTInsert(bt,key[i]);
}

二叉排序树的删除

1)若删除的是叶子节点,不会破坏二叉树特性,直接删除即可。

2)若删除的是非叶子节点,而且是只有左子树或者只有右子树的节点,则将该节点删除,并让左/右孩子取代被删除的节点。(子承父位)

3)若删除的是非叶子节点,而且是左右孩子都有的节点,可以将这种情况转化为1)或2)中的情况。具体做法为:沿着待删节点p,先向左走一步访问左孩子,再一直向右走,直到最右节点r,若r是叶子节点则按照1)来删除,否则按照2)来删除(因为r是最右节点,所以不可能有右孩子,即不存在左右孩子都存在的情况,r是p的前驱)。当然也可以先向右走一步访问右孩子,再一直向左走找到最左节点l,l是p的后继。

平衡二叉树

散列表

常用Hash函数构造方法

①直接定址法

H(key)=a*key+b

②数字分析法

取关键字的若干位组成Hash地址

③平方取中法

取关键字平方后的中间几位作为Hash地址 如key=32,32^2=1024,H(32)=2

④除留余数法

H(key)=key mod p(p为小于或等于表长的最大质数)

解决冲突的方法

开放定址法

①线性探测法

Hi(key)=(H(key)+i) mod m (m是表长)

②平方探测法

Hi(key)=(H(key)±i^2) mod m

链地址法

Hash表每个单元存放的是同义词单链表的头指针,每个链表上挂的都是互为同义词的记录。

ASL成功=Σ各个关键字要访问+执行解决冲突方法多少次才能在散列表中找到/关键字个数

ASL不成功=Σ散列表中每个单元要访问+执行解决冲突方法多少次才能访问到一个为空的单元/Hash函数可以映射到的地址个数(不要和表长混淆,Hash函数能映射的地址不一定能覆盖表中所有地址)

意思就是,如果表中某个单元本来就为空,就是1次,若不为空,就检测它的后继单元,若后继单元为空,就是2次,否则继续检测后继单元,直到找到一个空单元,假如往后探测4次才找到空单元,就是5次(加上一开始访问的那一次)。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!