Write directory title here
- 1. Storage structure of binary tree
- 2. Binary tree traversal (graphic)
- 3. Binary tree traversal (code)
- 4. The application of traversal
-
- 4.1. Count the number of leaf nodes in the binary tree (recursive pre-order traversal)
- 4.2. Find the depth of the binary tree (post-order traversal)
- 4.3, Copy the binary tree (post-order traversal)
- 4.4. Build a binary tree according to a given `preorder sequence`
- 4.5. Build a binary tree from a sequence of expressions
- 4.6. Build a tree from the preorder and inorder sequences of the binary tree
1. Storage structure of binary tree
1.1. Sequential storage structure
#define MAX_TREE_SIZE 100 // 二叉树的最大结点数
typedef int TElemType;
typedef TElemType SqBiTree[MAX_TREE_SIZE]; // 0号单元存储根结点
SqBiTree bt;
1.2. Binary linked list storage structure
typedef struct BiTNode{
TElemType data;
struct BiTNode * lchild, * rchild;
} BiTNode, * BiTree;
1.3, triple linked list storage structure
typedef struct TriTNode{
TElemType data;
struct TriTNode * lchild, * rchild;
struct TriTNode * parent;
} TriTNode, * TriTree;
1.4, parent linked list storage structure
typedef struct BiPTNode{
TElemType data;
int * parent;
char LRTag;
}BiPTNode;
typedef struct BiPTree{
BiPTNode nodes[MAX_TREE_SIZE];
int num_node;
int root;
}BiPTree;
2. Binary tree traversal (graphic)
2.1 Preorder traversal: [ 先访问根节点
] around the root
Visit the root node first, then visit the left subtree in sequence, and then visit the right subtree in sequence
2.2 Inorder traversal: [ 中间访问根节点
] left root right
First traverse the left subtree in inorder, then visit the root node, and then traverse the right subtree in inorder
2.3 Post-order traversal: [ 最后访问根节点
] left and right roots
First traverse the left subtree in inorder, then traverse the right subtree in inorder, and then visit the root node
2.4 Two kinds of traversal sequences are known to find the original binary tree
Through [pre-order and in-order] or [in-order and post-order] we can restore the original binary tree.
However, the original binary tree cannot be restored through [preorder and postorder].
Example 1 : Known, preorder: ABCDEFGH, inorder: BDCEAFHG, find postorder.
Answer: DECBHGFA (the original binary tree needs to be drawn according to the pre-order and in-order).
Example 2 : Known, preorder: ABDGHCEFI, inorder: GDHBAECIF, find postorder.
Answer: GHDBEIFCA (the original binary tree needs to be drawn according to the pre-order and in-order).
Example 3 : Known, inorder: BDCEAFHG, postorder: DECBHGFA, find preorder.
Answer: ABCDEFGH (the original binary tree needs to be drawn according to the inorder and postorder).
3. Binary tree traversal (code)
3.1, recursive traversal binary tree description
//先序遍历二叉树
/*
采用二叉链表存储结构,Visit是对数据元素操作的应用函数
先序遍历二叉树T的递归算法,对每个数据元素调用函数Visit。
最简单的Visit函数是:
Status PrintElement(TElemType e){// 输出e的值
printf(e); // 使用时,加上格式串
return OK;
}
// 调用实例:PreOrder(T, PrintElement);
*/
void PreOrder(BiTree T, void (*visit)(TElemType &e)){
if(T){
visit(T->data); //访问结点
PreOrder(T->lchild, visit); //遍历左子树
PreOrder(T->rchild, visit); //遍历右子树
}
} //PreOrder
3.2, non-recursive traversal binary tree description
// 非递归中序遍历二叉树 -- start
BiTNode * GoFarLeft(BiTree T, Stack * S){
if(!T){
return NULL;
}
while(T->lchild){
Push(S, T);
T = T->lchild;
}
return T;
}
void InOrderNonRecursive(BiTree T, void (* visit)(TElemType &e)){
Stack * S;
BiTNode * t = GoFarLeft(T, S);// 找到最左下的结点
while(t){
visit(t->data);
if(t->rchild){
//
t = GoFarLeft(t->rchild, S);
}else if(!StackEmpty(S)){
// 栈不空时退栈
t = Pop(S);
}else{
// 栈空表明遍历结束
t = NULL;
}
}
}
4. The application of traversal
4.1. Count the number of leaf nodes in the binary tree (recursive pre-order traversal)
void CountLeaf(BiTree T, int &count){
if(T){
if((!T->lchild) && (!T->rchild)){
count++;
}
CountLeaf(T->lchild, count);
CountLeaf(T->rchild, count);
}
}
4.2. Find the depth of the binary tree (post-order traversal)
The depth of the binary tree = M ax {the depth of the left subtree, the depth of the right subtree} + 1 depth = M ax { dl , dr } + 1 \begin{aligned} & the depth of the binary tree=Max\{the depth of the left subtree ,\ The depth of the right subtree\}+1 \\ &depth=Max\{d_{l},\ d_{r}\}+1 \end{aligned}The depth of the binary tree=M a x { the depth of the left subtree , depth of right subtree }+1depth=Max{ dl, dr}+1
int Depth(BiTree T){
if(!T){
depthVal = 0;
}else{
depthLeft = Depth(T->lchild);
depthRight = Depth(T->rchild);
depthVal = 1 + (depthLeft > depthRight ? depthLeft : depthRight);
}
return depthVal;
}
4.3, Copy the binary tree (post-order traversal)
//生成一个二叉树的结点
BiTNode * GetTreeNode(TElemType item, BiTNode *lptr, BiTNode *rptr){
T = (BiTNode *)malloc(sizeof(BiTNode));
if(!T){
exit(1);
}
T->data = item;
T->lchild = lptr;
T->rchild = rptr;
return T;
}
BiTNode *CopyTree(BiTNode *T){
if(!T){
return NULL;
}
if(T->lchild){
newlptr = CopyTree(T->lchild);
}else{
newlptr = NULL;
}
if(T->rchild){
newrptr = CopyTree(T->rchild)
}else{
newrptr = NULL;
}
newnode = GetTreeNode(T->data, newlptr, newrptr);
return newnode;
}
先序序列
4.4. Build a binary tree according to the given
Tentative:
the empty tree uses " "
"root" "left subtree" "right subtree" to build a binary tree
according to the given添加空格的完整的先序序列
Status CreateBiTree(BiTree &T){
scanf(&ch);
if(ch == ' '){
T = NULL;
}else{
T = (BiTNode *)malloc(sizeof(BiTNode));
if(!T){
exit(OVERFLOW);
}
T->data = ch; //生成根结点
CreateBiTree(T->lchild); //构造左子树
CreateBiTree(T->rchild); //构造右子树
}
return OK;
} //CreateBiTree
4.5. Build a binary tree from a sequence of expressions
Build a tree from a prefix expression
For example: the prefix expression of a known expression − × + a b c / d e -\times+a\ b\ c/d\ e−×+ a b c / d e
1 A binary tree is built from an expression sequence with spaces
2 先序
A binary tree is built from 后序
an expression expression
3 A binary tree is built from an original expression
原表达式 建立二叉树
void CrtExpTree(BiTree &T, char exp[]){
InitStack(S); //运算符栈
Push(S, '#');
InitStack(PTR); //操作数栈
p = exp;
ch = *p;
while(!(GetTop(S) == '#' && ch == '#')){
if(!IN(ch, OP)){
//ch不是运算符
CrtNode(t, ch); //建叶子结点并入栈
}else{
//ch是运算符
switch(ch){
case '(':
Push(S, ch);
break; //
case ')':
Pop(S, c);
while(c != '('){
CrtSubTree(t, c);//建二叉树并入栈
Pop(S, c);
}
break;
default:
while(!GetTop(S, c)&& (Precede(c, ch))){
CrtSubTree(t, c);
Pop(S, c);
}
if(ch != '#'){
Push(S, ch);
}
break;// default
}// switch
}// else
if(ch != '#'){
p++;
ch = *p;
}
}// while
Pop(PTR, T);
} //CrtExpTree
//建叶子结点的算法为:
void CrtNode(BiTree &T, char ch){
T = (BiTNode *)malloc(sizeof(BiTNode));
T->data = ch;
T->lchild = T->rchild = NULL;
Push(PTR, T);
}
//建子树的算法为:
void CrtSubTree(BiTree& T, char c){
T = (BiTNode *)malloc(sizeof( BiTNode));
T->data = c;
Pop(PTR, rc);
T->rchild = rc;
Pop(PTR, lc);
T->lchild = lc;
Push(PTR, T);
}
4.6. Build a tree from the preorder and inorder sequences of the binary tree
Inorder: left subtree root right subtree
Preorder: root...
postorder:...root
For example:
the preorder sequence of the known binary tree: abcdefg
inorder sequence: cdbaegf
analysis can be obtained:
the root node is a,
the left subtree is cdb,
the right subtree is egf
=========================================================================
typedef enum PointerTag {
Link, Thread};// Link==0指针, Thread==1线索
typedef int TElemType;
//线索链表,线索二叉树,线索化
typedef struct BiThrNode{
TElemType data;
struct BiThrNode * lchild, * rchild;//左右孩子指针
PointerTag LTag, RTag;// 左右标志
}BiThrNode, * BiThrTree;
// 4. The clue linked list storage structure