数据结构——查找

1 查找

  根据给定的值,在查找表中确定一个其关键字等于给定值的数据元素

  查找表:由同一类数据元素构成的集合

    静态查找表:只做查找操作的查找表

    动态查找表:在查找过程中,还可以进行插入或删除操作的查找表

  关键字:数据元素中某个数据项的值

    主关键字:可以唯一标识一个记录的关键字

    次关键字:可以标识多个记录的关键字

2 循序查找表

  从表的第一个数据元素开始,逐个将数据元素的关键值与给定值相比较,若相等则表示查找到了,若不相等则表示没有找到;

/*
查找数组a中,与key值相等的元素,并返回数组元素的下标
*/
int seqSearch(int a[],int n,int key)
{
  for(int i=0;i<n;i++)
  {
    if(a[i]==key)
      return i;
  }
  return -1;
}

3 折半查找表

  被查找的表的数据元素必须是升序或者降序的有序表;取中间数据元素的关键字与给定值比较;若相等则表示查找到了;若给定值大,则在中间到最后元素这一半中再取中间元素的关键字与给定值比较;若给定值小,则在第一个到中间元素这一半中再取中间元素的关键字与给定值比较;依次类推,直到找到或者没找着;

/*
查找数组a中,与key值相等的元素,并返回数组元素
*/
int binSearch(int a[],int n,int key)
{
  int low=0;
  int high=n-1;
  int mid;
  while(low<=high)
  {
    mid=(low+high)/2;
    if(a[mid]==key)
      return mid;
    else if(a[mid]<key)
      low=mid+1;
    else
      high=mid-1;
  }
  return -1;
}

4 插值查找

  是对折半查找法的改进;主要应用于关键字分布比较均匀的有序表,而对不均匀的表不适用

/*
查找数组a中,与key值相等的元素,并返回数组元素
*/
int binSearch(int a[],int n,int key)
{
  int low=0;
  int high=n-1;
  int mid;
  while(low<=high)
  {
    mid=low+(key-a[low])/(a[high]-a[low])*(high-low);
    if(a[mid]==key)
      return mid;
    else if(a[mid]<key)
      low=mid+1;
    else
      high=mid-1;
  }
  return -1;
}

5 斐波那契查找

  是对折半查找法的改进;利用黄金分割点进行数据的分割;

/*
查找数组a中,与key值相等的元素,并返回数组元素
*/
int fib[10]={1,1,2,3,5,8,13,21,34,55};
int fibSearch(int a[],int n,int key)
{
  int low=0;
  int high=n-1;
  int k=0;
  while(n>fib[k]-1)
    k++;
  while(low<=high)
  {
    mid=low+fib[k-1]-1;
    if(a[mid]==key)
    {
      if(mid<n)
        return mid;
      else
        return n-1;
    }
    else if(a[mid]<key)
    {
      low=mid+1;
      k=k-2;
    }
    else
    {
      high=mid-1;
      k=k-1;
    }
  }
  return -1;
}
void main()
{
  int a[]={7,18,23,39,46,55,62,71,84,98};
  fibSearch(a,10,23);
}

6 线性索引查找

  索引是指将关键字从数据元素中独立出来,形成查找表;索引的作用是加快查找速度;索引由若干个索引项(由关键字和其对应记录的存储位置构成的一种数据结构)构成;

  索引分类;

    线性索引、树形索引、多级索引

  线性索引:索引项是线性表的索引,包括稠密索引、分块索引、倒排索引

  稠密索引:

    索引项由关键字和地址构成;索引项的关键字是有序的,索引项的关键字可以使一个数据元素中的任何一项;当需要在所有数据元素中查找某一个时,可以使用有序查找法在索引项中通过关键字查找找到该数据元素。

 

  分块索引:

    索引项由块中最大关键字、块中元素个数和块首地址构成;索引项中的关键字是有序的,块中数据元素不要求有序;索引项中的关键字可以使数据元素中的任何一项;当需要在所有元素中查找某一个时,首先使用有序查找法在索引项中通过关键字查找到该元素所在的块,然后使用其它查找法在块中找到该数据元素。

   

  倒排索引:

    索引项由次关键字、记录号构成;索引项中的次关键字是有序的;

1we should live by our own principles
2they will live forver in our hearts
3he hated to live a lie

 

 

 

次关键字记录号
we1
should1
live1、2、3
by1
our1、2
own1
principles1
they2
will2
forver2
in2
heart2
he3
hated3
to3
a3
lie3

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

 

 

7 二叉排序树

  可以使一棵空树;若左子树存在,则左子树的所有结点的值均小于根结点的值;若右子树存在,则右子树的所有结点的值均大于根结点的值;左右子树也是一棵二叉排序树;

   

typedef int DataType;
typedef struct BiTNode
{
  DataType data;
  struct BiTNode *left,*right;
}BiTNode;

7.1 插入操作

void biTInsert(BiTNode **root,DataType data)
{
  if(*root==NULL)
  {
    BiTNode *p=(BiTNode *)malloc(sizeof(BiTNode));
    p->data=data;
    p->left=p->right=NULL;
    *root=p;
  }
  else if((*root)->data<data)
    biTInsert(&((*root)->right),data);
  else
    biTInsert(&((*root)->left),data);
}

7.2 删除操作

 1 void biTDelete(BiTNode **root,DataType data)
 2 {
 3   if(*root==NULL)
 4     return;
 5   else if((*root)->data==data)
 6   {
 7     BiTNode *p=*root;
 8     if((*root)->left==NULL)
 9       *root=(*root)->right;
10     else if((*root)->right==NULL)
11       *root=(*root)->left;
12     else
13     {
14       BiTNode *q=p->left;
15       while(q->right)
16       {
17         p=q;
18         q=q->right;
19         (*root)->data=q->data;
20         if(*root==p)
21           p->left=q->left;
22         else
23           p->right=q->left;
24         p=q;
25       }
26       free(p);
27     }
28     else if((*root)->data<data)
29       biTInsert(&((*root)->right),data);
30     else
31       biTInsert(&((*root)->left),data);
32   }
33 }

7.3 遍历操作

BiTNode *biTTraverse(BiTNode *root,void(*visitFunc)(DataType data))
{
  biTTraverse(root->left);
  visitFunc(root->data);
  biTTraverse(root->right);
}

7.4 创建操作

BiTNode *biTCreate()
{
  BiTNode *root;
  int data;
  do
  {
    printf("输入树中一个结点:");
    scanf("%d",&data);
    biTInsert(&root,data);
  }while(data != -1);
  return root;
}

 

转载于:https://www.cnblogs.com/dongry/p/10044531.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值