【C/C++笔试练习】顺序表的时间复杂度、链表的性质、双向循环链表、栈的性质、循环队列的有效长度、二叉树的性质、二叉平衡树、堆排序、哈希表散列法冲突、快速排序的过程、字符串反转、公共字串计算

C/C++笔试练习

选择部分

(1)顺序表的时间复杂度

  对于顺序存储的线性表,访问结点和增加结点的时间复杂度为()。

  A. O(n) O(n)
  B. O(n) O(1)
  C. O(1) O(n)
  D. O(1) O(1)

  答案:C

  顺序存储的线性表的特点是:数据元素是连续的,每个元素占用固定大小的存储单元。因此,我们可以通过元素的下标直接计算出其存储位置,即 O(1) 的时间复杂度。

  由于每个元素的大小是固定的,当我们需要增加一个元素时,需要在最后一个元素后面插入新元素,这个操作需要将最后一个元素之后的所有元素后移,所以这个操作的时间复杂度为 O(n)。 对于顺序存储的线性表,访问结点和增加结点的时间复杂度分别为 O(1) 和 O(n)。

  

(2)链表的性质

  在下列链表中不能从当前结点出发访问到其余各结点的是()

  A. 双向链表
  B. 单循环链表
  C. 单链表
  D. 双向循环链表

  答案:C

  单链表:每个节点只有一个指向下一个节点的链接。 所以单链表只能通过从头结点开始,按顺序访问到所有其他节点。如果从当前节点开始,由于只有一个指向下一个节点的链接,无法访问到其他所有节点。

  双向链表:每个节点有两个链接,一个指向前一个节点,另一个指向下一个节点。

  单循环链表:链表的最后一个节点指向第一个节点,形成循环。

  双向循环链表:链表的最后一个节点指向第一个节点,并且每个节点都有两个链接,一个指向前一个节点,另一个指向下一个节点。

  

(3)双向循环链表

  完成在双向循环链表结点 p 之后插入 s 的操作是()

  A. p->next=s;s->prior=p;p->next->prior=s;s->next=p->next
  B. p->next->prior=s;p->next=s;s->prior=p;s->next=p->next
  C. s->prior=p;s->next=p->next;p->next=s;p->next->prior=s
  D. s->prior=p;s->next=p->next;p->next->prior=s;p->next=s

  答案:D

  选项D可以满足题目中所给的要求。
在这里插入图片描述

  

(4)栈的性质

  栈是一种智能在某一端插入和删除的特殊线性表,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,若6元素为A、B、C、D、E、F出栈顺序为B、D、C、F、E、A,则S栈的最小容量为()。

  A. 3
  B. 4
  C. 5
  D. 6

  答案:A

  根据出栈和入栈,模拟栈中的元素后进先出的储存顺序(每次只进行一次入栈或出栈):

即将入栈的元素当前栈中的元素已经出栈的元素栈中的元素个数
A B C D E F暂无0
B C D E FA暂无1
C D E FA B暂无2
C D E FAB1
D E FA CB1
E FA C DB3
E FA CB D2
E FAB D C1
FA EB D C2
A E FB D C3
A EB D C F2
AB D C F E1
B D C F E A0

  栈中的元素个数的最大值就是S栈的最小容量为3。

  

(5)循环队列的有效长度

  现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为()(假设队头不存放数据)

  A. (rear - front + N) % N + 1
  B. (rear - front + N) % N
  C. (rear - front) % (N + 1)
  D. (rear - front + N) % (N - 1)

  答案:B

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

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

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

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

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

  队列中的有效元素:(rear - front + QueueSize) % QueueSize

在这里插入图片描述

  

(6)二叉树的性质

  下述结论中,正确的是()①只有一个结点的二叉树的度为0;②二叉树的度为2;③二叉树的左右子树可任意交换;④深度为K的完全二叉树的结点个数小于或等于深度相同的满二叉树

  A. ①②③
  B. ②③④
  C. ②④
  D. ①④

  答案:D

  只有根节点的二叉树的度为0;二叉树的度可能为0,1,2;二叉树的左右子树不一定完全相同,也不能随意交换。深度为K的满二叉树的节点个数一定大于或等于其相同深度的完全二叉树。

在这里插入图片描述

  

(7)二叉平衡树

  若将关键字1,2,3,4,5,6,7 依次插入到初始为空的平衡二叉树 T 中,则 T 中平衡因子为 0 的分支结点的个数是( )

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

  答案:D

在这里插入图片描述

  

(8)堆排序

  初始序列为1 8 6 2 5 4 7 3一组数采用堆排序,当建堆(小根堆)完毕时,堆所对应的二叉树中序遍历序列为()

  A. 8 3 2 5 1 6 4 7
  B. 3 2 8 5 1 4 6 7
  C. 3 8 2 5 1 6 7 4
  D. 8 2 3 5 1 4 7 6

  答案:A

在这里插入图片描述

  

(9)哈希表散列法冲突

  解决散列法中出现冲突问题常采用的方法是()

  A. 数字分析法、除余法、平方取中法
  B. 数字分析法、除余法、线性探测法
  C. 数字分析法、线性探测法、多重散列法
  D. 线性探测法、多重散列法、链地址法

  答案:D

  散列法是一种通过将键值映射到固定大小的数组中的索引来查找数据的方法。当两个或更多的键值映射到同一索引时,就会发生冲突。

  解决散列冲突的方法主要有以下几种:

  线性探测法: 当发生冲突时,按一定次序逐个探测其它索引位置,直到找到目标或探测了所有索引。这种方法在探测过程中可能会产生大量冲突。

  二次探测法: 当发生冲突时,按二次方序列逐个探测其它索引位置,直到找到目标或探测了所有索引。这种方法适用于固定大小的散列表。

  链地址法: 当发生冲突时,将所有相同索引位置的元素都放在一个链表中。这种方法在插入和查找操作中都能较好地处理冲突。

  开放地址法: 当发生冲突时,将元素放入另一个位置,直到找到可用的索引位置。这种方法在插入操作中能较好地处理冲突,但在查找操作中可能会有额外的开销。

  再哈希: 当发生冲突时,使用另一个哈希函数计算索引位置。这种方法适用于多个哈希函数的情况。

  多重散列法: 使用多个哈希函数来计算索引位置,当某个哈希函数发生冲突时,再使用另一个哈希函数。这种方法可以结合多种散列方法来提高性能。

  

(10)快速排序的过程

  下列选项中,不可能是快速排序第2趟排序结果的是 ()

  A. 2,3,5,4,6,7,9
  B. 2,7,5,6,4,3,9
  C. 3,2,5,4,7,6,9
  D. 4,2,3,5,7,6,9

  答案:C

  快速排序每次会选择一个基准值,每次进行一次单趟排序可以确定基准值的位置,将小于基准值的数移动到基准值左边,将大于基准值的数移动到基准值的右边。

  对于A,第一次可以将基准值设置为9,第二次的基准值设置为2,符合快速排序的第二趟排序结果。

  对于B,第一次也可以将基准值设置为9,第二次的基准值设置为2,符合快速排序的第二趟排序结果。

  对于C,第一次可以将基准值设置为9,但是对于剩下的数中,3 2 5 4 7 6 没有任何一个数满足快速排序的结果(通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据要小),所以不可能是快速排序的第二趟排序结果。

  对于D,第一次也可以将基准值设置为9,第二次的基准值设置为5,符合快速排序的第二趟排序结果。

            

编程题 day20

字符串反转

字符串反转

  解题思路:字符串反转,需要交换首尾字符,设置首尾两个位置start,end,每次交换首尾字符,然后start++, end–,直到start,end相遇,反转完成。

#include<string>
#include<iostream>
using namespace std;

string reverseString(string s) 
{
    if (s.empty())
        return s;
    size_t start = 0;
    size_t end = s.size() - 1;
    while (start < end) 
    {
        swap(s[start], s[end]);
        ++start;
        --end;
    }
    return s;
}

int main() 
{
    string s;
    getline(cin, s);
    cout << reverseString(s) << endl;
    return 0;
}

  

公共字串计算

公共字串计算

  解题思路:求最大公共子串,使用递推实现 假设 x(i): 字符串第i个字符 y(j): 字符串第j个字符 dp[i][j]: 以x(i),y(j)结尾的最大子串长度 比如:x: “abcde” y:“bcdae” dp[2][1]: 以x(2),y(1)结尾的最大子串长度 即:x遍历到"abc", y遍历到"bc", 都以字符’c’结尾时最大公共子串为"bc" 故:当计算dp[i][j]时,首先看x(i),y(j)的值:
  (1): x(i) == y(j)当前两个字符串结尾的字符相等,dp[i][j] = dp[i-1][j-1] + 1 即个它的长度加1;
  (2): x(i) != y(j) 当前两个字符串结尾的字符不相等,说明没有以这连个字符结尾的公共子串 即dp[i][j] = 0;
  (3): dp[0][j] 和 dp[i][0]表示以某个子串的第一个字符结尾,最大长度为1 如果x(0) = = y(j) 或者 x(i) = = y(0), 则长度为1,否则为0 当dp中的所有元素计算完之后,从中找打最大的值输出。

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

int getMaxComSubstr(const string& str1, const string& str2) 
{
    int len1 = str1.size();
    int len2 = str2.size();
    //所有值初始化为0
    vector<vector<int>> msc(len1, vector<int>(len2, 0)); 
    //msc[len1][len2];
    int max_len = 0;
    for (int i = 0; i < len1; ++i) 
    {
        for (int j = 0; j < len2; ++j) 
        {
            //如果当前结尾的字符相等,则在dp[i-1][j-1]的基础上加1
            if (str2[j] == str1[i]) 
            {
                if (i >= 1 && j >= 1)
                    msc[i][j] = msc[i - 1][j - 1] + 1;
                else
                    msc[i][j] = 1;
                //更新最大值
                if (msc[i][j] > max_len)
                    max_len = msc[i][j];
            }
        }
    }
    return max_len;
}

int main() 
{
    string str1, str2;
    while (cin >> str1 >> str2) 
    {
        int max_len = getMaxComSubstr(str1, str2);
        cout << max_len << endl;
    }
    return 0;
}
  • 30
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鳄鱼麻薯球

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

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

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

打赏作者

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

抵扣说明:

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

余额充值