九大查找算法,值得收藏(一)

简介: 九大查找算法,值得收藏

1 顺序查找


算法思路:


对于任意一个序列,从一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。


代码:


#include <stdio.h>
#include <stdlib.h>
#define keyType int
//2021.05.24
typedef struct 
{
  keyType key;//查找表中每个数据元素的值
}ElemType;
typedef struct
{
  ElemType *elem;//存放查找表中数据元素的数组
  int length;//记录查找表中数据的总数量
}SSTable;
//创建查询数据
void Create(SSTable **st,int length)
{
  (*st)=(SSTable*)malloc(sizeof(SSTable));
  (*st)->length=length;
  (*st)->elem =(ElemType*)malloc((length+1)*sizeof(ElemType));
  printf("输入表中的数据元素:\n");
  //根据查找表中数据元素的总长度,在存储时,从数组下标为 1 的空间开始存储数据
  for (int i=1; i<=length; i++) 
  {
    scanf("%d",&((*st)->elem[i].key));
  }
}
//顺序查找函数,其中key为要查找的元素
int Search_seq(SSTable *str,keyType key)
{
  //str->elem[0].key=key;//将关键字作为一个数据元素存放到查找表的第一个位置,起监视哨的作用
  int len = str->length;   
  //从最后一个数据元素依次遍历,一直遍历到数组下标为0
  for(int i=1; i<len+1; i++)   //创建数据从数组下标为1开始,查询也从1开始
  {
    if(str->elem[i].key == key)
    {
      return i;
    }
  }
  //如果 i=0,说明查找失败;查找成功返回要查找元素key的位置i
  return 0;
}
int main() 
{
  SSTable *str;
  int num;
  printf("请输入创建数据元素的个数:\n");
  scanf("%d",&num);
  Create(&str, num);   
  getchar();
  printf("请输入要查找的数据:\n");
  int key;
  scanf("%d",&key);
  int location=Search_seq(str, key);
  if (location==0) {
    printf("查找失败");
  }else{
    printf("要查找的%d的顺序为:%d",key,location);
  }
  return 0;
}

2 二分查找(折半查找)


算法思路:


确定查找范围low=0,high=N-1,计算中项mid=(low+high)/2。


若mid==x或low>=high,则结束查找;否则,向下继续。


若amid<x,说明待查找的元素值只可能在比中项元素大的范围内,则把mid+1的值赋给low,并重新计算mid,转去执行步骤2;若mid>x,说明待查找的元素值只可能在比中项元素小的范围内,则把mid-1的值赋给higt,并重新计算mid,转去执行步骤2。


说明:


查找元素必须是有序的,如果是无序的则要先进行排序操作。


在做查找的过程中,如果 low 指针和 high 指针的中间位置在计算时位于两个关键字中间,即求得 mid 的位置不是整数,需要统一做取整操作。


折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用。


                        ——《大话数据结构》

代码:


#include <stdio.h>
#include <stdlib.h>
#define keyType int
typedef struct 
{
  keyType key;//查找表中每个数据元素的值
}ElemType;
typedef struct
{
  ElemType *elem;//存放查找表中数据元素的数组
  int length;//记录查找表中数据的总数量
}SSTable;
//创建查询数据
void Create(SSTable **st,int length)
{
  (*st)=(SSTable*)malloc(sizeof(SSTable));
  (*st)->length=length;
  (*st)->elem =(ElemType*)malloc((length+1)*sizeof(ElemType));
  printf("输入表中的数据元素:\n");
  //根据查找表中数据元素的总长度,在存储时,从数组下标为 1 的空间开始存储数据
  for (int i=1; i<=length; i++) 
  {
    scanf("%d",&((*st)->elem[i].key));
  }
}
//折半查找函数 key为要查找的元素
int Search_Bin(SSTable *str,keyType key)
{
  int low=1;//初始状态 low 指针指向第一个关键字
  int high=str->length;//high 指向最后一个关键字
  int mid;
  while (low<=high) 
  {
    mid=(low+high)/2;//int 本身为整形,所以,mid 每次为取整的整数
    if(str->elem[mid].key==key)//如果 mid 指向的同要查找的相等,返回 mid 所指向的位置
    {
      return mid;
    }
        else if(str->elem[mid].key>key)//如果mid指向的关键字较大,则更新 high 指针的位置
    {
      high=mid-1;
    }
    //反之,则更新 low 指针的位置
    else
    {
      low=mid+1;
    }
  }
  return 0;
}
int main() 
{
  SSTable *str;
  int num;
  printf("请输入创建数据元素的个数:\n");
  scanf("%d",&num);
  Create(&str, num);   
  getchar();
  printf("请输入要查找的数据:\n");
  int key;
  scanf("%d",&key);
  int location=Search_Bin(str, key);
  if (location==0) {
    printf("没有查找到");
  }else{
    printf("要查找的%d的顺序为:%d",key,location);
  }
  return 0;
}


3 插值查找


插值查找基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找


算法思路:


确定查找范围low=0,high=N-1,计算中项mid=low+(key-a[low])/(a[high]-a[low])*(high-low)。


若mid==x或low>=high,则结束查找;否则,向下继续。


若amid<x,说明待查找的元素值只可能在比中项元素大的范围内,则把mid+1的值赋给low,并重新计算mid,转去执行步骤2;若mid>x,说明待查找的元素值只可能在比中项元素小的范围内,则把mid-1的值赋给higt,并重新计算mid,转去执行步骤2。


说明:


插值查找是基于折半查找进行了优化的查找方法。


当表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能要比折半查找要好得多。


代码:

#include<stdio.h>
int array[10] = { 1, 4, 9, 16, 27, 31, 33, 35, 45, 64 };
int InsertionSearch(int data) 
{
    int low = 0;
    int high = 10 - 1;
    int mid = -1;
    int comparisons = 1;      
    int index = -1;
    while(low <= high) 
    {
       printf("比较 %d 次\n" , comparisons );
       printf("low : %d, list[%d] = %d\n", low, low, array[low]);
       printf("high : %d, list[%d] = %d\n", high, high, array[high]);
       comparisons++;
       mid = low + (((double)(high - low) / (array[high] - array[low])) * (data - array[low]));
       printf("mid = %d\n",mid);
       // 没有找到
       if(array[mid] == data) 
       {
     index = mid;
           break;
        }
  else 
  {
     if(array[mid] < data) 
           {
               low = mid + 1;
           } 
           else 
     {
         high = mid - 1;
      }
   }               
     }
     printf("比较次数: %d\n", --comparisons);
     return index;
}
int main() 
{
    int location = InsertionSearch(27);  //测试代,查27,可以找到
    if(location != -1)
    {
  printf("查找元素顺序为: %d\n" ,(location+1));
     }
     else
     {
         printf("没有查找到");
     }
     return 0;
}


相关文章
|
5月前
|
搜索推荐
六大排序算法介绍
六大排序算法介绍
|
算法
五大常用算法-分治算法
五大常用算法-分治算法
56 0
|
6月前
|
搜索推荐 算法 测试技术
数据结构:一篇拿捏十大排序(超详细版)
数据结构:一篇拿捏十大排序(超详细版)
53 0
|
存储 算法 搜索推荐
<<算法很美>>——(三)十大排序算法(上)(二)
<<算法很美>>——(三)十大排序算法(上)
<<算法很美>>——(三)十大排序算法(上)(二)
|
存储 搜索推荐 算法
七大经典排序算法
七大经典排序算法
55 0
|
机器学习/深度学习 存储 搜索推荐
七大排序经典排序算法
七大排序经典排序算法
79 0
七大排序经典排序算法
|
算法 搜索推荐 测试技术
<<算法很美>>——(三)十大排序算法(上)(一)
<<算法很美>>——(三)十大排序算法(上)
<<算法很美>>——(三)十大排序算法(上)(一)
|
算法 搜索推荐 C++
<<算法很美>>——(三)十大排序算法(下)
<<算法很美>>——(三)十大排序算法(下)
<<算法很美>>——(三)十大排序算法(下)
【夯实算法基础】 并查集
【夯实算法基础】 并查集
【夯实算法基础】 并查集
|
存储 算法 数据库
九大查找算法,值得收藏(四)
九大查找算法,值得收藏
144 0
九大查找算法,值得收藏(四)