第五章:树和二叉树
先序遍历二叉树的非递归算法。
void PreOrderTraverse(BiTree T, void (*Visit)(TElemType)) {//表示用于查找的函数的指针
Stack S; BiTree p = T;
InitStack(S);//S模拟工作栈
while (p || !StackEmpty(S)) {//S为空且下一个结点为空,意味着结束遍历
if (p) {//p有值,则Push进栈为一个工作进程
Visit(p->data); Push(S, p); p = p->lchild;//先序遍历,先Visit
} else {
//p为空,则它的上级被Pop出去,成为新的p,再取右孩子。在下一个循环中如果它的上级没右孩子,则说明它的上级是叶子结点(或两端已经工作栈弹出了),则再Pop出它的上级的上级(此时它的上级已经无用,工作栈弹出),取它上级的兄弟结点
Pop(S, p); p = p->rchild;
}
}
}
利用工作栈的思想,过程十分复杂,多多复习,巩固加深!
层序遍历二叉树
void LayerTraverse(BiTree T, void (*Visit)(TElemType)) {
Queue Q; BiTree p;
InitQueue(Q);
EnQueue(Q, T);
while (!QueueEmpty(Q)) {
DeQueue(Q, p);
//每有一个父母结点出队列,就把它的左右孩子放到队尾排队,确保一层一层遍历
if (p) {
Visit(p->data);
EnQueue(Q, p->lchild); EnQueue(Q, p->rchild);
}
}
}
计算二叉树中每个结点的层次
void LevelRecur(BiTree T, int lev) {
if (T) {
++lev;//准备遍历下一层
cout << T->data << ' ' << lev << endl;
LevelRecur(T->lchild, lev);
LevelRecur(T->rchild, lev);//下一层启动
}
}
void Level(BiTree T) {
LevelRecur(T, 0);
}
输出二叉树根结点到所有叶子结点的路径
void OutPath(BiTree T, Stack &S) {//使用一个栈存储路径,起到回溯的作用
if (T) {
Push(S, T);
if (!T->lchild && !T->rchild)
PrintStack(S);//S栈中元素依次输出,不取出
OutPath(T->lchild, S);
OutPath(T->rchild, S);
Pop(S, T);//该节点左右孩子搜索完,则出栈,不再计入路径中
}
}
由扩展的先序序列,即波兰式,建立二叉树
void CreateBiTree(BiTree &T) {
// 读入扩展的先序序列,假定数据元素为字符型,#表示NULL
char ch; scanf("%c", &ch);
if (ch == '#') T = NULL;
else {
T = new BiTNode; T->data = ch;
CreateBiTree(T->lchild);//依次建立二叉树
CreateBiTree(T->rchild);
}
}
先根遍历树,孩子链表实现
void PreOrderRecur(CTree T, int loc, void (*Visit)(TElemType)) {
if (loc == -1) return;
Visit(T.nodes[loc].data);//先查询根结点
ChildPtr p;
for (p = T.nodes[loc].firstchild; p; p = p->next) {
PreOrderRecur(T, p->child, Visit);//取出下个孩子,并查询
}
}
void PreOrderTree(CTree T, void (*Visit)(TElemType)) {
PreOrderRecur(T, T.root, Visit);
}
计算树的深度,孩子兄弟链表实现
int TreeDepth(CSTree T) {
if (!T) return 0;//最简单情况,遍历结束条件
CSTree p; int maxh = 0;//maxh为全局变量
for (p = T->firstchild; p; p = p->nextsibling) {//到T的下一个孩子,并且遍历其孩子的兄弟
int h = TreeDepth(p);//当前遍历结点的深度
if (h > maxh) maxh = h;
}
return maxh + 1;
}
构造huffman树
typedef unsigned int WeightType;
typedef struct {
TElemType data;
WeightType weight; // 叶子权值的类型
int parent, lchild, rchild; // 三叉静态链表
} HTNode, *HuffmanTree;
void CreateHuffmanTree(HuffmanTree &HT, int n) {
int m = 2*n-1; // 最终将得到2n-1个结点
HT = new HTNode[m];
for (i=0; i<n; ++i) {
cin >> HT[i].data >> HT[i].weight;
HT[i].lchild = HT[i].rchild = HT[i].parent = -1;//-1即示意为为null
}//输入结点值
for (i=n; i<m; ++i) {
Select(HT, i-1, s1, s2); HT[s1].parent=HT[s2].parent=