初试811-数据结构(C语言)

第六章:集合和搜索📐

知识点:

  • 顺序查找

    • 考点一:加上哨兵💂的顺序查找

    • 考点二:优化->若表中元素有序

      • 1、此优化不会改变平均时间复杂度,查找成功的平均时间两者相同,即每个元素查找成功的比较次数只与其位置有关(与是否有序无关)
        2、只是查找失败平均查找长度少

  • 折半查找

    • 考点判定树

      • 1、为一棵平衡二叉树,其比较路径为一棵二叉排序树
        2、所以折半查找的时间性能与二叉排序树是有可能不同的,二叉排序树可以为倾斜树O(n)

      • 3、根据mid=(low+high)/2上界时,往左倾斜
              mid=(low+high)/2下界时,往右倾斜
              注意⚠️:可以用于快速画出判定树

    • 使用场景

      • 1、有序顺序表 2、线性表具有随机存取性质 3、不适合链式存储

    • 考点一:根据已知长度的顺序表,求比较次数
      注意⚠️:判定树中的方形结点是虚构的,不计入比较次数

      • 注意⚠️:就是树高h

        • 结论1:查找不成功时和查找关键字的最多比较次数为树高

 Q&A:

1、设计算法,判断线性表是否为有序表。

bool judgeSq(int A[], int n)
{
    if (n < 2) {
        return true;  // 如果数组长度小于2,则认为是有序的
    }

    bool isIncreasing = A[0] < A[1];  // 判断是递增还是递减
    for (int i = 1; i < n - 1; i++) {
        if (isIncreasing) {
            if (A[i] > A[i+1]) {
                return false;  // 发现不递增的情况
            }
        } else {
            if (A[i] < A[i+1]) {
                return false;  // 发现不递减的情况
            }
        }
    }
    return true;  // 如果遍历完毕没有发现任何异常,则是有序的
}

2、设计算法,求线性表表示的两个集合的交集。

// 函数返回两个数组的交集,并返回交集的大小
int* CommonE(int A[], int B[], int l, int s, int& resultSize) {
    int k = 0;
    int maxSize = (l < s) ? l : s;  // 交集的最大可能大小
    int* C = new int[maxSize];      // 动态分配内存以存储交集

    for (int i = 0; i < l; i++) { // 遍历数组 A
        for (int j = 0; j < s; j++) { // 遍历数组 B
            if (A[i] == B[j]) {
                // 检查是否已经在 C 中存在该元素,避免重复
                bool exists = false;
                for (int m = 0; m < k; m++) {
                    if (C[m] == A[i]) {
                        exists = true;
                        break;
                    }
                }

                // 如果不存在则添加到交集 C 中
                if (!exists) {
                    C[k++] = A[i];
                }
            }
        }
    }

    resultSize = k;  // 返回交集的大小
    return C;        // 返回交集数组
}

3、设计算法,实现对单链表表示的有序表的顺序搜索

// 定义单链表节点结构
struct ListNode {
    int data;       // 存储节点数据
    ListNode* next; // 指向下一个节点的指针
}*LinkList;

// 顺序搜索函数
ListNode* Search(LinkList* L, int target) {
    if (L == null) {
        return nullptr; // 空表返回null
    }

    ListNode* p = L->next; // 从第一个元素开始搜索
    while (p != null) {
        if (p->data == target) {
            return p; // 找到目标,返回该节点的指针
        }
        p = p->next; // 继续下一个节点
    }

    return null; // 没找到目标,返回nullptr
}

4、设计递归算法,实现对有序表的顺序搜索

int search(int A[], int m, int i, int x) {
    if (i >= m) {
        return -1;    // 超出数组长度,寻找失败
    }

    if (A[i] == x) {
        return i;    // 找到目标,返回下标
    } else {
        return search(A, m, i + 1, x);    // 递归调用,查找下一个元素
  //递归调用后的返回值需要返回给调用者,所以需要在递归调用时加上 return。
    }
}

5、假定对下标从0开始标记、长度为11的有序表(6,17,21,27,30,36,44,55,60,67,71)进行对半搜索,请画出描述对半搜索的二叉判定树。若每个元素的搜索概率相等,求搜索成功的平均查找长度。


查找成功的平均查找长度ASL:(1*1+2*2+3*4+4*4)/11=3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值