查找

查找表 Search Tab )是由同一类型的数据元素〈或记录)构成的集合
关键字 (Key) 是数据元素中某个数据项的值,又称为键值
若此关键字可以唯一地标识一个记录,则称此关键字为主关键字
可以识别多个数据元素(或记 )的关键字,我们称为次关键字
查找( Searchìng )就是根据给定的篝个值 在查找亵 确定-个
其关键字等于给定值的数据元素(或记褒)。
静态查找表(如tic Sear ch’ Table) :只作查找操作的查找表。
动态查找表 yna ic Search able): 在查找过程中同时插入查找表中不存在的
数据元素 或者从查找表中删除已经存在的某个数据元素。

1,顺序表查找

下面展示一些 内联代码片

int chazhao(int e)
{
    int i=n;
    a[0]=e;//让a[0]等于要查找的数
    while(a[i]!=a[0])//从后往前,如果不相等就i--
    {
        i--;
    }
    return i;
}

2,有序表查找

二分

基本思想:每次都从数组的中间查找,
如果小,则key在0到mid-1的范围内,如果大,则key在mid+1到n的范围内。
在查找元素大小分别不均匀的数组时性能优于插值查找
下面展示一些 内联代码片
`

int Binaxy_Search (int *a,int n,int key)
{
    int mid,right,left;
    right=n;
    left=0;
    while(left>=right)//当left=right的时候,意味着left《=key《=right,即关键字的位置是left或者right
    {
        min=left+(right-left)/2;//之所以用left+(right-left)/2代替(right+left)是防止超限
        if(a[mid]<key)
        {
            left=mid+1;
        }
        else if(a[mid]>key)
            {
                right=mid-1;
            }
            else return mid;
        
    }
}

插值查找与二分类似,只是插值查找的代码为mid=left+(key-a[left])/(a[right-a[left)*(right-left);
它适合与数组元素大小分布均匀的数组。

斐波那契查找

从黄金分割线处查找,因为科学家对黄金分割线有着独特的热爱,因此在没有任何科学依据的情况下,发明了斐波那契查找,也许可以叫玄学查找。
下面展示一些 内联代码片

`

斐波那契查找的思想是利用黄金分割比例来查找,与二分法差别不大,二分法是对半查找,斐波那契是黄金比例查找(即:每一次都在黄金比例处查找,有点像玄学查找法。。)。
void fibonacci_search(int *a,int key,int n)
{
     int left,right,k,mid,i;
     left=1;//
     right=n;//
     k=0;//
     while(n>f[k]-1)//找到n小于第几个斐波那契数
        k++;
       for(i=n;i<f[k]-1;i++)//如果n不等于该斐波那契数就将缺的数补上
            a[i]=a[n];
        while(left<=right)//
        {
            mid=left+f[k-1]-1;//mid等与黄金比例处的数。
            if(key<a[mid])//
            {
                right=mid-1;//
                k=k-1;//k-1的原因是,key比a[mid]小,所以要查找的数在左半部分,而左半部分的数还剩下f[k]个-++++++++++``+
            }
           else if(key>a[mid])//
            {
             left=mid+1;//
             k=k-2;//减2的原因是,key大于a[mid].此时要查找的数在右半部分,而右半部分还剩下f[k-2]个数
            }
            else {//
                if(mid<=n)//如果mid小于n,说明要找的数,在n内
                    return mid;
                else return n;//否则,mid为前面补齐的数
            }
        }
        return 0;



}

3,线性索引查找

稠密索引是指 线性索引 ,将数据集中的每个 录对应一个索 项,
对于稠密索引这个索引表来说,索引项一定是按照关键码有序的排列。

分块有序,是把数据集的记录分成了若干块,并且这些块需要满足两个条件:块内无序
块间有序

4,二叉排序树

二叉排序树 ,又称为二叉查找树。它或者是一棵空树,或者
是具有下列性质的二叉树
• 若它的左子树不空,则左子树上所有结点的值均小于它的根结构的值
• 若它的右子树不空 ,则右子树上所有结点的值均大于宫的根结点的值;
下面展示一些 内联代码片

typedef struct node
{
    int data;
    struct node *lchild,*rchild;
}bitree;


//二叉排序树的查找//
基本思想:从要查找的树开始,如果key小于关键结点,就向该结点的左子树遍历,如果大于该结点,就向该结点的右子树遍历。
bool serbst(bitree *t,int key,bitree f,bitree **p)//f指向结点的双亲,如果为头结点,则指向空
{
    if(!t)//如果t为空,即未查找到
    {
        *p=f;
        return false;
    }
    else if(t->data==key)
    {
        *p=t;
        return true;
    }
    else if(t->data<key)
    {
        serbst(t->rchild,key,t,p);
    }else  serbst(t->lchild,key,t,p);

}//二叉排序树的插入
基本思想:先查找,看树中有没有这个值,如果有就不用插入了,如果没有,就执行跟查找差不多的方法
bool insert(bitree **t,int key)//因为可能要对根节点赋值,用一级指针的话传递的是形参
{
    bitree *p,*s;
    if(!serbst(t,key,NULL,&p))//如果二叉排序树中没有key,则插入
    {
        s=(bitree *)malloc(sizeof(bitree));
        s->data=key;
        s->rchild=s->lchild=NULL;
        if(!p)//如果树中一个结点都没有,则s为根结点
          *t=s;//
           else if(key<p->data)//如果小于最后返回的p结点,就插到p结点的左方
            s=p->lchild;
        else s=p->rchild;
        return true;
    }
    else//如果树中有该数字,返回错误。
    return false;
}
//创建树
基本思想:其实就是多次执行插入操作
int i;
bitree *t=NULL;
int a[10{1,2,3,4,5,6,7,8,9,10};
for(int i=0;i<10;i++)
{
    insert(t,a[i]);
}
//二叉树的删除
要先在一个函数中找到要删除结点的位置,找到后,看它是不是只有左子树或者只有右子树,如果是的话,就直接让左孩子或者右孩子连上就行。
如果不是,就寻找左子树中最大的值,让该值替代结点。
bool deletejuci(int key,bitree **t)
{
    if(!t)//如果没找到
        return false;
    else
    {
        if(key==(*t)->data)//如果相等,就将该结点的地址放进删除函数中(二级地址)
            return delete(t);
        else if(key<(*t)->data)
        deletejuci(key,(*t)->lchild);
        else
            deletejuci(key,(*t)->rchild);

    }
}
void delete(bitree **p)
{
    bitree *q,*s;
    if(!(*p)->rchild)//如果没有右子树,该结点就等于左子树的第一个结点,然后释放结点
    {
        q=*p;
        (*p)=(*p)->lchild;//不是太懂
        free(q);
    } else if(!(*p)->lchild)//
    {
        q=*p;
        *p=(*p)->rchild;
        free(q);
    }
    else
    {
        q=*p;
        s=(*p)->lchild;
        while(s->rchild)//找到删除结点的左子树的最右结点
        {
            q=s;
            s=s->rchild;
        }
        (*p)->data=s->data;//删除结点等于最右结点的data
        if(q!=*p)//不是太懂
            q->rchild=s->lchild;
        else
            q->lchild=s->lchild;
    }

}

7,哈希

#define fals -333333;
#define maxsize  12;
typedef struct hash
{
    int *elem;
    int count;
}hashnode;
//初始化
void inti(hashnode *h)
{
    int m=maxsize;
    h->count=maxsize;
    h->elem=(hashnode*)malloc(m*sizeof(hashnode));//开辟maxsize个hashnode结构体内存
    for(int i=0;i<h->count;i++)//
        h->elem[i]=fasl;

}
int hsah(int key)
{
    return key%m;//返回key%m,这里用的取莫法
}
//建立
void creathash(hashnode *h,int key)
{
    int a=hash(key);
    while(h->elem[a]!=fals)//如果不等于fals,说明这个位置已经被其他key占用,即发生了哈希冲突
        a=(a+1)%m;
        h->elem[a]=key;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值