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 2H−1+X=N
-
L = 2 H − 1 − 1 + X L = 2^{H-1}-1+X L=2H−1−1+X ??
- X最小取0,最大取 2 H − 1 2^{H-1} 2H−1
- 所以: X = m i n { X , 2 H − 1 } X=min\lbrace X,2^{H-1}\rbrace X=min{X,2H−1}
-
Huffman Codes
- 题意理解
- Huffman编码不唯一
- 最优编码不一定通过Hufffman算法得到
- Huffman Codes 的特点
- 最优编码----总长度(WPL)最小
- 无歧义解码----前缀码:数据仅存在于叶结点
- 没有度为1的结点----满足1、2则必有3
- 注意:满足2、3可不一定有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])$
- 建树的过程中检查是否满足前缀码要求