树之习题选讲

Tree traversals again

  • 非递归中序遍历

    • Push的顺序为先序遍历
    • Pop的顺序给出中序遍历
  • 核心算法

void solve( int preL, int inL, int postL, int n )
{   //    preL:pre的首地址
   //    inL:in的首地址
   //    postL:post的首地址
   //    n:数据规模
   if( n==0 ) return;
   if( n==1 ) {
       post[postL] = pre[preL];
       return;
   }
   root = pre[preL];
   post[postL+n-1] = root;
   for( i=0; i<n; i++ )
       if( in[inL+1] == root )
           break;
   L = i; R = n-L-1;
   solve( preL+1, inL, postL, L);
   solve( preL+L+1, inL+L+1, postL+L, R);
}

Complete Binary Search Tree

  • 二叉搜索树

    • 左小右大
  • 完全二叉树

    • 一个数都不少
  • 树的表示法 :链表 vs. 数组

    • 需要的操作:

      • 填写数字(某种遍历)

      • 层序遍历

      • 完全二叉树,不浪费空间

      • 层序遍历 == 直接顺序输出

    • 数组完胜

  • 核心算法

void solve( int ALeft, int ARight, int TRoot )
{
    //初始调用为 solve( 0, N-1, 0 )
    n = ARight - ALeft + 1;
    if( n==0 ) return;
    L = GetLeftLength(n);//计算出n个结点的树其左子树有多少个结点
    T[TRoot] = A[ALeft+L];
    LeftTRoot = TRoot*2+1;
    RightTRoot = LeftTRoot+1;
    solve( ALeft, ALeft+L-1, LeftTRoot );
    solve( ALeft+L-1, ARight, RightTRoot);
} 
  • 排序
#include<stdio.h>
int main()
{
    qsort(A, N, sizeof(int), compare);
}
int compare(const void*a,const void*b)
{
    return *(int*)a-*(int*)b;
}//可根据实际情况自己实现
  • 计算左子树的规模

    • 2 H − 1 + X = N 2^H-1+X=N 2H1+X=N

    • L = 2 H − 1 − 1 + X L = 2^{H-1}-1+X L=2H11+X ??

      • X最小取0,最大取 2 H − 1 2^{H-1} 2H1
      • 所以: X = m i n { X , 2 H − 1 } X=min\lbrace X,2^{H-1}\rbrace X=min{X,2H1}

Huffman Codes

  • 题意理解
    • Huffman编码不唯一
    • 最优编码不一定通过Hufffman算法得到
  • Huffman Codes 的特点
    1. 最优编码----总长度(WPL)最小
    2. 无歧义解码----前缀码:数据仅存在于叶结点
    3. 没有度为1的结点----满足1、2则必有3
    4. 注意:满足2、3可不一定有1!!
  • 核心算法
    1. 计算最优编码长度
MinHeap H = CreateHeap( N );//创建一个空的、容量为N的最小堆
H = ReadData( N );//将f[]读入H->Data[]中
HuffmanTree T = Huffman( H );//建立Huffman树
int CodeLen = WPL( T, 0);
int WPL( HuffmanTree T, int Depth )
{
    if( !T->Left && !T->Right )
        return (Depth*T->Weight);
    else //否则一定有两个孩子
        return (WPL(T->Left, Depth+1) + WPL(T->Right, Depth+1));
} 
	2. 对每位学生的提交,检查
   - 长度是否正确 $\sum_{i=0}^{N-1}strlen(code[i]*f[i])$
   - 建树的过程中检查是否满足前缀码要求
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值