提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
typedef struct BTNode{
char data;
struct BTNode *lchild;
struct BTNode *rchild;
}BTNode;
typedef struct TBTNode{
char data;
int ltag, rtag;
struct TBTNode *lchild;
struct TBTNode *rchild;
}TBTNode;
一、基础算法
-
层次遍历
void level(BTNode *p){ if(p == NULL) return ; int front, rear; BTNode *qu[maxSize]; front = rear = 0; BTNode *q; rear = (reaar + 1) % maxSize; qu[rear] = p; while(front != rear){ front = (front + 1) % maxSize; q = qu[front]; Print(q); if(q->lchild != NULL){ rear = (rear + 1) % maxSize; qu[rear] = q->lchild; } if(q->rchild != NULL){ rear = (rear + 1) % maxSize; qu[rear] = q->rchild; } } }
- 扩展
假设二叉树用二叉链表结构存储,求宽度(结点最多那一层的结点个数)
-
中序遍历对二叉树线索化
void InThread(TBTNode *p, TBTNode *&pre){ if(p == NULL) return; InThread(p->lchild, pre); if(p->lchild == NULL){ p->lchild = pre; p->ltag = 1; } if(pre != NULL && p->rchild == NULL){ p->rchild = p; p->rtag = 1; } pre = p; InThread(p->rchild, pre); } void createInThread(TBTNode *root){ TBTNode *pre = NULL; if(root != NULL){ InThread(root, pre); pre->rchild = NULL; pre->rtag = 1; } } TBTNode *First(TBTNode *p){ while(p->ltag == 0){ p = p->lchild; } return p; } TBTNode *Next(TBTNode *p){ if(p->rtag == 0){ return First(p->rchild); }else{ return p->rchild; } } void Inorder(TBTNode *root){ for(TBTNode *p = First(root); p!=NULL; p=Next(p)){ Visit(p); } }
二、综合应用题
-
设二叉树根结点所在层次为1,树的深度d为距离根最远的叶结点所在的层次
-
试精确给出深度为d的完全二叉树的不同二叉树棵数
2 ( d − 1 ) 2^{(d-1)} 2(d−1)
-
试精确给出深度为d的满二叉树的不同二叉树棵数
1
-
-
假设二叉树采用二叉链存储结构,设计一个算法,计算一棵给定二叉树的所有结点数
int count(BTNode *p){ if(p == NULL) return 0; return count(p->lchild)+count(p->rchild)+1; }
-
假设二叉树采用二叉链存储结构,设计一个算法,计算一棵给定二叉树的所有叶子结点
int count(BTNode *p){ if(p == NULL) return 0; else if(p->lchild == NULL && p->rchild == NULL) return 1; return count(p->lchild)+count(p->rchild); }
-
假设二叉树采用二叉链存储结构,设计一个算法,利用结点的右孩子指针rchild将一棵二叉树的叶子结点按照从左往右的顺序串成一个单链表(在题目中定义两个指针head与tail,其中head指向第一个叶子结点,head初值为NULL,tail指向最后一个叶子结点)
Tip:无论哪种遍历方式 叶子节点 在序列中的 相对位置 总是 不变 的
void link(BTNode *p, BTNode *&head, BTNode *&tail){ if(p == NULL) return; if(p->lchild == NULL && p->rchild == NULL){ if(head == NULL){ head = p; tail = p; }else{ tail -> rchild = p; tail = p; } } link(p->lchild, head, tail); link(p->rchild, head, tail); }
-
在二叉树的二叉链存储结构中,增加一个指向双亲结点的parent指针,设计一个算法,给这个指针赋值,并输出所有结点到根结点的路径
typedef struct BTNode{ char data; struct BTNode *parent; struct BTNode *lchild; struct BTNode *rchild; }BTNode; void triBtree(BTNode *p, BTNode *q){ if(p == NULL) return; p->parent = q; q = p; triBtree(p->lchild, q); triBtree(p->rchild, q); } void printPath(BTNode *p){ while(p!=NULL){ cout<<p->data<<" "<<endl; p = p->parent; } } void allPath(BTNode *p){ while(p!=NULL){ printPath(p); allPath(p->lchild); allPath(p->rchild); } }
-
假设满二叉树b的 先序 遍历序列已经存在于数组中(在解题过程中,此数组名称可自定义,长度为n),设计一个算法将其 转换 为 后序 遍历序列
思路:
1. 根节点移动到整个序列的末尾
2. 递归处理序列左子树、右子树void change(char arr[], int L1, int R1, char res[], int L2, int R2){ if(L1<=R1){ res[R2] = arr[R1]; change(arr, L1+1, (L1+1+R1)/2, res, L2, (L2+R2-1)/2); change(arr, (L1+1+R1)/2+1, R1, res, (L2+R2-1)/2+1, R2-1); } }
-
假设二叉树采用二叉链存储结构,设计一个算法,求二叉树b中值为x的结点的层号
在这里插入代码片
-
以数据集合(2,5,7,9,13}为权值构造一棵赫夫曼树,并计算其带权路径长度
(2+5) * 3 + (7 + 9 + 13) * 2 = 79
-
对于一个堆栈,若其入栈序列为1,2,3,…,n,不同的出入栈操作将产生不同的出栈序列。其出栈序列的个数正好等于结点个数为n的二叉树的个数,且与不同形态的二叉树一一对应。请简要叙述一种从堆栈输入(固定为1,2,3,…,n)和输出序列对应一种二叉树形态的方法,并以入栈序列1,2,3(n=3)为例确定所有的二叉树。
Tips:
(二叉树遍历都是递归,递归用到系统栈)
1. 先序遍历:入栈时进行打印的序列
2. 中序遍历:出栈时进行打印的序列
∵ 二叉树 先序遍历和中序遍历 可唯一确定一棵二叉树
∴入栈序列:1,2,3,…,n,相当于先序遍历序列是1,2,3,…,n
出栈序列:对应的二叉树的中序遍历序列
有了进栈和出栈序列,相当于知道一棵二叉树的先序和中序遍历序列,即确定了对应的二叉树
-
二叉树的 双序遍历 是指:对于二叉树的每一个结点来说,先访问这个结点,再按双序遍历它的左子树,然后再一次访问这个结点,接下来按双序遍历它的右子树。试写出执行这种双序遍历的算法。
void Double_order(BTNode *t){ if(t == NULL) return; Print(t); Double_order(t->lchild); Print(t); Double_order(t->rchild); }
-
设 中序线索二叉树 的类型为TBTNode* InThTree;
-
设计算法,在一棵中序线索二叉树中寻找结点 t 的子树上中序下的最后一个结点。
TBTNode *inLast(TBTNode *t){ TBTNode *p = t; while(p && p->rtag == 1){ p = p->rchild; } return p; }
-
设计算法,在一棵中序线二叉树中寻找结点 t 的中序下的前驱。
TBTNode *inPrior(TBTNode *t){ TBTNode *p = t->lchild; if(p && p->ltag == 0){ p = inLast(p); } return p; }
-
设计算法,在一棵中序线索二叉树中寻找结点 t 的前序下的后继。
在这里插入代码片
-
总结
提示:这里对文章进行总结: