数据结构_查找 总结

一、查找的基本概念
1、基本概念

  • 列表:由同一类型的数据元素组成的集合。
  • 关键码:数据元素中的某个数据项,可以标识列表中的一个或一组数据元素。
  • 键值:关键码的值。
  • 主关键码:可以唯一地标识一个记录的关键码。
  • 次关键码:不能唯一地标识一个记录的关键码。
  • 静态查找 :不涉及插入和删除操作的查找 。
  • 动态查找 :涉及插入和删除操作的查找。
  • 线性表:适用于静态查找,主要采用顺序查找技术、折半查找技术。
  • 树表:适用于动态查找,主要采用二叉排序树的查找技术。
  • 散列表:静态查找和动态查找均适用,主要采用散列技术。
    2、查找算法的性能
    平均查找长度:查找算法进行的关键码的比较次数的数学期望值。
    计算公式为:
    在这里插入图片描述
    n:问题规模,查找集合中的记录个数;
    pi:查找第i个记录的概率;
    ci:查找第i个记录所需的关键码的比较次数。

二、线性表的查找技术

#include<bits/stdc++.h>
using namespace std;
const int MaxSize = 100;
class LineSearch{
public:
    LineSearch(int a[ ], int n); //构造函数
    ~LineSearch( ) { } //析构函数为空
    int SeqSearch(int k); //顺序查找
    int BinSearch1(int k); //折半非递归查找
    int BinSearch2(int low, int high, int k); //折半递归查找
private:
    int data[MaxSize]; //查找集合为整型
    int length; //查找集合的元素个数
};
LineSearch :: LineSearch(int a[ ], int n){
    for (int i = 0; i < n; i++)
        data[i+1] = a[i]; //查找集合从下标1开始存放
    length = n;
}

1、顺序查找(线性查找)
1).普通的顺序查找方法

int LineSearch :: SeqSearch(int k)
{   
     i=n;
     while (i>0 && data[i]!=k)
         i--;
     return i;
}

2).带监视哨的顺序查找方法
设置“哨兵”。
哨兵就是待查值,将哨兵放在查找方向的尽头处,免去了在查找过程中每一次比较后都要判断查找位置是否越界,从而提高查找速度。
在这里插入图片描述

int LineSearch :: SeqSearch(int k)
{ 
    int i = length;        //从数组高端开始比较
    data[0] = k;           //设置哨兵
    while (data[i] != k) //不用判断下标i是否越界
        i--;
    return i; 
}

查找成功:ASL=(n+1)/ 2=O(n)
查找不成功:ASL=n+1
改进:把访问频率高的数据移向顺序表的右端,构造有序的单链表,提高效率。
2、折半查找

  • 适用条件: 线性表中的记录必须按关键码有序; 必须采用顺序存储。
int LineSearch :: BinSearch2(int low, int high, int k){
      if (low > high) 
          return 0; //递归的边界条件
      else {
         int mid = (low + high) / 2;
      if (k < data[mid]) 
           return BinSearch2(low, mid-1, k);
      else if (k > data[mid]) 
           return BinSearch2(mid+1, high, k); 
      else 
           return mid; //查找成功,返回序号
     }
}

  • 折半查找的判定树
    树中的每个结点对应有序表中的一个记录,结点的值为该记录在表中的位置。
    在这里插入图片描述
    任意结点的左右子树中结点个数最多相差1
    任意结点的左右子树的高度最多相差1
    任意两个叶子所处的层次最多相差1

具有n个结点的折半查找判定树的深度为 :
在这里插入图片描述
查找成功:和给定值的比较次数等于该记录结点在树中的层数。
在这里插入图片描述
查找失败:和给定值进行的关键码的比较次数等于该路径上内部结点的个数(失败情况下的平均查找长度等于树的高度)。

三、树表的查找技术
1、二叉排序树
二叉排序树(也称二叉查找树):或者是一棵空的二叉树,或者是具有下列性质的二叉树:
⑴若它的左子树不空,则左子树上所有结点的值均小于根结点的值;
⑵若它的右子树不空,则右子树上所有结点的值均大于根结点的值;
⑶ 它的左右子树也都是二叉排序树。

分析:若二叉排序树为空树,则新插入的结点为新的根结点;否则,新插入的结点必为一个新的叶子结点,其插入位置由查找过程得到。如果插入的值比根节点值大,则在右子树中进行插入;否则,在左子树中进行插入。

1)、二叉排序树的删除

  • 被删除的是叶子
    直接删除。将双亲结点中相应指针域的值改为空。
  • 被删除结点只有左子树和右子树
    将双亲结点的相应指针域的值指向被删除结点的左子树(或右子树)。
  • 被删除的结点既有左子树也有右子树
    以其前驱(左子树中的最大值)替代之,然后再删除该前驱结点。
    2、平衡二叉树
    平衡二叉树:或者是一棵空的二叉排序树,或者是具有下列性质的二叉排序树:
    ⑴ 根结点的左子树和右子树的深度最多相差1;
    ⑵ 根结点的左子树和右子树也都是平衡二叉树。

平衡因子:结点的平衡因子是该结点的左子树的深度与右子树的深度之差。 在平衡树中,结点的平衡因子可以是1,0,-1。

四、散列表的查找技术
冲突的处理方法:
1、线性探测法
当发生冲突时,从冲突位置的下一个位置起,依次寻找空的散列地址。
对于键值key,设H(key)=d,闭散列表的长度为m,则发生冲突时,寻找下一个散列地址的公式为:
Hi=(H(key)+di) % m (di=1,2,…,m-1)
2、拉链法(链地址法)(开散列表)
将所有散列地址相同的记录,即所有同义词的记录存储在一个单链表中(称为同义词子表),在散列表中存储的是所有同义词子表的头指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值