查找C++

概念:

(1)查找表:是由同一类型的数据元素构成的集合,元素间关系松散,应用灵活;可分为静态查找表(仅查询)和动态查找表(需进行插入和删除操作)

(2)关键字:用来标识某个数据元素的某个数据项的值,分为主关键字(唯一标识一个数据项)和次关键字(标识了多个数据项)

(3)平均查找长度ASL:关键字的平均比较次数

查找方式:

顺序查找:
应用范围:

(1)顺序表或线性表表示的静态查找表

(2)表内元素无序

代码展示:
typedef int KeyType;
typedef struct
{
    KeyType key;
}ElemType;
typedef struct
{
    ElemType* R;
    int length;
}SSTable;
int SearchSeq(SSTable ST, KeyType key)
{
    int i;
    for (i = ST.length; i >= 1; i--)
        if (ST.R[i].key == key)
            return i;
    return 0;
}

运行:

改进(监视哨):
int SearchSeq(SSTable ST, KeyType key)
{
    int i;
    ST.R[0].key = key;/*监视哨*/
    for (i = ST.length; ST.R[i].key != key; i--);
    return i;
}
优点:算法简单,不同存储结构均适用
缺点:时间效率低
折半查找:
代码展示:
int SearchBin(SSTable ST, KeyType key)
{
    int low = 1, high=ST.length,mid;
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (ST.R[mid].key == key) return mid;
        else if (key < ST.R[mid].key) high = mid - 1;
        else low = mid + 1;
    }
    return 0;
}

运行:

文本输出:

代码:

int main()
{
    ofstream output("output",ios::out);
    SSTable ST;
    string s;
    int key;
    int a,b,i;
    ST.R = new ElemType[MAXSIZE];
    cout << "请输入存储数据需要的空间大小" << endl;
    cin >> ST.length;
    cout << "请输入需要存储的数据" << endl;
    for (i = 0; i < ST.length; i++)
        cin >> ST.R[i].key;
    cout << "请输入需要查找的数据" << endl;
    cin >> key;
    a=SearchSeq(ST, key)+1;
    b = SearchBin(ST, key) + 1;
    if (a == 0)output << "无此数据" << endl;
    else if (a > 0)output << "该数据在第" << a << "个位置上(顺序查找)" << endl;
    else output << "发生错误" << endl;
    if (a == 0)output << "无此数据" << endl;
    else if (a > 0)output << "该数据在第" << b << "个位置上(折半查找)" << endl;
    else output << "发生错误" << endl;
    cout << "成功" << endl;
    return 0;
}
改进:
int SearchBin(SSTable ST,KeyType key, int low,int high)
{
    int mid = (low + high) / 2;;
    if (low > high)return 0;
    if (key = ST.R[mid].key)return mid;
    else if (key < ST.R[mid].key)
    SearchBin(ST,key,low, mid - 1);
    else
        SearchBin(ST, key,low+1,high);
    return 0;
}
优点:效率比顺序查找高
缺点:只适用于顺序存储的有序表,不适用于线性链表
分块查找:

即索引顺序表查找

适用范围:

要快速查找又要经常动态变化

操作过程:

(1)将表分成几块,且表有序,或者分块有序

(2)建立索引表

优点:插入和删除容易,无需大量移动数据
缺点:要增加一个索引表空间
比较:

树表的查找:

表结构在查找过程中动态生成

类别:

二叉排序树,平衡二叉树,红黑树,B-树,B+树,键树

二叉排序树:
定义:

用中序遍历非空二叉排序树得到的数据元素序列是递增有序的

实现原理:
查找过程:
代码实现:
typedef int KeyType;
typedef int InfoType;
typedef struct/*定义数据的类型*/
{
    KeyType key;
    InfoType otherinfo;
}ElemType;
typedef struct BSTNode/*定义二叉排序树*/
{
    ElemType data;
    struct BSTNode* lchild, * rchild;
}BSTNode,*BSTree;
BSTree SearchBST(BSTree T, KeyType key)/*二叉排序树查找*/
{
    if (!T || key == T->data.key)return T;
    else if (key < T->data.key)return SearchBST(T->lchild, key);
    else return SearchBST(T->rchild, key);
}
插入操作:

若二叉排序树为空,则插入结点作为根结点

删除操作:

原理:

过程:

(1)被删除结点是叶子结点:直接删去该结点

(2)被删除结点只有左子树或右子树:用其左子树或右子树替换它

(3)被删除结点既有左子树,还有右子树:

在左子树上找到最大结点,以它作为根结点

并在左子树中将其删除

平衡二叉树(AVL):
定义:

给每个结点一个平衡因子,表示其左右子树的高度差,只能为-1,0,1

失衡二叉树调整方法:

(1)降低高度

(2)保证二叉排序树性质

散列表:

记录存储位置于关键字之间的关系,对应关系称为hash函数

查找:根据散列函数H(key)=k

优点:查找效率高

缺点:空间效率低

散列方法:

构造散列函数的考虑因素:

构造方法:

(1)直接定址法:

优点:以key的某个线性函数值为散列地址,不会产生冲突

缺点:要占用连续地址空间,空间效率低

(2)除留余数法:

处理冲突的方法:

(1)开放定址法

线性探测法:

有冲突时按照增量序列

1,2,3,...,n

寻找下一个空的散列地址,并存入数据元素

二次探测法:

有冲突时按照增量序列

将数据存入下一个空的散列地址

伪随机探测法:

(2)链地址法:

基本思想:将相同散列地址的数据连接成一个单链表

举例:

优点:不会冲突;结点空间动态申请,更适合于表长不确定的情况

编码问题总结:

(1)调用函数中参数过多

原因:函数参数名与宏函数名相同

改正方法:引入一个新变量作为中间变量来传递数据

(2)从文件中输入和输出数据

需添加一个#include<fstream>头文件

用ifstream来读取文件,用ofstream来输出数据存入文件

总结:

查找方法多种多样,我们应根据数据的存储类型和数据量大小来选择适合的方法,以提高效率,减少查找的时间,可在查找时记录下每个数据查找的频率,根据频率大小实时调整数据存储位置,提高效率

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值