查找C++

文章介绍了查找表的概念,包括静态和动态查找表,以及关键字的主次之分。接着详细讨论了顺序查找和监视哨的改进,以及折半查找的优缺点。此外,文章还提到了二叉排序树的查找、插入和删除操作,平衡二叉树(AVL树)的概念,以及散列表在解决查找效率问题上的作用和冲突处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念:

(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来输出数据存入文件

总结:

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

二分法查找,也称为折半查找,是一种在有序数组中查找特定元素的搜索算法。它通过每次将查找范围减半来提高效率。在C++中教授二分法查找,你可以按照以下步骤进行教案设计: 1. **引入概念**: - 解释什么是顺序查找和递归查找,并对比它们的时间复杂度。 - 介绍二分查找的优势:对于大规模数据,时间复杂度为O(log n),比线性查找更高效。 2. **算法步骤**: - 绘制流程图或伪代码,展示查找过程的基本逻辑: a. 初始化左右指针(start和end) b. 当start <= end时,执行循环: i. 计算中间位置mid ii. 比较目标值与中间元素: - 相等:返回中间索引 - 目标值小:更新right = mid - 1(左半部分) - 目标值大:更新left = mid + 1(右半部分) c. 当目标值不存在于数组时,返回-1 3. **C++实现**: - 举一个简单的C++函数示例,包括模板函数和迭代版本,以适应不同类型的数组(如整数、自定义类型): ```cpp template <typename T> int binarySearch(T arr[], int left, int right, T target) { // ... 实现代码 ... } ``` 4. **练习**: - 提供一些练习题目让学生自己实现二分查找函数。 - 分析并讨论二分查找的边界条件,如空数组或已排序数组为空的情况。 5. **扩展**: - 谈论二分查找的局限性,比如只适用于静态排序的数据。 - 与其他查找算法(如哈希表)进行比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值