查找算法

查找
注:后续,继续补充。

1)顺序查找

> 1.适用:顺序表,链表。
> 2.方式:在某一个数据集合中从第一个元素开始,依次向后查找。

例:设有一数据集合{3,2,5,8,4,7,6,9}给定某个关键字key,在数据集合中查找key对应的元素。
顺序表

①顺序表
int Search(int data[],int n,int key)
{
    int tag=-1;
    for(int i=0;i<n && data[i]-key;i++);
    if(i!=n)
        tag=i;
    return tag;
}

链表

②链表
ElemSN * Search(ElemSN *h,int key)
{
    ElemSN *p;
    for(p=h;p && p->data !=key;p=p->next);
    return p;
}

分析:
- 平均查找长度(ASL)=(1+n)/2
- 缺点:不适合海量数据集合。时间复杂度大。



2)二分查找

条件:经过排序的数据集合。只适合顺序储存的数据集合。

例:设数据集合data={5,7,12,25,34,37,43,46};查找关键字key.
二叉查找树:
二分查找树
数据集合
如:key=34

- (0+7)/2=3
- D[3]=25<34


- (4+7)/3=5
- D[5]=37>34


- (4+4)/3=4
- D[4]=34=34
结论:二分查找会生成,二叉查找树,

int HalfSearch(int data[],int low,int high,int key)
{
    int mid,result=-1;
    while(low<high)
    {
        mid=(low+high)/2;
        if(data[mid]>key)
        {
            high=mid;
        }
        else if(data[mid]<key)
        {
            low=mid;
        }
        else
        {
            result=mid;
            break;
        }
    }
    return result;
}
②递归
int HalfSearch(int data[],int low,int high,int key)
{
        if(low>high)
            return -1;
        int mid=(low+high)/2;
        if(data[mid]>key)
            return HalfSearch(data,low,mid,key);
        else if(data[mid]<key)
            return HalfSearch(data,mid,high,key);
        else
            return mid;
}

分析:
- 时间复杂度O(log2n)



3)散列查找(哈希查找)

散列函数:用来计算存储,数据元素地址的函数。 H(k)=k%m (除留余法)

例:散列长度13,数据集合{5,13,17,42,46,55,70,82,94}

①线性探查法
    5%13=513%13=017%13=442%13=346%13=755%13=3456
    70%13=5678  82%13=456789
    94%13=345678910

线性探查法

②拉链法
    5%13=513%13=017%13=442%13=346%13=755%13=3
    70%13=5  82%13=4
    94%13=3

拉链法

//拉链法
#include<stdio.h>
#include<stdlib.h>
#define len 10

typedef struct node{
    int data;
    struct node * next;
}ElemSN;
//创建哈希表
void CreatHash(int Data[],ElemSN **H)
{
    ElemSN *newp,*t;
    int k;
    for(int i=0;i<len;i++)
    {
        newp=(ElemSN*)malloc(sizeof(ElemSN));
        newp->data=Data[i];
        newp->next=NULL;
        k=Data[i]%len;

        for(t=H[k];t && t->next;t=t->next);
        {
            if(t)
                t->next=newp;
            else
                H[k]=newp;

        }
    }
}
//输出哈希表
void PrintHash(ElemSN **H)
{
    for(int i=0;i<len;i++)
    {
        for(ElemSN *p=H[i];p;p=p->next)
            printf("%5d",p->data);
        printf("\n");
    }
}
//哈希查找
ElemSN * FindHashKey(ElemSN **H,int key)
{
    int k=key%len;
    for(ElemSN *p=H[k];p && p->data-key;p=p->next);

    return p;
}
int main(void)
{
    int Data[len]={3,5,8,0,6,9,13,14,13,23};
    int k;
    //创建指针数组
    ElemSN **H;
    H=(ElemSN**)malloc(len*(sizeof(ElemSN*)));
    for(int i=0;i<len;H[i++]=NULL);
    //创建哈希表
    CreatHash(Data,H);
    //输出哈希表
    PrintHash(H);
    //哈希查找
    printf("输入key");
    ElemSN *resoult;
    scanf("%d",&k);
    resoult=FindHashKey(H,k);
    if(resoult)
        printf("%5d\n",resoult->data);
    else
        printf("no find\n");
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值