【C++】基础强训

本文介绍了二叉树的后序、中序和前序遍历,并通过实例解析了如何根据遍历序列确定二叉树结构。此外,还探讨了线性表的顺序存储及其访问和插入操作的时间复杂度,以及堆排序的具体步骤。最后,提供了两个编程题目,分别是洗牌算法和MP3光标位置的实现,详细阐述了解题思路和代码实现。
摘要由CSDN通过智能技术生成

选择题:

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

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

如果直到中序和前序,后序中的一种,必须直到前序就能知道另一种排序顺序。

前序:根->左->右 , 中序:左->根->右, 前序:左->右->根

我们拿出来后续bfegcda,根据中序排列。所以根是a,左子树是b且就他一个。 d在a的右边,c在a右边,d的右边,g在a,d,c的右边;e在a,d右边,c,g的左边。如果e画在g的左边在,这样e就不再c的左边了。

所以答案:B

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

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

看到顺序存储就想到数组了,既然有数组就可以用下标访问,所以访问结点的时间复杂度是O(1),但是增加结点就要挪动数据,所以是O(n)。

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

  • A 8 3 2 5 1 6 4 7
  • 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

 

小堆排序,所以要换位置。 

4.将数组(7-6-3-5-4-1-2)按照堆排序的方法在原地进行升堆排序, 则第一轮排序后的顺序是(C)

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

所以我们原地先建立一个堆。

编程题:

1.洗牌:

 

   这是大思路,洗一次牌的顺序是它,再洗一次,左手牌,右手牌的顺序仍旧根据排放规律再重新放到card中。

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    int T , n, k;
    cin>>T;
    while(T--)   //输入T组数据
    {
        cin>>n>>k;
        int num=n*2;   //手牌总数
        vector<int> card(num);
        for(int i=0;i<num;i++)
        {
            cin>>card[i];    //把牌输入进去
        }
        // 开始洗牌
        while(k--)
        {
            vector<int> tmp(card.begin(),card.end());  //临时牌的收养所
            for(int j=0;j<n;j++)
            {
                card[j*2]=tmp[j];   //左手牌的洗牌次序
                card[j*2+1]=tmp[n+j];  //右  手牌的洗牌次序
            }
        }
        for(int i=0;i<num-1;i++)
        {
            cout<<card[i]<<" ";
        }
        cout<<card[num-1]<<endl;
    }
}

一定要注意最后一张牌的后面不带空格,所以我们给他开个专场。

2.MP3光标位置

  •  解析:

这个题其实我们要设置一个变量first指向每一页的第一首歌的编号,来判断是否需要翻页。

再设置num表示光标所在歌的编号。

  • 1.n<=4(歌曲正好一页显示完,用不到first)
  1. num在第一首歌的位置,执行U命令,num变成最后一首歌就行了。
  2. num在最后一首歌的位置,执行D,num=1就可以了。
  3. 普通情况,U执行-运算,D+。
  • 2.歌数大于4首
  1. 第一页第一首歌,U操作,first到最后一页第一首,num到最后一页最后一首。
  2. 最后一页最后一首,first和num都到第一页第一首。
  3. 中间页的第一首歌进行U操作,first,num同时减一就可以
  4. 中间页的最后一首进行D操作,first,num同时加一就可以了。
  5. 普通情况,该加加,该减减。
#include<iostream>
#include<string>
using namespace std;

int main()
{
    int n;
    string cmd;
    while(cin>>n>>cmd)
    { 
        int first=1,num=1;
        //first表示每一页的第一首歌编号,num表示光标所在歌的编号
        //1.就4首歌不需要翻页
        if(n<=4)
        {
            for(int i=0;i<cmd.size();i++)
            {
                if(num == 1 && cmd[i] == 'U')  //光标是第一首歌
                     num=n;
                else if(num == n && cmd[i] == 'D')  //光标在最后一首歌
                    num=1;
                else if(cmd[i] == 'U')   //上命令
                    num--;
                else
                    num++;
                    
            }
            for(int i=1;i<=n;i++)
                cout<<i<<" ";   //打印的是歌曲那一页的歌编号
            cout<<endl;
            cout<<num<<endl;  //光标所在歌曲编号
        }
        //2.歌曲数目大于4首
        else  
        {
            for(int i=0;i<cmd.size();i++)
            {
                if(first == 1 && num == 1 && cmd[i] == 'U') //第一页第一首歌
                {
                    first = n-3;   //first要到最后一页的第一首歌哪去
                    num = n;
                }
                else if(first == n-3 && num == n && cmd[i] == 'D') //最后一页的最后一首歌
                {
                    first = num = 1;
                }
                else if(first!=1 && num== first && cmd[i]=='U')
                {
                    first--;
                    num--;
                }
                else if( first!=n-3 &&num==first+3&&cmd[i]=='D')
                {
                    first++;
                    num++;
                }
                else if(cmd[i]=='D')
                {
                    num++;
                }
                else 
                {
                    num--;
                }
            }
            for(int i=first ;i<=first+3;i++)
            cout<<i<<" ";
            cout<<endl;
            cout<<num<<endl;
        }
    }
    return 0;
}
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值