【C/C++笔试练习】二分查找、单链表插入、双向链表、栈的输出、循环队列、二叉树的遍历、二叉树的性质、哈希表、稳定排序、汽水瓶、 查找两个字符串a,b中的最长公共子串

C/C++笔试练习

选择部分

(1)二分查找

  二分查找的时间复杂度()

  A. O(N*log(N))
  B. O(N)
  C. O(log(N))
  D. O(N^2)

  答案:C

  二分查找是一种在有序数组中查找特定元素的搜索算法。它的工作原理是将数组分为两半,比较中间元素与目标值,如果目标值与中间元素相等,则查找成功;如果目标值小于中间元素,则在左半部分数组中继续查找;如果目标值大于中间元素,则在右半部分数组中继续查找。这个过程会一直重复,直到找到目标值或者搜索区间为空。

  二分查找的时间复杂度是 O(log(N)),因为每次查找都将搜索区间减半。

  

(2)单链表插入

  有一个单向链表中有一个A、B两个相邻元素,有一个指针p指向元素A,现将一个指针r指向的S元素要插入到A和B之间,该进行操作()

  A. p->next=p->next->next
  B. r-next=p;p->next=r->next
  C. r->next=p->next;p->next=r
  D. r=p->next;->next=r->next
  E. r->next=p;p->next=r
  F. p=p->next->next

  答案:C

  单向链表的节点结构是每个节点包含两个部分:数据部分和指向下一个节点的指针部分。考虑将一个指针r指向的S元素插入到A和B之间,我们需要进行以下操作:

  1.将r的next指针指向A的下一个节点,即p->next。
  2.将A的下一个节点(原本指向B)的next指针指向r。

r->next = p->next;  // 第一步  
p->next = r;         // 第二步

在这里插入图片描述

  

(3)双向链表

  双向链表中有两个指针域,llink和rlink分别指向前驱和后继,设p指向链表中的一个结点,现要求删去p所指结点,则正确的删除是()(链中结点数大于2,p不是第一个结点)

  A. p->llink->rlink=p->llink; p->llink->rlink=p->rlink; dispose( p);
  B. dispose( p); p->llink->rlink=p->llink; p->llink->rlink=p->rlink;
  C. p->link->rlink=p->llink; dispose( p); p->llink->rlink=p->rlink;
  D. 以上A,B,C都不对

  答案:D

  双向链表中节点的基本结构:每个节点包含三个部分:数据部分、指向前驱的指针llink、指向后继的指针rlink。当我们要删除一个节点p时,必须考虑以下几点:

  1.将p的前驱节点的rlink指针指向p的后继节点,从而跳过p节点。
  2.将p的后继节点的llink指针指向p的前驱节点,从而跳过p节点。
  3.释放p节点的内存空间。

在这里插入图片描述

  

(4)栈的输出

  一个栈的入栈序列是A,B,C,D,E,则栈的不可能输出序列是()

  A. EDCBA
  B. DECBA
  C. DCEAB
  D. ABCDE

  答案:C

  栈是一种线性数据结构,它遵循后进先出(Last In First Out,LIFO)的原则。这意味着后进入栈的元素将是先出来的元素。

  

(5)循环队列

  循环队列放在一维数组A[0…M-1]中,end1指向队头元素,end2指向队尾元素的后一个位置。假设队列两端均可进行入队和出队操作,队列中最多能容纳M-1个元素。初
始时为空,下列判断队空和队满的条件中,正确的是()

  A. 队空:end1== end2;队满:end1==(end2+1) mod M
  B. 队空:end1== end2;队满:end2==(end1+1) mod (M-1)
  C. 队空:end2==(end1+1) mod M;队满:end1==(end2+1) mod M
  D. 队空:end1==(end2+1) mod M;队满:end2==(end1+1) mod (M-1)

  答案:A

  顺序队列的一些操作和判断:

  空队列判断条件: rear == front

  尾指针的移动方式: rear = (rear+1)%QueueSize

  头指针的移动方式: front=(front+1)%QueueSize

  判断队列满: front == (rear+1)%QueueSize

在这里插入图片描述

  

(6)二叉树的遍历

  已知二叉树后序遍历序列是bfegcda,中序遍历序列是badefcg,它的前序遍历序列是()

  A. abcdefg
  B. abdcefg
  C. adbcfeg
  D. abecdfg

  答案:B
在这里插入图片描述

  前序遍历为:abdcefg。

  

(7)二叉树的性质

  某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为()

  A. 不存在这样的二叉树
  B. 200
  C. 198
  D. 199

  答案:B

  完全二叉树有公式:n0=n2+1和n=n0+n1+n2。代入第一个即可得到:n0=200。

  

(8)哈希表

  设有一组记录的关键字为{19,14,23,1,68,20,84,27,55,11,10,79},用链地址法构造哈希表,哈希函数为H(key)=key MOD 13,哈希地址为1的链中有()个记录

  A. 1
  B. 2
  C. 3
  D. 4

  答案:D

  由于哈希函数为H(key)=key MOD 13,所以对上面的数%13时,有14,1,27,79四个数取模为1。 哈希地址为1的链中有4个记录。

  

(9)稳定排序

  以下哪种排序是不稳定排序()

  A. 冒泡
  B. 插入排序
  C. 归并排序
  D. 快速排序

  答案:D

排序方法平均情况最好情况最坏情况辅助空间稳定性
冒泡排序O(n2)O(n)O(n2)O(1)稳定
简单选择排序O(n2)O(n2)O(n2)O(1)不稳定
直接插入排序O(n2)O(n)O(n2)O(1)稳定
希尔排序O(nlogn)~O(n2)O(n1.3)O(n2)O(1)不稳定
堆排序O(nlogn)O(nlogn)O(nlogn)O(1)不稳定
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定
快速排序O(nlogn)O(nlogn)O(n2)O(logn)~O(n)不稳定

            

编程题 day19

汽水瓶

汽水瓶

  解题思路:每次空瓶的数量除以2,直到最后空瓶的数量少于两瓶,就累加到了课兑换的数量。

#include<iostream>
using namespace std;

//概念法
int calcNumber_1(int n) 
{
    int sum = 0;
    while (n > 1) 
    {
        int res = n / 3; //所能兑换的个数
        int left = n % 3; //遗下的个数
        sum += res;
        n = left + res;
        if (n == 2) 
        {
            sum++;
            break;
        }
    }
    return sum;
}

//取巧法
int calcNumber_2(int n) 
{
    return n / 2;
}

int main() 
{
    int n, res;
    while (cin >> n) 
    {
        if (n == 0)
            break;
        res = calcNumber_2(n);
        cout << res << endl;
    }
    return 0;
}

  

查找两个字符串a,b中的最长公共子串

查找两个字符串a,b中的最长公共子串

  解题思路:本题需要用动态规划求解,MCS[i][j]记录短字符串 s1 前 i 个字符和长字符串 s2 前 j 个字符的最长子串的长度,初始化所有值为 0。当 s1[i-1] = s2[j-1]时,MCS[i][j] = MCS[i - 1][j - 1] + 1,这里使用一个额外的值start 来记录最长子串在短字符串 s1 中出现的起始位置,maxlen记录当前最长子串的长度,当MCS[i][j] >maxlen 时,maxlen = MCS[i][j], 则start = i - maxlen ;档s1[i-1] != s2[j-1]时不需要任何操作,最后获取substr(start, maxlen)即为所求。

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

string getComSubstr(string &str1,string &str2)
{
    if(str1.size()>str2.size())
    swap(str1,str2);      //保证str1是最短的字符串
    int len1=str1.size();
    int len2=str2.size();
    vector<vector<int>> MSC(len1+1,vector<int>(len2+1,0));
    int start=0,max_size=0;
    for(int i=1;i<=len1;i++)
    {
        for(int j=1;j<=len2;j++)
        {
            if(str2[j-1]==str1[i-1])
            {
                MSC[i][j]=MSC[i-1][j-1]+1;
            }
            if(MSC[i][j]>max_size)
            {
                max_size=MSC[i][j];
                start=i-max_size;
            }
        }
    }
    return str1.substr(start,max_size);
}

int main() 
{
    string str1,str2;
    string str;
    while (cin >> str1 >> str2) { // 注意 while 处理多个 case
        str=getComSubstr(str1,str2);
        cout << str << endl;
    }
}
  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鳄鱼麻薯球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值