习题整理

1.具有2n个结点的完全二叉树,该树的叶子结点个数有__个?
答案:n个

分析:对于一颗任意二叉树来讲,树的叶子结点比度为2(有两个分叉)的结点的个数多一个,有就是有n0 = n2+1成立;在完全二叉树中,度为1的结点为0个或者1个,根据题意完全二叉树结点数为2n,因而有n0+n1+n2 = (n0+n1+n0-1) = 2n;因为2n是偶数表示树有偶数个结点,因此度为1的结点个数为1,因此有n0+n0=2n,可以得知n0为n个。

2.有权值分别为11,8,6,2,5的叶子结点生成一棵哈夫曼树,它的带权路径长度为多少?

答案:71

在这里插入图片描述

3.设栈S和队列Q的初始状态为空,元素e1,e2,e3,e4,e5和e6依次通过栈S,1个元素出栈后即进队列Q,若6个元素出队的序列是e2,e4,e3,e6,e5,e1,则栈S的容量至少应该是__。

答案:3

设栈长度为s,起始为0
因为栈后进先出,队列先进先出.
又因为元素E1…E6是顺序入栈,那么分析过程如下:
按照出栈过程分析,因为给定出栈顺序:E2,E4,E3,E6,E5,E1,
E2要进栈,所以E1必须进栈,进栈顺序:E1,E2,所以s为2
下面E2出栈,打印出E2,剩余结果为E4,E3,E6,E5,E1,
因为E2出栈了,所以当前栈容量为2,但是只是用了1个,存放E1,下面继续
E3进栈,E4进栈,此时s为3,根据出栈结果,那么E4出栈,E3出栈,此时栈容量为3
但是只有E1在栈中,剩余结果为E6,E5,E1,
同理,E5进栈,E6进栈,此时栈被填满,容量为3,后E6出栈,E5出栈,E1出栈,栈空,容量为3.所以S的容量至少为3.

4.设一个有序的单链表中有n个结点,现要求插入一个新结点后使得单链表仍然保持有序,则该操作的时间复杂度为__。

答案:O(n)

插入的这个过程时间复杂度虽然是O(1),但是遍历的这个过程时间复杂度为O(n); 时间复杂度看有没有循环 单链表插入新节点必然要用到循环 时间复杂度就是O(n)。Ο(1)表示基本语句的执行次数是一个常数,一般来说,只要算法中不存在循环语句,其时间复杂度就是Ο(1)。

5.洗牌

洗牌在生活中十分常见,现在需要写一个程序模拟洗牌的过程。 现在需要洗2n张牌,从上到下依次是第1张,第2张,第3张一直到第2n张。首先,我们把这2n张牌分成两堆,左手拿着第1张到第n张(上半堆),右手拿着第n+1张到第2n张(下半堆)。接着就开始洗牌的过程,先放下右手的最后一张牌,再放下左手的最后一张牌,接着放下右手的倒数第二张牌,再放下左手的倒数第二张牌,直到最后放下左手的第一张牌。接着把牌合并起来就可以了。 例如有6张牌,最开始牌的序列是1,2,3,4,5,6。首先分成两组,左手拿着1,2,3;右手拿着4,5,6。在洗牌过程中按顺序放下了6,3,5,2,4,1。把这六张牌再次合成一组牌之后,我们按照从上往下的顺序看这组牌,就变成了序列1,4,2,5,3,6。 现在给出一个原始牌组,请输出这副牌洗牌k次之后从上往下的序列。

输入描述:

第一行一个数T(T ≤ 100),表示数据组数。对于每组数据,第一行两个数n,k(1 ≤ n,k ≤100),接下来有2n行个数a1,a2,…,a2n(1 ≤ ai ≤ 1000000000)。表示原始牌组从上到下的序列。

输出描述:

对于每组数据,输出一行,最终的序列。数字之间用空格隔开,不要在行末输出多余的空格。
在这里插入图片描述

实现代码:

import java.util.Scanner;

//思想:比较原来牌的下标i与n的大小
//下标比n小时重洗后该牌的下标变为2*i,下标大于等于n时重洗后牌的下标为2*(i-n)+1

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        while (m>0){
            int n = sc.nextInt();
            int k = sc.nextInt();
            int array[] = new int[2*n];

            for(int i = 0;i<array.length;i++){
                int temp = i;
                for(int j= 0;j<k;j++){
                    if(temp<n){
                        temp = 2*temp;
                    }else{
                        temp = 2*(temp-n)+1;
                    }
                }
                array[temp] = sc.nextInt();
            }
            //输出重洗后的扑克牌
            for(int i = 0;i<array.length;i++){
                if(i == array.length-1){
                    System.out.print(array[i]);
                }else{
                    System.out.print(array[i]+" ");
                }
            }
            System.out.println();
            m--;
        }
    }
}

6.MP3光标位置

链接:https://www.nowcoder.com/questionTerminal/eaf5b886bd6645dd9cfb5406f3753e15
来源:牛客网

MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。

现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:
链接:MP3光标位置

1.歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。

光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。
在这里插入图片描述
其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。
在这里插入图片描述

2.歌曲总数大于4的时候(以一共有10首歌为例):

特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
在这里插入图片描述
一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。
在这里插入图片描述
其他情况,不用翻页,只是挪动光标就行。

输入描述:

输入说明 1 输入歌曲数量
     2 输入命令 U或者D

本题含有多组输入数据!

输出描述:

输出说明 1 输出当前列表
     2 输出当前选中歌曲

示例1

输入 10
  UUUU
输出
7
8
9
10
7

实现代码:

import java.util.Scanner;


public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            int num = sc.nextInt();  //歌曲数量
            String order = sc.next();  //输入顺序字符串
            int[] arr = new int[num];
            //初始化歌曲列表,下标从0开始,0下标存1
            for (int i = 1; i <= num; i++) {
                arr[i-1] = i;
            }
            int display = num >= 4 ? 3 : num-1;
            int tempIndex = 0;  //表示当前光标的位置
            int begin = 0;  //歌单顶部
            int end = display; //歌单底部
            for (int i = 0; i < order.length(); i++) {
                if (order.charAt(i) == 'U'){
                    if (tempIndex == 0){
                        tempIndex = arr.length - 1;
                        end = tempIndex;
                        begin = tempIndex - display;
                    }else {
                        tempIndex -= 1 ;
                        if (tempIndex < begin){
                            begin = tempIndex;
                            end = begin + display;
                        }
                    }
                //操作为D
                }else {
                    if (tempIndex == arr.length - 1){
                        tempIndex = 0;
                        begin = 0;
                        end = display;
                    }else {
                        tempIndex += 1 ;
                        if (tempIndex > end){
                            begin++;
                            end++;
                        }
                    }
                }
            }
            StringBuilder sb = new StringBuilder();
            for (int i = begin; i <= end; i++) {
                sb.append(arr[i] + " ");
            }
            System.out.println(sb.toString().trim());
            System.out.println(arr[tempIndex]);
        }
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值