《算法竞赛入门经典》第六章6.3树和二叉树总结

UVa679

这道题刚开始我的想法就是和书上那个超时的代码,一样的,通过一个树状数组去模拟那个过程和书上分析的那样,测试数据太过庞大,虽然没有数组移动这样耗时的程序,但for(int i=0;i<I;i++)中的for最多可以有524288
,而且还有一万组,肯定会超时。所以现在重点是如何减小对I的判断量,
模拟一个过程后,我们很容易发现到底某个点的球数Number,如果是奇数,
则最后一个往左边走,且左边比右边的球多一个,如果是偶数则往右边走,
且两边的数量一样多,然后按照书上那个优化算法写就可以了
,因为2^20约等于一百万>524288,所以for循环量被大大减小了。

UVa122

这道题非常好首先怎么输入就是个难点
因为这道题出现了跨行读取,就显得非常难处理了,仅仅通过whilescanf("%s",str)!=EOF这样没有办法判断每两次之间的分割符”()“,刘汝佳很巧妙的通过写一个read_input()函数来解决这个问题,因为while循环每次都要判断,所以读到()就返回true这样while还会继续,读到EOF返回false,程序结束。

正如刘汝嘉所说,大部分的ACM题并不需要内存池,但是学习这个可以锻炼工程思维,那段程序大致的作用是,首先声明一个足够大的数组,数组元素是Node,然后把他们的指针一一放到,一个队列中,每次需要新的节点时就从队首弹出来一个,如何回收那些用过的内存内,将remove_tree中的delete u;换成deletenode(u),就是把那些内存重新放入队尾

这道题需要判断什么样的二叉树是不正确的,有两种错误情况
1.有节点没有被赋值
2.有节点被重复赋值
设置一个全局变量failed都判断一下就行了

注意记住几个小技巧,strchr sscanf;

使用数组代替指针的方法与6.2最后一题思想类似。和结构体的区别就是他用四个数组来分别存放四个变量。
其实have_value这个变量不是必需的,只是有程序更健壮,用v这个值就可以判断了(再初期先全部赋值为0)

附上数组代码,其他两种代码仓库有
#pragma warning(disable:4996)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
#include<time.h>

using namespace std;

const int maxn = 256 + 10;


bool failed;
int cnt;
const int root = 1;
int left[maxn];
int right[maxn];
bool have_value[maxn];
int value[maxn];


void newtree()
{
    left[root] = right[root] = 0;
    have_value[root] = false;
    cnt = root;
}

int newnode()
{
    int u = ++cnt;
    left[u] = right[u] = 0;
    have_value[u] = false;
    return u;
}

void addnode(int v, char* s) {
    int n = strlen(s);
    int u = root;
    for (int i = 0; i < n; i++)
        if (s[i] == 'L') {
            if (left[u] == 0)left[u] = newnode();
            u = left
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 一棵二叉树的顺序存储情况如下: 中,度为2的结点数为( )。 A.1 B.2 C.3 D.4 2. 一棵“完全二叉树”结点数为25,高度为( )。 A.4 B.5 C.6 D.不确定 3.下列说法中,( )是正确的。 A. 二叉树就是度为2的 B. 二叉树中不存在度大于2的结点 C. 二叉树是有序 D. 二叉树中每个结点的度均为2 4.一棵二叉树的前序遍历序列为ABCDEFG,它的中序遍历序列可能是( )。 A. CABDEFG B. BCDAEFG C. DACEFBG D. ADBCFEG 5.线索二叉树中的线索指的是( )。 A.左孩子 B.遍历 C.指针 D.标志 6. 建立线索二叉树的目的是( )。 A. 方便查找某结点的前驱或后继 B. 方便二叉树的插入与删除 C. 方便查找某结点的双亲 D. 使二叉树的遍历结果唯一 7. 有abc三个结点的右单枝二叉树的顺序存储结构应该用( )示意。 A. a b c B. a b ^ c C. a b ^ ^ c D. a ^ b ^ ^ ^ c 8. 一颗有2046个结点的完全二叉树的第10层上共有( )个结点。 A. 511 B. 512 C. 1023 D. 1024 9. 一棵完全二叉树一定是一棵( )。 A. 平衡二叉树 B. 二叉排序 C. 堆 D. 哈夫曼 10.某二叉树的中序遍历序列和后序遍历序列正好相反,则该二叉树一定是( )的二叉树。 A.空或只有一个结点 B.高度等于其结点数 C.任一结点无左孩子 D.任一结点无右孩子 11.一棵二叉树的顺序存储情况如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 A B C D E 0 F 0 0 G H 0 0 0 X 结点D的左孩子结点为( )。 A.E B.C C.F D.没有 12.一棵“完全二叉树”结点数为25,高度为( )。 A.4 B.5 C.6 D.不确定 二、填空题(每空3分,共18分)。 1. 的路径长度:是从根到每个结点的路径长度之和。对结点数相同的来说,路径长度最短的是 完全 二叉树。 2. 在有n个叶子结点的哈夫曼中,总结点数是 2n-1 。 3. 在有n个结点的二叉链表中,值为非空的链域的个数为 n-1 。 4. 某二叉树的中序遍历序列和后序遍历序列正好相反,则该二叉树一定是 任一结点无左孩子 的二叉树。 5. 深度为 k 的二叉树最多有 个结点,最少有 k 个结点。 三、综合题(共58分)。 1. 假定字符集{a,b,c,d,e,f }中的字符在电码中出现的次数如下: 字符 a b c d e f 频度 9 12 20 23 15 5 构造一棵哈夫曼(6分),给出每个字符的哈夫曼编码(4分),并计算哈夫曼的加权路径长度WPL(2分)。 (符合WPL最小的均为哈夫曼,答案不唯一) 哈夫曼编码: 2. 假设用于通信的电文由字符集{a,b,c,d,e,f,g}中的字符构成,它们在电文中出现的频率分别为{0.31,0.16,0.10,0.08,0.11,0.20,0.04}。要求: (1)为这7个字符设计哈夫曼(6分)。 (2)据此哈夫曼设计哈夫曼编码(4分)。 (3)假设电文的长度为100字符,使用哈夫曼编码比使用3位二进制数等长编码使电文总长压缩多少?(4分) (1) 为这7个字符设计哈夫曼为(符合WPL最小的均为哈夫曼,答案不唯一): (2) 哈夫曼编码为: a:01;b:001;c:100;d:0001;e:101;f:11;g:0000 (3) 假设电文的长度为100字符,使用哈夫曼编码比使用3位二进制数等长编码使电文总长压缩多少? 采用等长码,100个字符需要300位二进制数,采用哈夫曼编码发送这100个字符需要261二进制位,压缩了300-261=39个字符。压缩比为39/300=13%。 3. 二叉数T的(双亲到孩子的)边集为: { <A,B>, <A,C>, <D,A>, <D,E>, <E,F>, <F,G> } 请回答下列问题: (1)T的根结点(2分): (2)T的叶结点(2分): (3)T的深度(2分): (4)如果上述列出边集中,某个结点只有一个孩子时,均为其左孩子;某个结点有两个孩子时,则先列出了连接左孩子的边后列出了连接右孩子的边。画出该二叉树其及前序线索(6分)。 (1)T的根结点 (2)T的叶结点 : (3)T的深度 : (4)该二叉树其及前序线索为: 4.现有以下按前序和中序遍历二叉树的结果: 前序:ABCEDFGHI 中序:CEBGFHDAI 画出该二叉树的逻辑结构图(5分),并在图中加入中序线索(5分)。 5.有电文:ABCDBCDCBDDBACBCCFCDBBBEBB。 用Huffman构造电文中每一字符的最优通讯编码。画出构造的哈夫曼,并给出每个字符的哈夫曼编码方案。(符合WPL最小的均为哈夫曼,答案不唯一) (1)构造哈夫曼(6分): (2)哈夫曼编码方案(4分):

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值