一个二叉树第i层的最大结点数为2^(i-1) i>=1;
深度为k的二叉树有最大结点总数为2^(k-1) k>=1;
对任何非空二叉树,若n0表示叶结点的个数,n2是度为二的非叶结点个数,那么两者满足关系n0=n2+1;





在二叉树结点的先序序列、中序序列和后序序列中,所有叶子结点的先后顺序是 完全相同 的
一棵有n个结点的二叉树,按层次从上到下,同一层从左到右顺序存储在一维数组A[1..n]中,则二叉树中第i个结点(i从1开始用上述方法编号)的右孩子在数组A中的位置( 条件不充分,无法确定 )。


高度为8的完全二叉树至少有( 64 )个叶子结点。
高度为 n的完全二叉树至少有 2n−2个叶子结点(n≥2)。
设森林F中有三棵树,第一,第二,第三棵树的结点个数分别为M1,M2和M3。与森林F对应的二叉树根结点的右子树上的结点个数是M2+M3
在二叉树结点的先序序列,中序序列和后序序列中,所有叶子结点的先后顺序完全相同
一个深度为k的,具有最少结点数的完全二叉树按层次,(同层次从左到右)用自然数依此对结点编号,则编号最小的叶子的序号是2 k−2+1

最短。正确的哈夫曼树(要求左孩子权值小于等于右孩子)以及编码是( )。


已知一棵完全二叉树的第 6层(设根为第1层)有8个叶结点,则该完全二叉树的结点个数最多是111
叶子节点:也称为终端节点,没有子树的节点或者度为零的节点
第五层及以上是满二叉树 结点数为(2^n)-1
第七层有24*2个结点
最多为前6层结点加未知的数量 2^6-1+48=111


性质1:二叉树的第i层上至多有2^(i-1)(i≥1)个节点
性质2:深度为h的二叉树中至多含有(2^h)-1个节点
性质3:若在任意一棵二叉树中,有n0个叶子节点,有n2个度为2的节点,则必有n0=n2+1
性质4:具有n个节点的满二叉树深为log2(n+1)
性质5:若对一棵有n个节点的完全二叉树进行顺序编号(1≤i≤n),那么,对于编号为i(i≥1)的节点:
当i=1时,该节点为根,它无双亲节点 。
当i>1时,该节点的双亲节点的编号为i/2 。
若2i≤n,则有编号为2i的左节点,否则没有左节点 。
若2i+1≤n,则有编号为2i+1的右节点,否则没有右节点 。
若一棵完全二叉树有n个结点,则该二叉树中叶结点的个数是
当n为奇数时:
总节点数n为奇数,说明最后一层结点数为奇数,此时n 1=0,代入得:n 0 = (n+1)/2
当n为偶数时:
总节点数n为偶数,最后一层结点数为偶数,此时n 1=1,代入得:n 0 = 2n−1+1= n/2
设一棵非空完全二叉树T的所有叶结点均位于同一层,且每个非叶结点都有2个子结点。若T有
k个叶结点,则T的结点总数是2k-1

对于任意一棵高度为且有10个结点的二叉树,若采用顺序存储结构保存,每个结点占1个存储单元(仅存放结点的数据信息),则存放该二叉树需要的存储单元数量至少是(2^h)-1

要使一棵非空二叉树的先序序列与中序序列相同,其所有非叶结点须满足的条件是( )
只有右子树









先序序列为 a, b, c, d的不同二叉树的个数是14

卡特兰数应用:对于 n 个节点的二叉树,其形态数满足卡特兰数。当已知先序遍历序列(或后序遍历序列 )时,不同二叉树的个数都可以用卡特兰数计算。因为先序遍历确定了
根节点(第一个元素 ),后续节点在左右子树的分配组合情况符合卡特兰数的规律。
在一棵度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个
度为1的结点,则树T的叶结点个数是82
在无向图中,所有结点的度之和 = 2 × 边数 e
在有根树中,所有结点的出度之和 = 边数 (e)。
设树T的节点总数为N,由上述树的性质可知,边数e=结点数N−1
根据度之和的计算方法,可得度之和为122,节点数为123,
又节点总数N等于度为4、度为3、度为2、度为1和度为0(叶结点)的节点数之和
20+10+1+10+x=123,

已知一棵有2011个结点的树,其叶结点个数为116, 该树对应的二叉树中无右孩子的结点个数是1896
结论:
一棵分支结点(非终端结点)个数为n(总结点数-叶结点数) 的树,该树对应的二叉树中无右孩子的结点(或右指针域为空的结点)个数为 n + 1。【森林对应二叉树时也适用,上述过程推导主要涉及对应后的二叉树】
其他推导中所得的结论:
原始树(或森林)的叶结点个数 = 转换的二叉树中左指针域为空的个数
非空指针域个数 = 总结点个数 – 1
空指针域个数 = 总结点个数 + 1
题目:将森林F转换为对应的二叉树T,F中叶结点的个数等于__。【2014年全国试题】
A.T中叶结点的个数
B.T中度为1的结点个数
C.T中左孩子指针为空的结点个数
D.T中右孩子指针为空的结点个数
左孩子 – 右兄弟” 规则:树中一个节点的第一个孩子在二叉树中成为其左孩子,这个节点的
右兄弟在二叉树中成为其右孩子
A
/ | \
B C D
/ \ \
E F G
树的说明:根节点为 A,有 3 个子节点 B、C、D;B 有 2 个子节点 E、F;D 有 1 个子节点
G。
A
/
B
/ \
E C
\ \
F D
/
G




前缀编码的定义
前缀编码要求在一组编码中,任何一个字符的编码都不是其他字符编码的前缀。
左孩子依旧作为左孩子
左孩子的最近的右兄弟作为该左孩子的右儿子
以此类推
对n个互不相同的符号进行哈夫曼编码。若生成的哈夫曼树共有115个结点,则n的值是58
已知哈夫曼树共有115个结点,即N=115,由N=2n 0 −1可得n 0 = 116/2=58 ,因为n就是叶节点数n 0(n个互不相同的符号对应哈夫曼树的n个叶节点 ),所以n=58。
哈夫曼树的节点数N必为奇数,不可能为偶数。
若某二叉树有5个叶结点,其权值分别为10, 12, 16, 21, 30, 则其最小的带权路径长度 (WPL)
是( )





C,n个结点的连通无向图最少需要n−1条边 。可以把无向图想象成树的结构(树是一种特殊的连通无向图),树中节点数为n时,边数恰好是n−1,此时图中每两个顶点之间恰好有一个路径,刚好连通且没有多余的边。当边数小于n−1时,图一定是非连通的 。
统计二叉树度为1的结点个数。
#include<iostream>
using namespace std;
typedef struct BiNode{
char data;
struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T){
char ch;
cin >> ch;
if(ch=='#') T=NULL;
else{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
int NodeCount ( BiTree T)
{
if(T==NULL) return 0;
if(T->lchild==NULL&&T->rchild!=NULL)
return 1;
if(T->lchild!=NULL&&T->rchild==NULL)
return 1;
return NodeCount(T->lchild)+NodeCount(T->rchild);
}
int main(){
BiTree T;
CreateBiTree(T);
printf("%d", NodeCount(T));
return 0;
}
计算二叉树深度。
int Depth(BiTree T)
{
int m, n;
if (T == NULL)
return 0;
else
{
m = Depth(T->lchild);
n = Depth(T->rchild);
if (m > n)
return (m + 1);
else
return (n + 1);
}
}
创建哈夫曼树。
#include<cstring>
#include<iostream>
using namespace std;
typedef struct
{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
void Select(HuffmanTree HT,int len,int &s1,int &s2)
{
int i,min1=32767,min2=32767;
for(i=1;i<=len;i++)
{
if(HT[i].weight<min1&&HT[i].parent==0)
{
s2=s1;
min2=min1;
min1=HT[i].weight;
s1=i;
}
else if(HT[i].weight<min2&&HT[i].parent==0)
{ min2=HT[i].weight;
s2=i;
}
}
}
void CreatHuffmanTree(HuffmanTree &HT,int n)
{
int m,s1,s2,i;
if(n<=1) return;
m=2*n-1;
HT=new HTNode[m+1];
for(i=1;i<=m;++i)
{ HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; }
for(i=1;i<=n;++i)
cin >> HT[i].weight;
for(i=n+1;i<=m;++i)
{
Select(HT,i-1,s1,s2);;
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
void print(HuffmanTree HT,int n)
{
for(int i=1;i<=2*n-1;i++)
cout << HT[i].weight << " " << HT[i].parent << " " << HT[i].lchild << " " << HT[i].rchild << endl;
}
int main()
{
HuffmanTree HT;
int n;
cin >> n;
CreatHuffmanTree(HT,n);
print(HT,n);
return 0;
}
哈夫曼编码
编写函数实现哈夫曼编码。输入结点个数(保证个数>1)及各结点的权值,为各结点进行编码。
void CreateHuffman_tree(HuffmanTree &HT,int n)
{
if(n<=1)
{
return ;
}
int m=2*n-1;
HT=new HTNode[m+1];
for(int i=0;i<=m;i++)
{
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&HT[i].weight);
}
for(int i=n+1;i<=m;i++){
int s1,s2;
Select(HT,i-1,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
void Huffman_code(HuffmanTree HT,HuffmanCode &HC,int n)
{
HC=new char*[n+1];
char *s=new char[n];
s[n-1]='\0';
for(int i=1;i<=n;i++)
{
int c,f,start=n-1;
c=i;
f=HT[i].parent;
while(f)
{
--start;
if(HT[f].lchild==c) s[start]='0';
else s[start]='1';
c=f;
f=HT[f].parent;
}
HC[i]=new char[n-start];
strcpy(HC[i],&s[start]);
}
delete s;
}
二叉树的遍历
输入二叉树的先序遍历序列,以#代表空树,输出该二叉树的中序遍历序列。例如,有如下二叉树,其先序序列为:ABC##DE#G##F###,输出其中序序列:CBEGDFA
void InOrder(BiTree Tree)
{
if (Tree != NULL)
{
InOrder(Tree->lchild); // 先遍历左子树
printf("%c", Tree->data); // 访问根节点并输出数据
InOrder(Tree->rchild); // 再遍历右子树
}
}
BiTNode* newNode(char data) {
BiTNode* node = (BiTNode*)malloc(len);
node->data = data;
node->lchild = node->rchild = NULL;
return node;
}
void creat(BiTree &Tree)
{
char ch;
scanf("%c",&ch);
if(ch=='#')
{
Tree=NULL;
}
else{
Tree=(BiTNode*)malloc(len);
Tree->data=ch;
creat(Tree->lchild);
creat(Tree->rchild);
}
}
求二叉树的WPL(408)
二叉树的带权路径长度 (WPL) 是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树T, 采用二叉链表存储,结点结构为

其中叶结点的weight域保存该结点的非负权值。设root为指向T的根结点的指针,请设计求T的WPL的算法.
int WPL(BiTree root)
{
if (root == NULL)
{
return 0;
}
BiTree queue[len];
int front = 0, rear = 0;
int wpl = 0;
int depth = 0;
queue[rear++] = root;
while (front != rear)
{
int count = rear - front;
for (int i = 0; i < count; i++)
{
BiTree curr = queue[front++];
if (curr->lchild == NULL && curr->rchild == NULL)
{
wpl += curr->weight * depth;
}
if (curr->lchild != NULL)
{
queue[rear] = curr->lchild;
rear++;
}
if (curr->rchild != NULL)
{
queue[rear] = curr->rchild;
rear++;
}
}
depth++;
}
return wpl;
}
后缀式
本题要求实现一个函数,输出二叉树表示的表达式的后缀式。输入一个表达式的前缀形式(该表达式二叉树的扩展的先序序列),构造该二叉树,并输出其后序序列即为该表达式的后缀形式。
void creat(BiTree &Tree){
char c;
scanf("%c",&c);
if(c=='#'){
Tree=NULL;
}else{
Tree=(BiTree)malloc(len);
Tree->data=c;
creat(Tree->lchild);
creat(Tree->rchild);
}
}
void PostOrder(BiTree Tree){
if(Tree==NULL){
return;
}
PostOrder(Tree->lchild);
PostOrder(Tree->rchild);
printf("%c",Tree->data);
}
表达式树转中缀表达式(408)
请设计一个算法,将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。例如,当下列两棵表达式树作为算法的输入时:

输出的等价中缀表达式分别为 (a+b)* (c* (-d) )和 (a*b) + (- (c-d) )。
二叉树结点定义如下:
typedef struct node{
char data ;
struct node *left, *right;
}BTree;
void Btree(BiTree root, int deep)
{
if (root == NULL)
return ;
else if (root->lchild == NULL && root->rchild == NULL) //叶节点
printf("%c", root->data); //输出操作数
else
{
if (deep > 1)
printf("(");
Btree(root->lchild, deep + 1);
printf("%c", root->data); //输出操作符
Btree(root->rchild, deep + 1);
if (deep > 1)
printf(")");
}
}
void BtreeToE(BiTree root)
{
Btree(root, 1);
}